如何通过串联4个漏洞(特性?)在亚马逊协作系统上实现远程代码执行
嗨!这是我2018年Black Hat USA和DEFCON 26演讲中的案例研究,你也可以在这里查看幻灯片:Breaking Parser Logic! Take Your Path Normalization Off and Pop 0days Out
在过去两年中,我开始更多关注“不一致性”漏洞。那是什么?就像我去年的Black Hat演讲中的SSRF和GitHub SSRF到RCE案例一样,发现URL解析器和URL获取器之间的不一致性导致整个SSRF绕过!
还有另一篇很酷的文章Bypassing Web-Application Firewalls by abusing SSL/TLS由@0x09AL撰写,说明了“不一致性”有多么强大。
所以今年,我开始关注路径解析器和路径规范化之间的“不一致性”! 编写一个设计良好的解析器很难。不同的实体有自己的标准和实现。为了修复漏洞而不影响业务逻辑,通常应用变通方法或过滤器而不是直接修补漏洞。因此,如果过滤器和被调用方法之间存在任何不一致性,安全机制很容易被绕过!
在阅读安全公告时,我注意到了一个叫做URL路径参数的特性。一些研究人员已经指出这个特性可能导致安全问题,但它仍然取决于编程失败!通过一些思维映射,我发现这个特性可以完美应用于多层架构,并且默认情况下就是易受攻击的,无需任何编码失败。如果你使用反向代理且后端服务是Java,你就处于威胁之中!
回到2015年,我第一次发现这个攻击面是在一次红队测试中。之后,我意识到这真的很酷,并且好奇有多少人知道这一点。所以我在WCTF 2016上设计了一个挑战。 (我检查了DirBuster、wFuzz、DirB和DirSearch中的扫描器。直到现在,只有DirSearch在2017年5月1日加入了该模式)
WCTF是由Belluminar和360举办的比赛。它不同于其他CTF比赛中的一般Jeopardy或攻防模式。它邀请来自全球的前10支队伍,每支队伍需要设计两个挑战,所以总共有20个挑战!你解决的挑战越多,得分就越高。然而,在比赛期间没有人解决我的挑战。因此,我认为这个技巧可能并不广为人知!
今年,我决定分享这个技术。为了说服评审委员会这很厉害,我需要更多案例来证明它有效!所以我开始寻找漏洞!结果表明,这个攻击面不仅可以泄露信息,还可以绕过ACL(比如我的Uber OneLogin绕过案例),并在几个漏洞赏金计划中导致RCE。这篇文章就是其中之一! (如果你对其他故事感兴趣,请尽快查看幻灯片!!!)
↓ 多层架构中的不一致性!
前言
首先,感谢亚马逊开放的漏洞披露。与亚马逊安全团队(以及Nuxeo团队)合作是一次非常好的体验。从时间线中,你可以看到亚马逊的响应速度以及他们采取的步骤!
整个故事始于一个域名collaborate-corp.amazon.com。它似乎是一个用于内部目的的协作系统。从底部的版权信息中,我们知道这个系统是基于开源项目Nuxeo构建的。这是一个非常大的Java项目,我只是想提高我的Java审计技能。所以故事就从那里开始了……!
漏洞
对我来说,当我拿到Java源代码时,第一件事就是阅读pom.xml并查找是否有任何过时的包。在Java生态系统中,大多数漏洞是由于OWASP Top 10 - A9. 已知易受攻击的组件。 之前是否有任何Struts2、FastJSON、XStream或具有反序列化漏洞的组件?如果有,恭喜!
在Nuxeo中,似乎大多数包都是最新的。但我找到了一个老朋友 - Seam Framework。Seam是由JBoss开发的一个Web应用程序框架,是Red Hat的一个部门。它在几年前曾是一个流行的Web框架,但仍然有很多基于Seam的应用程序 :P
我在2016年审查过Seam,并发现了许多对黑客友好的特性!(抱歉,只有中文版本)然而,看起来我们不能直接访问Seam部分。但仍然记下这一点,并继续前进!
1. 路径规范化漏洞导致ACL绕过
在查看WEB-INF/web.xml中的访问控制时,我们发现Nuxeo使用了一个自定义身份验证过滤器NuxeoAuthenticationFilter,并将/*映射到该过滤器。从过滤器中我们知道大多数页面需要身份验证,但有一个白名单允许少数入口,如login.jsp。所有这些都在一个方法bypassAuth中实现。
|
|
如你所见,bypassAuth检索当前请求的页面以与unAuthenticatedURLPrefix进行比较。但是bypassAuth如何检索当前请求的页面?Nuxeo编写了一个方法从HttpServletRequest.RequestURI中提取请求的页面,第一个问题就出现在这里!
|
|
为了处理URL路径参数,Nuxeo通过分号截断所有尾部部分。但URL路径参数的行为各不相同。每个Web服务器都有自己的实现。Nuxeo的方式在像WildFly、JBoss和WebLogic这样的容器中可能是安全的。但它在Tomcat下运行!所以方法getRequestedPage和Servlet容器之间的差异导致了安全问题!
由于截断,我们可以伪造一个请求,该请求匹配ACL中的白名单,但到达Servlet中的未授权区域! 在这里,我们选择login.jsp作为我们的前缀!ACL绕过可能看起来像这样:
|
|
如你所见,我们绕过了身份验证的重定向,但大多数页面仍然返回500错误。这是因为servlet逻辑无法获取有效的用户主体,因此抛出Java NullPointerException。尽管如此,这仍然给了我们一个敲门的机会!
2. 代码重用特性导致部分EL调用
正如我之前提到的,Seam框架中有许多对黑客友好的特性。所以,对我来说,下一步是将第一个漏洞链接到访问未经授权的Seam servlet!
在以下部分中,我将详细解释这些“特性”!
为了控制浏览器应该重定向到哪里,Seam引入了一系列HTTP参数,并且这些HTTP参数也存在漏洞……actionOutcome就是其中之一。2013年,@meder发现了一个远程代码执行漏洞。你可以阅读这篇很棒的文章CVE-2010-1871: JBoss Seam Framework remote code execution了解详情!但今天,我们将讨论另一个 - actionMethod!
actionMethod是一个特殊的参数,可以从查询字符串调用特定的JBoss EL(表达式语言)。它看起来很危险,但在调用之前有一些先决条件。详细实现可以在方法callAction中找到。为了调用EL,必须满足以下先决条件:
- actionMethod的值必须是一对,看起来像FILENAME:EL_CODE
- FILENAME部分必须是context-root下的真实文件
- 文件FILENAME必须包含内容"#{EL_CODE}"(需要双引号和大括号)
例如: 在context-root下有一个名为login.xhtml的文件。
|
|
你可以通过URL调用EL user.username
|
|
3. 双重评估导致EL注入
先前的特性看起来合格。你无法控制context-root下的任何文件,因此无法在远程服务器上调用任意EL。然而,还有一个更疯狂的特性……
更糟糕的是,如果前一个返回一个字符串,并且该字符串看起来像EL,Seam框架会再次调用!
以下是详细的调用栈:
|
|
有了这个疯狂的特性。如果我们能控制返回值,我们就可以执行任意EL! 这非常类似于二进制利用中的ROP(返回导向编程)。所以我们需要找到一个好的gadget!
在这个案例中,我们选择在widgets/suggest_add_new_directory_entry_iframe.xhtml下的gadget
|
|
为什么我们选择这个?这是因为request.getParameter返回一个我们可以从查询字符串控制的字符串!尽管整个标签是为了分配一个变量,但我们可以滥用语义!
所以现在,我们将我们的第二阶段payload放在directoryNameForPopup中。通过第一个漏洞,我们可以将它们链接在一起,无需任何身份验证即可执行任意EL!以下是PoC:
|
|
就这样结束了吗?还没有!尽管我们可以执行任意EL,但我们仍然无法弹出一个shell。为什么? 让我们进入下一部分!
4. EL黑名单绕过导致RCE
Seam也知道EL是疯狂的。自从Seam 2.2.2.Final以来,有一个新的EL黑名单来阻止危险的调用!不幸的是,Nuxeo使用最新版本的Seam(2.3.1.Final),因此我们必须找到一种方法来绕过黑名单。黑名单可以在resources/org/jboss/seam/blacklist.properties中找到。
|
|
通过一点研究,我们发现黑名单只是一个简单的字符串匹配,我们都知道黑名单总是一个坏主意。我第一次看到这个时,我想起了Struts2 S2-020的绕过。那个绕过和这个的想法是一样的。使用类似数组的操作符来避免黑名单模式!只需更改:
|
|
为
|
|
简单吗?是的!就这样。
所以最后一件事是用JBoss EL编写shellcode。我们使用Java反射API来获取java.lang.Runtime对象,并从中列出所有方法。索引7是方法getRuntime()以返回Runtime实例,索引15是方法exec(String)以执行我们的命令!
好的!让我们总结我们的步骤并将所有内容链接在一起!
- 路径规范化漏洞导致ACL绕过
- 绕过白名单以访问未经授权的Seam servlet
- 使用Seam特性actionMethod调用文件suggest_add_new_directory_entry_iframe.xhtml中的gadget
- 在HTTP参数directoryNameForPopup中准备第二阶段payload
- 使用类似数组的操作符绕过EL黑名单
- 使用Java反射API编写shellcode
- 等待我们的shell返回并像老板一样获胜 ._./
以下是整个漏洞利用:
(Perl脚本代码)
好的,通过执行Perl脚本,我们得到了shell!
修复
我将从3个方面说明修复!
1. JBoss
由于最漏洞百出的事情是在Seam框架上。我在2016年9月向security@jboss.org报告了这些“特性”。但他们的回复是:
非常感谢您向我们报告这些问题。
Seam仅包含在EAP 5中,而不是6或7。EAP已接近维护支持的结束,将在2016年11月结束,[1]。您用于测试的上游版本是3年前发布的。 在维护支持期间,EAP 5仅接收重要或关键问题的补丁。虽然您强调RCE是可能的,但前提是攻击者可以首先上传文件。这似乎将影响降低到中等。
我们认为在Seam项目生命周期的这个阶段不会费心修复这些安全问题。
[1] https://access.redhat.com/support/policy/updates/jboss_notes/
我们非常感谢您向我们报告这些问题的努力,并希望您将来继续告知我们安全问题。
由于EOL,似乎没有这些疯狂特性的官方补丁。然而,世界上仍然有很多Seam应用程序在运行。所以如果你使用Seam。我建议你使用Nuxeo的修复来缓解这个问题。
2. 亚马逊
通过快速调查,亚马逊安全团队隔离了服务器,与报告者讨论了如何缓解,并详细列出了他们采取的每一步!与他们合作是一次很好的体验 :)
3. Nuxeo
在亚马逊通知后,Nuxeo迅速在8.10版本发布了补丁。该补丁重写了方法callAction()以修复疯狂特性!如果你需要为你的Seam应用程序打补丁。你可以在这里参考补丁!
时间线
- 2018年3月10日 01:13 GMT+8 通过aws-security@amazon.com向亚马逊安全团队报告
- 2018年3月10日 01:38 GMT+8 收到他们正在调查的回复
- 2018年3月10日 03:12 GMT+8 询问是否可以参加与安全团队的电话会议
- 2018年3月10日 05:30 GMT+8 与亚马逊进行电话会议,了解漏洞的状态和他们采取的步骤
- 2018年3月10日 16:05 GMT+8 询问是否可以在我的Black Hat演讲中公开披露
- 2018年3月15日 04:58 GMT+8 Nuxeo发布了新版本8.10,修补了RCE漏洞
- 2018年3月15日 23:00 GMT+8 与亚马逊进行电话会议,了解状态并讨论公开披露细节
- 2018年4月5日 05:40 GMT+8 获得亚马逊的奖励