CVE-2013-0422

CVE-2013-0422漏洞简略分析

简介

此漏洞属于JAVA7的设计缺陷,该漏洞主要利用了MBeanInstantiator类中FindClass函数能够查找到任何包内任何类的对象的功能,使得Applet获得了本来无权访问的类;
然后又利用了在JDK1.7中新增的动态实现细节中MethodHandles.Lookup类中findConstructor及findVirtual函数创建了Classloader,并加载了恶意类.

调试环境

本机:Eclipse;win7 x64;jre-7u5-windows-i586;Metasploit 4.6
虚拟机:win xp sp3;jre-7u5-windows-i586;IE8

Metasploit测试

1.首先在Metasploit里边做下漏洞利用测试,配置环境如下所示:

2.之后在虚拟机中IE8输入上边的URL地址之后在Metasploit内就可以得到shell窗口了。
地址:http://192.168.237.1:8080/SIBwjkLzdI

测试代码

首先看下正常情况下的本地测试,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import java.io.IOException;   
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Policy;
import java.security.ProtectionDomain;
import java.util.Enumeration;
import javax.swing.JOptionPane;

public class Test {
void checkPermission() {
ProtectionDomain domain = this.getClass().getProtectionDomain();
PermissionCollection pcoll = Policy.getPolicy().getPermissions(domain);
Enumeration e = pcoll.elements();
int i = 0;
for (; e.hasMoreElements();) {
Permission p = (Permission) e.nextElement();
System.out.println(i + ": " + p);
i++;
}
System.out.println("the num:" + i);
}

void alert() throws IOException {
try {
Runtime.getRuntime().exec("calc.exe");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw e;
}
}

public static void main(String[] args) {
try{
// TODO Auto-generated method stub
Test test = new Test();
// test.checkPermission();
System.out.println("1.SecurityManager 开启前测试");
try {
test.alert();
System.out.println("2.成功执行 exec");
} catch (SecurityException e) {
System.out.println("2.you have no permission to exec");
}
System.out.println("3.开启SecurityManager");
System.setSecurityManager(new SecurityManager());
System.out.println("4.SecurityManager 开启后测试");
try {
test.alert();
System.out.println("5.成功执行 exec");
} catch (SecurityException e) {
System.out.println("5.you have no permission to exec");
}
}catch (Throwable e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}

运行结果:
1.SecurityManager 开启前测试
2.成功执行 exec //弹出计算器
3.开启SecurityManager
4.SecurityManager 开启后测试
5.you have no permission to exec
可见,在开启SecurityManager的情况下是不具有执行exec权限的。

关键代码分析

该漏洞关键代码如下:

1.

由于MBeanInstantiator.findClass函数能够获得任意包中的任意类,因此其继承类
localMBeanInstantiator能够访问原本无权访问的sun.org.mozilla.javascript.internal.Context 及
sun.org.mozilla.javascript.internal.GeneratedClassLoader类;
其中,localClass1 及localClass2分别是两个类的引用.

2.

根据Java7中MethodHandles的动态调用功能, MethodHandles.Lookup 类中包含findVirtual(), findConstructor(), findStatic() , findSpecial() 四个函数。第 三 行localLookup.findVirtual 函 数返回了MethodHandles.Lookup类的findConstructor 函数,指其定类型为localMethodHandle1;之后指定locaMethodType2 的类型为Void型。

由于localMethodHandle1为MethodHandles.Lookup的findConstructor函数句柄,localClass1 为MBean中已经加载的sun.org.mozilla.javascript.internal.Context对象的引用,故调用invokeWithArguments函数即为在JVM中寻找sun.org.mozilla.javascript.internal.Context类的构造函数,返回该类构造函数的句柄为localMethodHandle2, 于是接下来的调用localMethodHandle2.invokeWithArguments即是创建sun.org.mozilla.javascript.internal.Context类的实例对象localObject1.至此通过
MBeanInstantiator类与MethodHandles类,实现了在Applet类中访问原本无权访问
的sun.org.mozilla.javascript.internal.Context类的目的.

3.

方法与上面2相同,localMethodHandle3为MethodHandles.Lookup类findVirutal()函数句柄,类型为localMethodType3。

通过findVirtual函数得到sun.org.mozilla.javascript.internal.Context类的createClassLoader函数,localMethodHandle4即为createClassLoader句柄;

通过调用localObject1的createClassLoader函数创建了一个新的classLoader. localObject2为ClassLoader的实例.

通过MethodHandles.Lookup函数的findVirtual()查找到sun.org.mozilla.javascript.internal.GeneratedClassLoader类的defineClass函数,函数类
型由localMethodType5 指定.此时localMethodHandle5 为defineClass函数类型.

通过调用localObject2类的defineClass函数将arrayOfByteBuff加载到JVM中,并创建为对象
localClass3,此时localClass3具有与localObject2相同的系统权限.

4.当执行localClass3.newInstance 时,在其实现中去掉了系统的SecurityManager,到此完
全关闭了系统的安全策略,从而实现了exploit.