javaCC链-CC1

1. 环境搭建

JDK版本:jdk8u65
commons-collections 3.2.1
Maven依赖:

<dependencies>
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

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

2. CC1链的核心思路

  1. 有个“万能遥控器”——InvokerTransformer
    • 这个类有个 transform 方法,可以用来“反射”调用任何你想要的方法,比如 Runtime.getRuntime().exec("calc"),就能弹出计算器。
  2. 找个“帮手”能帮你自动按下遥控器——TransformedMap
    • 这个 Map 可以在你往里面放数据或者修改数据时,自动调用你指定的 transform 方法。
  3. 把遥控器装进帮手手里
    • 用 TransformedMap.decorate(map, null, invokerTransformer) 把 InvokerTransformer 作为 valueTransformer 装进去。
  4. 找个“触发器”让帮手动起来
    • 只要有人调用 TransformedMap 的 setValue 方法(比如遍历 entrySet 的时候),就会自动触发 transform,也就是执行你想要的命令。
  5. 最后一步:让这些东西在反序列化时自动触发
    • Java 反序列化时会自动调用某些方法(比如 readObject),而 AnnotationInvocationHandler 这个类在反序列化时会遍历 Map 并 setValue,从而触发整个链条。

3. 分析

cc1链起点是commons-collections包的Transformer接口,这个接口的transform方法接收一个对象作为参数

3.1. 万能遥控器—— InvokerTransformer

InvokerTransformer 是 commons-collections 3.2.1 包中的一个,也是我们的入口类,其全名是:
org.apache.commons.collections.functors.InvokerTransformer

3.1.1. 作用

它可以让你通过 transform 方法,反射调用任何你想要的方法
在 CC1 链中,它就是“遥控器”,用来执行恶意命令的关键
Pasted image 20250505230512.png

3.1.2. 例子

// 创建一个 InvokerTransformer,指定调用 exec 方法,参数是 "calc"
InvokerTransformer transformer = new InvokerTransformer(
    "exec", new Class[]{String.class}, new Object[]{"calc"}
);

当你调用 transformer.transform(Runtime.getRuntime()) 时,它就会执行:Runtime.getRuntime().exec("calc"); 触发计算器
Pasted image 20250505230817.png

3.2. TransformedMap-按下遥控器的帮手

它是一个可以在存取数据时自动对 key 或 value 进行“变换处理”的 Map。
这个 Map 可以在你往里面放数据或者修改数据时,自动调用你指定的 transform 方法。

3.2.1. 作用

  • 当你往 TransformedMap 里 put、setValue 或修改数据时,它会自动调用你指定的 Transformer,把 key 或 value 变换成你想要的样子。
  • 你可以单独指定 keyTransformer(处理 key)和 valueTransformer(处理 value)
  • 攻击者把 valueTransformer 设置成恶意的 InvokerTransformer
  • 只要有人往这个 Map 里 setValue 或 put,就会自动执行 transform 方法,从而执行恶意代码
为什么会自动执行 transform 方法
  • 当你调用 put(key, value) 或 setValue(value) 时,TransformedMap 会自动调用你传进去的 valueTransformer 的 transform(value) 方法,把 value 先“加工”一下,再存进去。

  • 如果你传进去的 valueTransformer 是一个恶意的 InvokerTransformer,那么 transform 方法里就会执行你想要的恶意操作。

你可以把 TransformedMap 想象成一个“智能快递柜”:

  • 你往柜子里放快递(put/setValue),柜子会自动帮你消毒(transform)。

  • 你指定的消毒方式(Transformer)是什么,柜子就怎么处理。


org.apache.commons.collections.functors.InvokerTransformer
可以看到我们这个payload就是先new了一个 InvokerTransformer
小框框中的是他的三个参数:iMethodName,iParamTypes,iArgs都是可控的
Pasted image 20250505213249.png

然后通过它的transform方法使用了反射来调用input的方法,
且传入的这个input对象也是可控的
Pasted image 20250505213415.png

我们可以通过直接利用invoketransformer的代码,执行过后就会触发计算器

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

public class CC1 {
    public static void main(String[] args) {
        new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"}).transform(Runtime.getRuntime());
    }
}

PixPin_2025-05-04_22-01-17.gif

然后我们去找一个其它的类有transform方法,并且传入的Object是可控的,然后我们只要把这个Object设为InvokeTransformer即可,我们全局搜索transform方法,能够发现很多类都是有transform方法的,我们这里先研究的是CC1,所以我们直接看 TransformerMap

然后我们查找用法,看有那些类也用了这个 transform(object)
Pasted image 20250505223330.png

TransformedMap 中的checkSetValue方法中调用了transform,valueTransformer是构造的时候赋的值,再看构造函数
Pasted image 20250505224601.png

构造函数是一个protected,所以不能让我们直接实例赋值,只能是类内部构造赋值,找哪里调用了构造函数
Pasted image 20250505224749.png

这里找到了一个静态方法,这里我们就能控制参数了
Pasted image 20250505224904.png