CC1链路分析


总体思路:利用lazy调用decorate()方法的第二个参数Transformer可控,该接口有三个重要的实现类

Transformer可以理解为一个转换器,当做工厂的一个加工程序,进入转换器需要做点事情才能输出,不同的转换器进行不同的处理,如下列举三个 CC1链子用到的转换器

  • ConstantTransformer:当调用其 transform 方法时,它将返回构造时传入的 对象
  • InvokerTransformer:初始化此类后,调用 transform 方法将通过反射创建对象实例

  • ChainedTransformer:将各个 Transformer  连接在一起,使用上一个 Transformer 的结果作为下一个 Transformer 的输入

使用方法3链式调用方法1生成一个Runtime对象,同时利用方法2去获取Runtime对象的getRuntime()运行时环境,再获取invoke来执行相关命令(包括系统敏感的命令),这里涉及到Java反射机制的原理

要想触发decorate()方法,需要调用map.get(),但是yso不需要lazymap直接使用该方法,于是可以使用AnnotationInvocationHandler的invoke方法(实现了调用map.get()方法)

AnnotationInvocationHandler类是动态代理InvocationHandler接口的一个实现类,使用AnnotationInvocationHandler来创建一个上边map的动态代理proxy_map

由于需要执行AnnotationInvocationHandler的invoke方法,所以需要再对proxy_map进行AnnotationInvocationHandler代理来执行自身的invoke方法

Gadget chain:
		ObjectInputStream.readObject()
			AnnotationInvocationHandler.readObject()
				Map(Proxy).entrySet()
					AnnotationInvocationHandler.invoke()
						LazyMap.get()
							ChainedTransformer.transform()
								ConstantTransformer.transform()
								InvokerTransformer.transform()
									Method.invoke()
										Class.getMethod()
								InvokerTransformer.transform()
									Method.invoke()
										Runtime.getRuntime()
								InvokerTransformer.transform()
									Method.invoke()
										Runtime.exec()

CommonsCollections

Java版本为 1.7

<dependency>
    <groupId>commons-collections</groupId>
    <artifactId>commons-collections</artifactId>
    <version>3.2.1</version>
</dependency>

LazyMap

官方文档:https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/map/LazyMap.html

简介:修饰另一个 map,当调用 map 中不存在的 key 时使用工厂创建对象

多说无益,上代码

package com.chuxia.cc1;

import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.map.LazyMap;
import org.apache.commons.lang3.StringUtils;

import java.util.HashMap;
import java.util.Map;

public class TestLazyMap {
    public static void main(String[] args) {
        //  定义处理不存在 key 的情况,可以是 Transformer 也可以是 ChainedTransformer 链子
        //  用于反转调用不存在的 key 值
        final Transformer reverseString = new Transformer() {
            public Object transform(Object object) {
                String name = (String) object;
                String reverse = StringUtils.reverse(name);
                return reverse;
            }
        };

        Map names = new HashMap();
        //  将处理链传给 lazyMap
        Map lazyMap = LazyMap.decorate(names, reverseString);
        //  lazyMap 为空,测试调用不存在 key
        String name = (String) lazyMap.get("chuxia");
        System.out.println("name:" + name);
        //  put 一个键值
        lazyMap.put("chuxia", "TestLazyMap");
        //  key 存在,不进入处理链
        name = (String) lazyMap.get("chuxia");
        System.out.println("name:" + name);
    }
}

可以看到 La

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值