Java安全 CC链1分析

本文围绕Java的CC链展开,介绍了CC链是因Apache Commons Collections组件使用导致的反序列化漏洞。详细说明了环境搭建,包括JDK下载、Idea配置和项目创建。阐述了Transformer接口及其实现类等前置知识,重点分析了CC链1的构造,从核心代码到触发机制,最终给出完整的CC链1 exp。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是CC链

Apache Commons工具包中有⼀个组件叫做 Apache Commons Collections ,其封装了Java 的 Collection(集合) 相关类对象,它提供了很多强有⼒的数据结构类型并且实现了各种集合工具类,Commons Collections被⼴泛应⽤于各种Java应⽤的开发,而正是因为在大量web应⽤程序中这些类的实现以及⽅法的调用,导致了反序列化漏洞的普遍性和严重性

Apache Commons Collections中有⼀个特殊的接口,其中有⼀个实现该接口的类可以通过调用 Java的反射机制来调用任意函数,叫做InvokerTransformer,它可通过反射调用类中的方法,从而通过一连串的调用而造成命令执行,这条链便叫做Commons Collections链(简称cc链)。

建议学习cc链之前先学一下Java的反射机制

环境搭建

jdk下载

我们一共需要下载两个东西

  • CommonsCollections <= 3.2.1
  • java 8u66 (高版本的jdk有些漏洞已被修复)

java 8u66下载地址
在这里插入图片描述

一些源码为class文件,idea反编译出来的文件不方便阅读,我们需要去下载openjdk的源码,并导入我们的jdk中

下载地址
在这里插入图片描述

在jdk 8u66安装好后,我们进入安装目录的jdk1.8.0_65文件夹,将 src.zip 解压到当前文件夹
在这里插入图片描述

然后将刚才下好的openjdk源码解压,并来到src\share\classes下面,将sun文件夹复制到jdk的src目录中

idea配置

我们点击左上角的项目结构
在这里插入图片描述

然后将jdk的src目录分别添加到类路径和源路径中
在这里插入图片描述

创建项目

我们构建系统选择Maven然后创建名为cc1的项目
在这里插入图片描述

然后在项目左侧的文件栏中选择 pom.xml 并在其中添加以下内容

用于下载commons-collections依赖

    <dependencies>
        <!-- https://mvnrepository.com/artifact/commons-collections/commons-collections -->
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.1</version>
        </dependency>
    </dependencies>

最后右键 pom.xml,再点击 Maven选项,按图上标号顺序点击即可

生成源代码需要等待一小会,等目录中出现target文件夹时即可点击 重新加载项目
在这里插入图片描述

到此我们所需环境配置完成,下面开始调试分析

前置知识

Transformer接口

接口代码为

public interface Transformer {
   
    public Object transform(Object input);
}

该接口实现了对 对象 的转化,对传入的对象进行一些操作,然后并返回操作完的对象

该接口的重要实现有:

  • ConstantTransformer
  • invokerTransformer
  • ChainedTransformer
  • TransformedMap

这些实现的类都与CC链有关,以下是对这些实现的介绍

ConstantTransformer类

ConstantTransformer类的代码为

public class ConstantTransformer implements Transformer, Serializable {
   
    public static Transformer getInstance(Object constantToReturn) {
   
        if (constantToReturn == null) {
   
            return NULL_INSTANCE;
        }
        return new ConstantTransformer(constantToReturn);
    }
    public ConstantTransformer(Object constantToReturn) {
   
        super();
        iConstant = constantToReturn;
    }
    public Object transform(Object input) {
   
        return iConstant;
    }
    public Object getConstant() {
   
        return iConstant;
    }
}

我们着重分析下ConstantTransformer构造方法和transform方法

其ConstantTransformer构造方法接收任意类型对象,并赋值给 iConstant 变量,然后无论 transform方法接收什么 input 参数,其都会返回 iConstant 变量,也就是说假如只调用构造方法和transform方法的话,我们传入什么对象,就会原封不动地返回什么对象

invokerTransformer类

invokerTransformer类的代码为

public class InvokerTransformer implements Transformer, Serializable {
   
    private static final long serialVersionUID = -8653385846894047688L;
    private final String iMethodName;
    private final Class[] iParamTypes;
    private final Object[] iArgs;
    public static Transformer getInstance(String methodName) {
   
        if (methodName == null) {
   
            throw new IllegalArgumentException("The method to invoke must not be null");
        }
        return new InvokerTransformer(methodName);
    }
    public static Transformer getInstance(String methodName, Class[] paramTypes, Object[] args) {
   
        if (methodName == null) {
   
            throw new IllegalArgumentException("The method to invoke must not be null");
        }
        if (((paramTypes == null) && (args != null))
            || ((paramTypes != null) && (args == null))
            || ((paramTypes != null) && (args != null) && (paramTypes.length != args.length))) {
   
            throw new IllegalArgumentException("The parameter types must match the arguments");
        }
        if (paramTypes == null || paramTypes.length == 0) {
   
            return new InvokerTransformer(methodName);
        } else {
   
            paramTypes = (Class[]) paramTypes.clone();
            args = (Object[]) args.clone();
            return new InvokerTransformer(methodName, paramTypes, args);
        }
    }
    private InvokerTransformer(String methodName) {
   
        super();
        iMethodName = methodName;
        iParamTypes = null;
        iArgs = null;
    }
    public InvokerTransformer(String methodName, Class[] paramTypes, Object[] args) {
   
        super();
        iMethodName = methodName;
        iParamTypes = paramTypes;
        iArgs = args;
    }
    public Object transform(Object input) {
   
        if (input == null) {
   
            return null;
        }
        try {
   
            Class cls = input.getClass();
            Method method = cls.getMethod(iMethodName, iParamTypes);
            return method.invoke(input, iArgs);
                
        } catch (NoSuchMethodException ex) {
   
            throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' does not exist");
        } catch (IllegalAccessException ex) {
   
            throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' cannot be accessed");
        } catch (InvocationTargetException ex) {
   
            throw new FunctorException("InvokerTransformer: The method '" + iMethodName + "' on '" + input.getClass() + "' threw an exception", ex);
        }
    }

}

我们同样分析下 InvokerTransformer构造方法和transform方法

构造方法为

    public InvokerTransformer
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Elitewa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值