首页
社区
课程
招聘
[翻译]Java类型混淆,沙箱逃逸
发表于: 2018-6-4 11:29 5901

[翻译]Java类型混淆,沙箱逃逸

2018-6-4 11:29
5901


    上周,甲骨文公司公布了他们的季度重要补丁更新(CPU)。其中7个漏洞通过ZDI计划提交,其中的一个让人想起2012年底和2013年初的java提交。这个漏洞,CVE-2018-2826 (ZDI-18-307),是一个因类型检查不足引起的沙箱逃逸漏洞,由xor19发现。一个拥有低执行权限的攻击者可以利用这个漏洞来绕过SecurityManager并提权。

漏洞

    漏洞位于反射API(java.lang.invoke.MethodHandles::tryFinally(MethodHandle target, MethodHandle cleanup)方法的实现里。从这以后我会把该API称为MethodHandles::tryFinally()。该API返回一个方法句柄,这个句柄通过把目标方法包进一个try-finally块来改写它。这个cleanup方法句柄体现了final块的功能。任何在目标句柄执行期间抛出的异常都会被传递给cleanup句柄。

在MethodHandles::tryFinally()的实现里,不充分的类型检查发生了。对一个攻击者来说,在目标和cleanup方法句柄之间指派不匹配的Throwalbe对象是可能的,从而引起类型混淆。这样攻击者就可以把任何对象转化成任何类型。

一个例子

    假设我们有下面两个类和方法。

    攻击者构造了一个throwEx()的方法句柄和handleEx()作为cleanup.注意throwEx抛出一个Cast1类型的Throwable异常并且handleEx()处理Cast2类型的Throwalbe异常。当攻击者在一个漏洞版本的java调用新创建的方法句柄,它把Cast1类型的Throwable对象传递给了handleEx(),handleEx()处理Cast2类型的Throwable对象,并没有对传入类型有任何处理或者适当的类型检查。当handleEx()继续处理Throwable异常时,它把Lemon对象当做了Lime,这允许攻击者把Lemon转换成Lime,用Lemon类调用了Lime类的makeLimenade()方法。

利用

    在漏洞利用里,攻击者尝试通过反射函数把Security Manager置为空来绕过它。首先,攻击者通过MethodHandles::publicLookup()方法得到一个setSecurityManager的方法句柄。然而,正常情况下setSecurityManager不能被MethodHandles::publicLookup()访问,所以攻击者定义了下面的代码并且利用类型混淆漏洞把Lookup对象转换成伪造的LookupMirror对象。

    在handleEx()方法,攻击者把Lookup对象当作LookupMirror对象来操作。从下面相关的OpenJDK源代码可以看到,攻击者已经把Lookup对象的allowedModes属性改成了TRUSTED,从而允许攻击者得到任何方法的方法句柄,包括setSecurityManager()。

    最终,攻击者使用可信的Lookup对象得到了setSecurityManager()的方法句柄并且把SecurityManager设置为空从而绕过SecurityManager产生的所有限制。

补丁


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
支持
分享
最新回复 (2)
雪    币: 6818
活跃值: (153)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
2018-6-10 22:49
0
雪    币: 36
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
2018-6-11 10:33
0
游客
登录 | 注册 方可回帖
返回
//