某CMS sql注入梅开二度
字数 1548 2025-08-06 08:34:57
某CMS SQL注入漏洞分析与利用教学
漏洞概述
本教学文档详细分析某开源CMS中存在的SQL注入漏洞,该漏洞允许攻击者通过精心构造的请求执行任意SQL语句。漏洞存在于API接口中,涉及多个功能点,可导致数据库信息泄露甚至服务器被控制。
漏洞复现
基础Payload
POST /api.php?c=call&f=index HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 67
data={"m_picplayer":{"_alias":"abc","fields_need":"CASE 1 WHEN (substr((select database()) from 1 for 1)=0x70) THEN sleep(5) ELSE 1 END"}}
关键点说明
- 请求路径为
/api.php?c=call&f=index - 通过POST请求的
data参数传递JSON格式的注入payload - 利用
fields_need参数构造时间盲注条件
路由分析
- 系统有三个入口(前端、接口、后台)都从
framework/_init_phpok.php执行初始化 - 以
action_api为例:$ctrl和$func分别通过GET请求中的c和f获取- 默认值为
index
- 在
_action_phpok4中调用相关控制器和方法- 例如访问
http://127.0.0.1/api.php?c=call&f=index会调用framework\api\call_control.php中的index_f方法
- 例如访问
漏洞分析
主要漏洞点分析
-
framework/api/call_control.php中的index_f方法:- 判断传入值是否以
{开头,如果是则转换为JSON格式 - 通过
$this->model('call')->all($this->site['id'],'identifier')获取站点下全部数据并格式化 - 在
all()方法中获取数据库内容,并将ext字段数据反序列化
- 判断传入值是否以
-
数据流跟踪:
- 遍历
data中的数据 - 检查
$call_all[$key]['is_api']为真 - 将
data中的键和值传递给framework/phpok_tpl_helper.php中的phpok方法 - 继续调用
framework/phpok_call.php中的phpok方法
- 遍历
-
SQL注入点:
- 在
_arclist方法中调用_arc_condition方法 - 检查
fields_need参数存在时,通过,分割并直接拼接到SQL语句 $condition参数传入arc_count方法并执行
- 在
第二个漏洞点分析
-
发现
_catelist方法中存在另一个注入点:- 未对
$rs['cateid']进行过滤 - 直接拼接到SQL语句的
orderby后执行
- 未对
-
利用Payload:
data={
"catelist":{
"_alias":"abc",
"orderby":"if(2=1,1,sleep(0.5))"
}
}
注意:实际延迟时间与查询数据条数成倍数关系,不是精确的sleep时间。
漏洞利用技巧
-
缓存机制绕过:
- 系统默认开启缓存,相同请求会直接返回缓存
- 每次构建payload时需要改变数据以确保不被缓存
-
时间盲注技巧:
- 使用
CASE WHEN ... THEN sleep() ELSE ... END结构 - 使用
if(condition, true_value, false_value)结构
- 使用
-
十六进制编码:
- 使用
0x前缀绕过某些过滤 - 例如
0x70表示字母'p'
- 使用
修复方案
官方修复方式:
- 将传入的
data值转换为JSON格式后使用safe_text方法过滤 - 在
safe_text中新增对(,),0x等特殊字符的过滤
防御建议
- 对所有用户输入进行严格过滤和转义
- 使用参数化查询或预处理语句
- 最小权限原则,数据库连接使用最低必要权限
- 对关键操作添加日志记录
- 及时更新到最新版本
总结
该CMS的SQL注入漏洞源于对用户输入缺乏充分过滤,特别是在动态调用数据库方法时未进行严格检查。攻击者可以利用此漏洞获取数据库敏感信息,甚至控制服务器。开发人员应重视输入验证和安全编码实践,避免此类漏洞的产生。