本文内容仅供安全研究与学习,使用者需严格遵守《网络安全法》等相关法律法规,严禁用于任何非法用途。
一、 项目背景与审计准备
近期,为巩固PHP代码审计技能,笔者选取了一套盲盒交友平台的源码进行实战演练。本文旨在记录并分享在该平台前台发现的一处SQL注入漏洞的完整挖掘流程。
二、 框架与入口分析
首先对项目结构进行观察,如下图所示:

通过目录结构和文件访问方式判断,该项目并未使用主流的MVC框架(如ThinkPHP、Laravel等),而是采用传统的面向过程式开发,PHP文件可直接通过URL访问,路由处理逻辑相对简单。
三、 全局过滤机制分析
在初步审计过程中,笔者发现源码在多数用户参数接收处都设置了统一的过滤函数,核心过滤代码如下:


该过滤函数对‘(单引号)等常见注入字符进行了转义或拦截。这种防护对于字符型(即参数被单引号包裹)的SQL注入有较好的防御效果。因此,需要转变思路,寻找数字型或未被引号包裹的注入点。
受此启发,联想到某些网络安全与渗透测试案例中,常从支付回调、订单查询等接口入手,因为这些地方对参数的处理逻辑可能与常规业务不同。于是,开始重点关注此类文件。
四、 权限鉴别与文件筛选
为了找到可从前台直接访问且无需鉴权的漏洞点,需先分析后台的鉴权逻辑。查看后台入口文件,发现其包含了一个公共的鉴权文件:

跟进该包含文件,其核心鉴权逻辑如下:

逻辑显示,程序通过校验adminToken(由管理员用户名和密码的MD5值构成)来判断会话权限。若校验失败,则跳转到登录页。
由此可推断:所有不包含此鉴权头文件的PHP脚本,理论上均可被前台直接访问。利用工具对源码进行扫描,分离出所有未包含该鉴权文件的脚本,共筛选出32个文件。随后对这32个文件进行逐一人工审计。
五、 漏洞定位与利用
在审计至 pay/notify_url.php 文件时,发现一处可疑的数据库操作:

代码中,$_GET[‘out_trade_no’] 参数被直接拼接进SQL语句,且未被单引号包裹,这正是之前寻找的数字型或“裸参数”注入点。同时,SQL语句的执行依赖于 $trade_status 等于 TRADE_FINISHED 或 TRADE_SUCCESS。
由于该参数未经过上文提到的全局过滤函数处理(过滤主要针对字符型参数),且其值直接进入SQL逻辑,因此构成了一个标准的SQL注入漏洞。

通过构造特定的out_trade_no参数(例如1 or sleep(5)),成功触发了数据库的延时响应,证实了该SQL注入漏洞的存在。至此,完成了对该盲盒交友平台首个前台高危漏洞的挖掘与验证。
|