导语:在本文中,我将演示如何使用Burp Infiltrator来找到JetBrains公司产品TeamCity的通用型0day。
在本文中,我将演示如何使用Burp Infiltrator来找到JetBrains公司产品TeamCity的通用型0day,TeamCity是Java编写的一款针对专业开发人员和构建工程师的持续集成(CI)服务器。在这一过程中Burp Infiltrator通过测试目标应用程序,注入代码来跟踪用户输入,最终帮助我使用经典的扫描技术找到了一枚通常情况下难以找到的漏洞。除此之外我还将分享一些使用Infiltrator的一些技巧,以使大家能够获得更多的收益。有关Infiltrator的基本介绍,请参阅Burp Infiltrator介绍。
实例解析
Infiltrator在注入代码时发送一个pingback到Burp Collaborator,那么只要Burp Scanner给Burp Collaborator提供数据,Burp Scanner就会触发潜在的漏洞,例如运行系统命令或更改文件系统。这一点有助于找到可能被输入转换,输入过滤或输出缺失掩盖的漏洞。同时它还揭示了应用程序遍历的代码路径,以覆盖到每个危险的API,这样也会使漏洞更容易修补和利用。
首先,我开始通过使用Collaborator ID来对需要进行渗透的应用程序进行全面的清查,禁用除了外部服务交互的每个扫描检查,并且启用实时主动扫描和浏览来作为普通用户。
在浏览了一段时间之后,我注意到,在一些页面上有一些相同的模式的交互。这些交互显示应用程序正在从用户输入创建一个字节数组,然后将其传递给FileInputStream.read方法。该方法由org.eclipse.jgit包中的类调用,而该包是TeamCity的Git插件的依赖项。
我从与存储库URL创建新项目相关的页面获得了这些交互,这意味着URL可能被写入文件系统。虽然我不知道这些内容是写在哪里,但我知道字节数组的确切内容。请参阅以下截图:
这是一个有趣的参数值:某些基于属性的文件是用用户提供的数据构建的。解码后实际的字符串看起来像这样:
我马上认识到这是一个Git仓库文件配置。这个文件格式很简单:
1、一部分被表示为[sectionName],每个部分都有一组属性,这些属性使用propertyName = value格式设置。
2、分号或散列后的所有字符串都将被视为注释。
3、反斜杠转义特殊字符。
4、通过在行的末尾添加反斜杠来支持多行属性值。
我的目标是转义teamcity部分,并在核心部分设置属性。首先我会使用Collaborator客户端来生成一系列用于我的payload的交互ID。因此,每次转义远程属性的尝试都会产生Infiltrator与文件内容的交互。此设置提供了一个方便的反馈循环,允许一个输入值在由多层代码转换后确定输入值的影响。
在使用这种方法一段时间后,我意识到我想出的所有URL都可以被正确转义,虽然我可以使用0x0a字符输入换行符,但它仍然在远程属性的上下文中。此外,某些字节会使org.apache.commons.httpclient.HttpMethodBase类引发异常,因为这些异常在URL中是非法的。
经过几次尝试后,我改进了我的payload,最后得出以下的POC:
生成以下文件:
对上面的payload进行解析,我们可以得到这些信息:%23(#)字符使HttpClient不会出现异常,因为URL片段中的所有内容都被忽略。%0d(CR)字符将插入符号返回到行的开头,使得能够有效的写入原始属性之上。分号从原始内容中注释其中的剩余部分,并在解码%0a(LF)之后,转义TeamCity添加的反斜杠。
这是一个简单的语句,允许我们转义当前属性并将任意数据写入属性层次结构的顶层。设置这些属性中的一些属性的影响是巨大的,这可能导致从代码执行到在代码库(代表合法的开发人员)中插入后门到迫使开发人员将任意代码提取到其机器上。
事实上,有几十个可以添加的属性可能会导致远程代码执行,比如core.sshCommand,core.editor,gpg.program等等。其他属性允许攻击者设置存储库特定的代理,更改签名的检查方式,设置加载git钩子的位置等等。
以上是使用Burp Infiltrator发现错误并为其编写POC的示例。但这只是冰山一角,用Collaborator的URL去对需要进行渗透的应用程序进行全面的了解可以产生非常有趣的结果,如:
1、异步渗透者事件。
2、从输入转换中获取的SMTP协作者事件被报告为渗透者交互。
3、将由相同API生成的多个Infiltrator交互的看似无关的插入点相关联
4、互动指向从不同插入点到达同一个易受攻击代码路径的多种方式。
渗透应用程序是一个迭代过程; 选择正确的目标路径取决于您要获得的交互量。理想情况下,我们只对应用程序的字节码及其依赖关系感兴趣。这是因为应用程序可能不会自动实例化XML解析器,但它可能会使用库来处理XML解析。如果是这种情况,我们不会渗透XML依赖关系,即使Scanner可靠地检测到XML漏洞,我们也不会看到这些Infiltrator交互。
相反,如果我们盲目渗透一切,我们可能会产生误导性的互动。例如,当Web服务器接收到请求时,它将使用其路径来确定哪个应用程序应该发送此请求。以下屏幕截图显示了一个示例:
看起来有一个文件遍历问题,但是调用堆栈显示没有执行org.eclipse.jetty包以外的代码。这种交互显然不是来自应用程序,而是来自Web服务器本身。
使用Collaborator ID全面了解您的目标应用程序,等待Infiltrator交互到达并相应地调整您的目标路径。
还有一个重要的是决定是——什么时候渗透您的目标应用程序是最为正确的时间。一般来说,我们要修补与用户功能相关的每个类。大多数应用程序在首次部署之前可能会渗透,但有一些情况可能不是这种情况。
比如,有一个例子就是通过插件的可扩展性来进行的。插件在运行时会拓宽应用程序的攻击面,在这种情况下,最好先安装要测试的所有插件,将这些插件的位置添加到目标路径列表中,并重新部署渗透的应用程序。
JSP页面是一个值得提及的特殊情况。简而言之,JSP代码被转换成servlet,而这些代码又被编译成Java字节码。JSP的大多数实现都是按需实现的,即:JSP只有在客户端请求之后才能被编译。这意味着Infiltrator不会调用JSP文件,因为它们最初不是Java字节码。然而,用户可以通过多种方式解决这个问题。例如,通过在部署应用程序之前手动触发JSP预编译,这将生成所需的字节码。
可能出现的问题
如果您看到奇怪的行为或者您的应用程序在渗透后无法启动,请注意Web服务器日志(或应用程序日志记录工具)中的异常。现代应用程序通常会出现一些异常,因此如果您认为有问题,您可以对以下类型进行过滤:
java.lang.ClassFormatError java.lang.VerifyError java.lang.NoClassDefFoundError java.lang.StackOverflowError
这四种类型的例外是一些很好的指标,一些类别或档案馆正在进行修补过程破坏的假设。另外,我们也非常希望您能够将您所遇到的问题提交一份报告,因为您的反馈有助于改善渗透人员们的体验!