反序列化漏洞
反序列化
反序列化漏洞是 Web 安全中极具危害性的漏洞类型,其核心是 攻击者通过构造恶意的序列化数据,诱导程序在反序列化过程中执行非预期操作(如远程代码执行、服务器权限夺取等)。下面从基础概念、漏洞原理、危害、典型案例到防御措施进行详细讲解。
一、序列化与反序列化
要理解反序列化漏洞,需先明确两个核心操作:
- 序列化(Serialization):
将内存中的对象(包含数据和方法)转换为可传输 / 存储的格式(如字节流、JSON、XML、特定二进制格式等)的过程。目的是方便数据在网络传输或本地存储(例如保存到文件、数据库)。
例:Java 中通过ObjectOutputStream.writeObject()将对象转为字节流;PHP 中通过serialize()生成字符串。 - 反序列化(Deserialization):
将序列化后的数据流恢复为内存中原始对象的过程。程序通过反序列化,可重新获取对象的状态和方法,继续使用该对象。
例:Java 中通过ObjectInputStream.readObject()恢复对象;PHP 中通过unserialize()解析字符串。
二、原理
反序列化漏洞的本质是:程序在反序列化时,未对输入的序列化数据进行严格校验,导致攻击者可以构造恶意数据,利用反序列化过程中自动触发的代码(如类的魔术方法、回调函数)执行恶意操作。
关键前提:
- 程序存在反序列化操作(即接收外部输入的序列化数据并解析);
- 反序列化的类中存在可被利用的代码(如魔术方法、危险函数调用);
- 攻击者能控制反序列化的输入数据。
三、案例
不同编程语言的序列化机制不同,漏洞利用方式也有差异,以下是典型案例:
-
Java 反序列化漏洞
Java 的序列化基于Serializable接口,反序列化时通过readObject()方法恢复对象,且过程中可能触发类的自定义逻辑(如重写的readObject()方法)。-
典型案例:
Apache Commons Collections漏洞(CVE-2015-7501)
Apache Commons Collections是 Java 常用工具库,其中TransformingComparator类的compare()方法会调用 Transformer 接口的transform()方法。攻击者可构造恶意序列化数据,将 Transformer 替换为可执行命令的类(如InvokerTransformer,可调用Runtime.exec()),当反序列化时,compare()被自动触发,最终执行系统命令。 -
利用流程:
攻击者构造包含恶意 Transformer 链的序列化对象 → 目标程序反序列化该对象 → 触发compare()方法 → 执行Runtime.exec("恶意命令")。
-
-
PHP 反序列化漏洞
PHP 的序列化格式是字符串class S{ public $test="pikachu"; } $s=new S(); //创建一个对象 serialize($s); /* 把这个对象进行序列化 序列化后得到的结果是这个样子的:O:1:"S":1:{s:4:"test";s:7:"pikachu";} O:代表object 1:代表对象名字长度为一个字符 S:对象的名称 1:代表对象里面有一个变量 s:数据类型 4:变量名称的长度 test:变量名称 s:数据类型 7:变量值的长度 pikachu:变量值 */反序列化时通过
unserialize()函数解析$u=unserialize("O:1:"S":1:{s:4:"test";s:7:"pikachu";}"); echo $u->test; //得到的结果为pikachu且会自动触发类的魔术方法常见的几个魔法函数:
__construct() //当一个对象创建时被调用 __destruct() //当一个对象销毁时被调用 __toString() //当一个对象被当作一个字符串使用 __sleep() //在对象在被序列化之前运行 __wakeup() //将在序列化之后立即被调用-
典型场景:
若某个类的魔术方法中存在危险操作(如__destruct()调用file_put_contents()写入文件,且参数可控),攻击者可构造序列化数据,控制该参数写入恶意代码(如 PHP 一句话木马)。 -
示例代码:
class Evil { private $data; function __destruct() { // 危险操作:将$data写入文件 file_put_contents('/var/www/html/shell.php', $this->data); } } // 攻击者构造恶意序列化数据:将$data设为"<?php eval($_POST['cmd']);?>" $malicious = 'O:4:"Evil":1:{s:9:"Evildata";s:28:"<?php eval($_POST[\'cmd\']);?>";}'; unserialize($malicious); // 反序列化时触发__destruct(),写入木马 -
-
Python 反序列化漏洞
Python 的 pickle 模块用于序列化(pickle.dumps())和反序列化(pickle.loads()),其反序列化过程会执行数据中包含的 Python 代码(如函数调用、类实例化),因此风险极高。- 示例:
攻击者构造包含os.system("恶意命令")的 pickle 数据,目标程序调用pickle.loads()解析时,会直接执行命令:
import pickle import os # 恶意序列化数据:执行"ls"命令 malicious_data = b'''cos system (S'ls' tR.''' pickle.loads(malicious_data) # 反序列化时执行ls命令 - 示例:
四、危害
反序列化漏洞的危害程度极高,主要包括:
- 远程代码执行(RCE):最严重的危害,攻击者可直接执行系统命令(如删除文件、反弹 shell),夺取服务器控制权;
- 数据泄露:通过恶意操作读取敏感数据(如数据库密码、用户信息);
- 拒绝服务(DoS):构造特殊数据导致反序列化过程无限循环或资源耗尽,使服务崩溃;
- 权限提升:利用反序列化操作突破程序权限控制,执行高权限操作。
五、防御
反序列化漏洞防御的核心是限制反序列化的输入来源和内容,具体措施如下:
- 严格校验输入:仅接收可信来源的序列化数据(如内部服务间通信),拒绝外部不可信输入;
- 禁用危险序列化机制:避免使用原生危险序列化(如 Java 的
Serializable、PHP 的unserialize()、Python 的pickle),改用安全格式(如 JSON、XML,需注意解析器安全); - 限制反序列化类范围:通过白名单机制,仅允许反序列化可信类(如 Java 中自定义
ObjectInputStream,过滤危险类); - 加密与签名:对序列化数据进行加密或数字签名,确保数据未被篡改(如用 HMAC 验证数据完整性);
- 隔离反序列化操作:在沙箱环境中执行反序列化(如独立进程、低权限用户),即使被攻击也不会影响主程序;
- 及时更新依赖:修复第三方库的已知反序列化漏洞(如升级
Apache Commons Collections至安全版本); - 避免在魔术方法 / 回调中执行危险操作:如 PHP 的
__destruct()、Java 的readObject()中不调用系统命令、文件操作等。
六、实战
靶机pikachu之反序列化
源代码为定义了一个类,属性test的值为pikachu
定义_construct()函数,输出test的值,在对象创建时调用
class S{
var $test = "pikachu";
function __construct(){
echo $this->test;
}
}
$html='';
if(isset($_POST['o'])){
$s = $_POST['o'];
if(!@$unser = unserialize($s)){
$html.="<p>大兄弟,来点劲爆点儿的!</p>";
}else{
$html.="<p>{$unser->test}</p>";
}
}
输入一串序列化字符串
O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}
反序列化后创建了一个test对象,同时调用_construct()函数,输出test变量的值,即执行脚本<script>alert('xss')</script>
更多推荐

所有评论(0)