【代码审计】某CMS-sql注入漏洞审计过程
字数 1302 2025-08-09 22:00:43

某CMS SQL注入漏洞审计过程详解

1. 漏洞背景

本文档详细分析某CMS系统中存在的一个SQL注入漏洞的审计过程,通过完整的代码审计流程展示如何发现、分析和验证该漏洞。

2. 审计环境准备

  1. 获取目标CMS源码
  2. 本地搭建测试环境
  3. 进入后台寻找可能存在漏洞的功能模块

3. 漏洞发现过程

3.1 功能点定位

在后台功能中发现一个SQL语句输入框,初步测试发现存在输入过滤:

  • 输入测试内容后返回"非法操作"错误
  • 通过报错信息在源码中搜索关键词"非法操作"

3.2 代码定位

通过搜索发现相关代码位于同一PHP文件中,关键参数包括:

  • title
  • limits
  • orders
  • isall
  • sqls(对应SQL输入框)

通过抓包确认参数传递:

  • 在功能块点击保存并抓包
  • 确认请求中包含上述参数,特别是sqls参数

4. 代码审计分析

4.1 关键过滤函数分析

系统使用frparam函数处理参数,函数调用形式:

frparam('go', 1)

frparam函数定义分析:

  1. 获取URL参数值
  2. 将前端所有数据赋值给$data
  3. 检查参数是否存在
  4. 最终调用format_param($value,$int,$default)进行格式化

4.2 参数过滤机制

format_param函数分析:

  • 根据$int值进行不同处理
  • $int=1时调用SafeFilter函数进行过滤

SafeFilter函数分析:

  1. 过滤XSS攻击
    • 使用preg_replace移除危险字符
    • 过滤基本JS语句
  2. 对输入值进行HTML实体编码
  3. PHP版本判断:
    • ≥7.4版本:使用addslashes转义双引号
    • 其他版本:检查魔术引号设置,未开启则使用addslashes

4.3 SQL语句过滤机制

sqls参数的特殊过滤:

if(stripos($sqls,'update')!==false || stripos($sqls,'delete')!==false 
   || stripos($sqls,'insert')!==false || stripos($sqls,'drop')!==false 
   || stripos($sqls,'truncate')!==false){
    // 抛出"非法操作"错误
}

过滤特点:

  • 使用stripos查找危险SQL关键字
  • 禁止的关键字包括:update、delete、insert、drop、truncate
  • 只要包含任一关键字即报错

4.4 漏洞点分析

漏洞成因:

  1. 虽然对危险SQL关键字进行了过滤
  2. 但未对SELECT语句进行限制
  3. 过滤后的SQL语句直接带入执行

执行流程:

  1. 绕过关键字检测(不使用被过滤的关键字)
  2. 构造合法SQL语句
  3. 系统直接执行该语句

5. 漏洞验证方法

5.1 构造Payload要点

  1. 避免使用被过滤的关键字:
    • update、delete、insert、drop、truncate
  2. 可使用SELECT语句进行注入
  3. 利用系统未过滤的其他SQL功能

5.2 自动化验证

可使用sqlmap工具进行自动化验证:

  1. 定位存在漏洞的参数
  2. 构造绕过过滤的Payload
  3. 进行注入测试

6. 漏洞修复建议

  1. 完善SQL关键字过滤列表,增加SELECT等关键字检测
  2. 使用预处理语句(PDO或mysqli预处理)
  3. 实施最小权限原则,限制数据库账户权限
  4. 增加输入内容白名单验证
  5. 对输出进行适当编码

7. 审计经验总结

  1. 通过报错信息定位关键代码
  2. 分析自定义过滤函数的行为
  3. 关注过滤机制的完整性
  4. 注意过滤规则的绕过可能性
  5. 验证过滤后的语句执行方式

8. 附录:关键代码片段

// 参数获取函数
function frparam($str, $int=0, $default=''){
    $data = $this->_data;
    if(empty($str) || !array_key_exists($str,$data)){
        return $default;
    }
    $method = isset($this->_method) ? $this->_method : '';
    $value = $data[$str];
    return format_param($value,$int,$default);
}

// SQL语句过滤检测
if(stripos($sqls,'update')!==false || stripos($sqls,'delete')!==false 
   || stripos($sqls,'insert')!==false || stripos($sqls,'drop')!==false 
   || stripos($sqls,'truncate')!==false){
    // 抛出"非法操作"错误
}
某CMS SQL注入漏洞审计过程详解 1. 漏洞背景 本文档详细分析某CMS系统中存在的一个SQL注入漏洞的审计过程,通过完整的代码审计流程展示如何发现、分析和验证该漏洞。 2. 审计环境准备 获取目标CMS源码 本地搭建测试环境 进入后台寻找可能存在漏洞的功能模块 3. 漏洞发现过程 3.1 功能点定位 在后台功能中发现一个SQL语句输入框,初步测试发现存在输入过滤: 输入测试内容后返回"非法操作"错误 通过报错信息在源码中搜索关键词"非法操作" 3.2 代码定位 通过搜索发现相关代码位于同一PHP文件中,关键参数包括: title limits orders isall sqls (对应SQL输入框) 通过抓包确认参数传递: 在功能块点击保存并抓包 确认请求中包含上述参数,特别是 sqls 参数 4. 代码审计分析 4.1 关键过滤函数分析 系统使用 frparam 函数处理参数,函数调用形式: frparam 函数定义分析: 获取URL参数值 将前端所有数据赋值给 $data 检查参数是否存在 最终调用 format_param($value,$int,$default) 进行格式化 4.2 参数过滤机制 format_param 函数分析: 根据 $int 值进行不同处理 当 $int=1 时调用 SafeFilter 函数进行过滤 SafeFilter 函数分析: 过滤XSS攻击 使用 preg_replace 移除危险字符 过滤基本JS语句 对输入值进行HTML实体编码 PHP版本判断: ≥7.4版本:使用 addslashes 转义双引号 其他版本:检查魔术引号设置,未开启则使用 addslashes 4.3 SQL语句过滤机制 对 sqls 参数的特殊过滤: 过滤特点: 使用 stripos 查找危险SQL关键字 禁止的关键字包括:update、delete、insert、drop、truncate 只要包含任一关键字即报错 4.4 漏洞点分析 漏洞成因: 虽然对危险SQL关键字进行了过滤 但未对SELECT语句进行限制 过滤后的SQL语句直接带入执行 执行流程: 绕过关键字检测(不使用被过滤的关键字) 构造合法SQL语句 系统直接执行该语句 5. 漏洞验证方法 5.1 构造Payload要点 避免使用被过滤的关键字: update、delete、insert、drop、truncate 可使用SELECT语句进行注入 利用系统未过滤的其他SQL功能 5.2 自动化验证 可使用sqlmap工具进行自动化验证: 定位存在漏洞的参数 构造绕过过滤的Payload 进行注入测试 6. 漏洞修复建议 完善SQL关键字过滤列表,增加SELECT等关键字检测 使用预处理语句(PDO或mysqli预处理) 实施最小权限原则,限制数据库账户权限 增加输入内容白名单验证 对输出进行适当编码 7. 审计经验总结 通过报错信息定位关键代码 分析自定义过滤函数的行为 关注过滤机制的完整性 注意过滤规则的绕过可能性 验证过滤后的语句执行方式 8. 附录:关键代码片段