jdk7u21链的分析
前言
分析jdk7u21链。
实验环境
Osx 14.6,jdk7u21,ysoserial最新版。
实验步骤
直接使用ysoerial生成 jdk7u21的链的oayload,然后将断点下在Runtime的exec
1
2
3
4
5
6
7
8
9try {
FileInputStream fis=new FileInputStream("payload");
ObjectInputStream obs=new ObjectInputStream(fis);
Object o=obs.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}调用链如下
ysoserial最终生成的对象是啥样
第一个对象是TemplatesImpl对象,第二个对象实现了动态代理,接口用的是AnnotationInvocationHandler,代理了Templates基类的实现对象。
链分析
- LinkedHashSet
- TemplatesImpl
- Proxy(Templates)
- Handler:AnnotationInvocationHandler
- AnnotationInvocationHandler.invoke
- AnnotationInvocationHandler.equalsImpl
- Method.invoke
- TemplatesImpl.newTransformer
- create evil class object
- TemplatesImpl.newTransformer
- Method.invoke
- AnnotationInvocationHandler.equalsImpl
- AnnotationInvocationHandler.invoke
- Handler:AnnotationInvocationHandler
现在来实际跟一下。
HashSet的readObject会依次反序列化成员对象并且加入集合,在加入集合中调用put方法。
在put方法中有两个方法需要注意,一个是hash方法,最终会调用hashcode方法,另外一个是equals方法。hashcode方法是一个常见的Gadget,但是这里主要用到了equals方法作为跳板。由于第一轮集合为空所以不触发循环。
在第二轮的时候会进入循环,触发代理对象的equals方法。因为是动态代理的缘故,所以会触发Handler中的invoke方法,并最终进入equalsImpl方法。
在equalsImpl方法中,需要构造type来满足比较对象类型相同,然后需要伪造memberValues,来获取Method对象,需要注意的是这里可以使用的Method需要是无参的,这也是最终利用链选择TemplatesImpl利用的理由。
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
35private Boolean equalsImpl(Object var1) {
if (var1 == this) {
return true;
} else if (!this.type.isInstance(var1)) {
return false;
} else {
Method[] var2 = this.getMemberMethods();
int var3 = var2.length;
for(int var4 = 0; var4 < var3; ++var4) {
Method var5 = var2[var4];
String var6 = var5.getName();
Object var7 = this.memberValues.get(var6);
Object var8 = null;
AnnotationInvocationHandler var9 = this.asOneOfUs(var1);
if (var9 != null) {
var8 = var9.memberValues.get(var6);
} else {
try {
var8 = var5.invoke(var1);
} catch (InvocationTargetException var11) {
return false;
} catch (IllegalAccessException var12) {
throw new AssertionError(var12);
}
}
if (!memberValueEquals(var7, var8)) {
return false;
}
}
return true;
}
}跟入TemplatesImpl的利用链,这里触发getTransletInstance方法。
需要置空_name和_class来加载字节码。
创建一个AbstractTranslet实例,evilcode一般都写在这个类中的构造器里,创建即执行。
弹计算器
- LinkedHashSet
总结与思考
该链用到了相当程度的java知识,所以分析起来需要一些耐心,动态代理的部分可以自己写个demo来理解概念,其他部分跟完payload就基本上明白了。