准备
编译Gondvv.java,生成在Gondvv.class,在同目录下新建test.htm,内容如下

<APPLET CODE="Gondvv.class" WIDTH=200 HEIGHT=100> </APPLET>

粗略观察一下java代码,应该是绕过了Java Sandbox,而并非是JVM中溢出等漏洞,所以可以直接调试java代码。

setSecurityManager

首先需要简单了解setSecurityManager()函数。setSecurityManager()用于设置一个SystemSecurity。如果已经设置过securityManager,调用setSecurityManager时则会调用checkPermission检查权限是否正确。同样可以通过调用setSecurityManager来替换掉一个现有的securityManager。所以绕过SandBox的方法一般为禁用掉SecurityManager,调用setSecurityManager()函数,并传入null参数。如下图

首先对setSecurityManager()下断点,检查函数调用链,看是在何处修改security manager。

中断在setSecurityManager(),观察函数调用链

可以在调用链中观察到Gondvv中的代码,调用了Gondvv.disableSecurity()函数。并且观察一下setSecurityManager()的参数,为null,这是一个取消security manager的操作,若执行成功,则可以绕过其权限检查,从而任意执行命令。链中出现Gondvv的代码,为非信任代码,却仍成功关闭SecurityManager,猜测可能是权限被修改。

代码分析

下面开始分析Gondvv.java中的disableSecurity()函数。

首 先 创 建 表 达 式 , 用 于 执 行setSecurityManager()。但是,若直接执行则会触发setSecurityManager()中checkPermission()的检查,导致失败

所以在Gondvv.java中,首先修改上下文为AllPermission,以保证以AllPermission权限调用

setSecurityManager(),绕过检查。下图为准备设置的新权限。

接着调用关键函数,在此函数内,完成权限的更改。

创建一个表达式,用来获取到SunToolkit,在java6中是获取不到的,java7中的ClassFinder

可以获取到SunToolkit

查看GetClass的实现,是表达式调用Class.forName(“sun.awt.SunToolkit”),用来获取SunToolkit

接着会在Expression.invoke()调用到ClassFinder.findClass(),如下图


此时可以观察ClassFinder.findClass()的参数,正是“sun.awt.SunToolkit”,通过ClassFinder类成功的获取到了我们想要的信息

其中”acc”为Statement中的私有成员,用于控制当前Statement上下文的访问权限

getField()为sun.awt.SunToolkit中的一个公有方法,并返回一个对象的引用(Field类型),并且

该方法可以获取到私有成员,如下图

以下表达式实际为SunToolkit.getField(Statement.class, “acc”),即执行该表达式后,即可返

回”acc”的引用

此时已成功获取acc对象,可直接修改其权限。

调用Field类的set方法,成功的将传入的localStatement上下文设置为AllPermission,localStatement上下文权限已被修改,执行该Statement将可通过setSecurityManager()中的权限检查,将SecurityManager置为null

执行Statement,即可执行任意命令。

Exploit中弹出calc

漏洞成因

sun.awt.SunToolkit本身就是安全机制实现的一部分,按照SandBox的机制,是不应该让不信任的代码直接获取到该类库的,而ClassFinder.findClass()却没有考虑这一点,致使攻击者可以获取到SunToolkit,修改自身权限,进而关闭SecurityManager.

源链接

Hacking more

...