Java 反序列化概念比 PHP 抽象,链子靠工具生成,一开始完全是黑盒。按理解顺序:机制 → CC6 → Shiro 550 → 内存马。
Java 序列化机制速览
Serializable对象经ObjectOutputStream.writeObject()序列化成字节流,readObject()还原;字节流以AC ED 00 05开头,Base64 后是rO0AB——Cookie/参数里见到它就要警觉。- 类可自定义
readObject(),反序列化时自动调用——对应 PHP 魔术方法的”引爆点”。
CC6 链到底在干什么
CC6 是 CC 链里路径最短的:
java.util.HashMap.readObject()
→ hash(key)
→ TiedMapEntry.hashCode()
→ getValue()
→ LazyMap.get()
→ ChainedTransformer.transform()
→ InvokerTransformer 反射执行任意方法
transformer 链是一条”延迟执行的管道”:每个 Transformer 把能力转交下一个,最后由 InvokerTransformer 反射执行 Runtime.exec();HashMap 提供触发入口。
链子可用 ysoserial 生成。
Shiro 550(rememberMe 反序列化)
- 原理:rememberMe Cookie 是 AES 加密 + Base64 的序列化对象;老版本默认硬编码密钥(
kPH+bIxk5D2deZiIxcaaaA==),拿到密钥就能加密自己的恶意序列化数据。 - 验证流程(靶场环境):
- 抓包看 Cookie 有没有
rememberMe=deleteMe回显(判断 Shiro 框架) - 用 known-key 字典跑密钥(Shiro 721/550 工具都集成这步)
- 命中后选链生成 payload 加密写入 Cookie 发送,DNSLog 收回显
- 抓包看 Cookie 有没有
- 注意点:CC 链依赖目标 classpath 里有对应版本的 CommonsCollections,打不通先换链(CC2/CC4/CC6/CommonsBeanutils),别死磕一条。
冰蝎与内存马
文件型 WebShell 落地即有特征;内存马把代码直接注册进运行中的容器(Filter/Servlet/Listener 型),不落盘、重启即消失:
- Filter 型:动态注册 Filter 插到 FilterChain 最前面,请求先进内存马
- 冰蝎流量特征(防守视角):固定 Accept 头、Content-Type 怪异、AES 密钥协商阶段的固定报文
- 查杀:比对 FilterMap 里的陌生 Filter、dump 内存分析、专用工具(河马 WebShell 查杀、arthas)
学习建议
别一上来啃 CC1(最长那条),顺序:URLDNS(入口)→ CC6(最短链)→ Shiro 550(实战)→ CC1-CC5;环境用 vulhub 的 Shiro 靶场。