初学代码审计之taocms
字数 1747 2025-08-29 08:31:54

TaoCMS 代码审计与SQL注入漏洞分析

一、前言

本文档基于对TaoCMS的代码审计过程,重点分析其中存在的SQL注入漏洞。通过详细分析漏洞成因、利用方式及修复建议,帮助开发者理解SQL注入原理并提高代码安全意识。

二、系统架构分析

1. 路由机制

TaoCMS采用基于类和方法的简单路由机制:

// admin.php中的路由处理
if (class_exists($action) && method_exists($action, $ctrl)) {
    // 执行对应类的方法
}
  • action参数对应类名
  • ctrl参数对应方法名

2. 数据库操作类

核心数据库操作类为Dbclass,位于单独文件中,提供以下主要方法:

  • query() - 执行原始SQL
  • getlist() - 获取列表数据
  • get_one() - 获取单条数据
  • add_one() - 添加数据
  • updatelist() - 更新数据
  • delist() - 删除数据
  • getquery() - 通过特定格式字符串执行查询

三、安全过滤机制分析

系统存在安全过滤函数Base::safeword(),但存在以下问题:

  1. 仅在特定安全等级(level=6)时才会进行严格过滤
  2. 过滤内容包括:
    • 敏感字符替换
    • 进制转换
    • 特殊字符处理
  3. 许多数据库操作方法未调用过滤函数

四、SQL注入漏洞分析

1. 漏洞函数列表

审计发现以下方法存在SQL注入风险:

  1. delist()
  2. getquery()
  3. updatelist()
  4. get_one()
  5. getlist()

2. 具体漏洞点分析

(1) delist() 方法注入

位置:Article类、CMS类(继承自Article类)

漏洞代码

function delist($table, $idArray, $wheres = "") {
    if ($wheres == '') {
        $ids = implode(',', $idArray);
        $query = $this->query("DELETE FROM " . $table . " WHERE id in(" . $ids . ")");
    } else {
        $query = $this->query("DELETE FROM " . $table . " WHERE " . $wheres);
    }
    return $query;
}

利用方式

  • 通过id参数注入
  • Payload示例:27) or 1=1#
  • 延时注入Payload:27) or sleep(5)#

验证过程

  1. 使用Burpsuite发送请求
  2. 观察到延时响应(5秒)
  3. 确认存在三次注入执行(共延时15秒)

(2) getlist() 方法注入

位置:多个类中调用

漏洞代码

function getlist($table, $wheres = "1=1", $colums = '*', $limits = '20', $orderbys = "id DESC") {
    $query = $this->query("select " . $colums . " from " . $table . " where " . $wheres . " ORDER BY " . $orderbys . " limit " . $limits);
    // ...
}

利用方式

  • 通过$wheres参数注入
  • Payload示例:2 and sleep(5)%23
  • 注意不能使用or,因为存在短路逻辑

(3) updatelist() 方法注入

位置:Category类

漏洞代码

function updatelist($table, $data, $idArray) {
    // ...
    $ids = implode(',', $idArray);
    $query = $this->query("UPDATE " . $table . " set " . $data . " WHERE id in(" . $ids . ")");
    return $query;
}

利用方式

  • 通过idArray参数注入
  • Payload示例:1) or sleep(4)#

(4) tags参数注入

位置:relations表查询

漏洞代码

$tagdata = $this->db->getlist(TB."relations","name='".$tag."'","id,counts",1);

利用方式

  • 字符型注入,需闭合单引号
  • Payload示例:test' or sleep(2)%23

五、漏洞利用验证

1. 手工验证步骤

  1. 使用Burpsuite拦截请求
  2. 修改相关参数(id、where等)
  3. 注入延时语句观察响应时间
  4. 使用注释符#%23终止SQL语句

2. SQLMap自动化验证

命令示例:

sqlmap -v 3 --level 5 --risk 3 --random-agent --current-user --technique T --dbms mysql -p id

参数说明:

  • -v 3:详细级别3
  • --level 5:测试级别5
  • --risk 3:风险级别3
  • --random-agent:随机User-Agent
  • --current-user:获取当前用户
  • --technique T:使用基于时间的盲注
  • --dbms mysql:指定MySQL数据库

六、漏洞修复建议

  1. 参数化查询

    • 使用预处理语句替代字符串拼接
    • 示例:
      $stmt = $conn->prepare("SELECT * FROM users WHERE id = ?");
      $stmt->bind_param("i", $id);
      $stmt->execute();
      
  2. 严格输入过滤

    • 对所有用户输入应用safeword()过滤
    • 提高默认安全等级到最高级
  3. 白名单验证

    • 对ID等参数进行数字验证
    • 示例:
      if (!is_numeric($id)) {
          die("Invalid input");
      }
      
  4. 最小权限原则

    • 数据库连接使用最小必要权限
    • 避免使用root或高权限账户
  5. 错误处理

    • 禁用错误信息直接显示
    • 使用自定义错误页面

七、总结与经验

  1. 核心模块审计重要性

    • 基础数据库操作类漏洞会影响整个系统
    • 一个漏洞点可能衍生出多个实际注入点
  2. 过滤机制缺陷

    • 部分过滤不等于安全
    • 需要统一的安全处理策略
  3. 注入类型多样性

    • 数字型注入
    • 字符型注入
    • 时间盲注
    • 布尔盲注
  4. 开发建议

    • 使用ORM框架
    • 建立统一的安全编码规范
    • 定期进行代码审计

通过本次审计,我们深入理解了SQL注入的产生原理和利用方式,强调了安全编码在Web开发中的重要性。开发者应当重视所有用户输入的过滤和验证,避免直接拼接SQL语句,从根本上杜绝此类漏洞。

TaoCMS 代码审计与SQL注入漏洞分析 一、前言 本文档基于对TaoCMS的代码审计过程,重点分析其中存在的SQL注入漏洞。通过详细分析漏洞成因、利用方式及修复建议,帮助开发者理解SQL注入原理并提高代码安全意识。 二、系统架构分析 1. 路由机制 TaoCMS采用基于类和方法的简单路由机制: action 参数对应类名 ctrl 参数对应方法名 2. 数据库操作类 核心数据库操作类为 Dbclass ,位于单独文件中,提供以下主要方法: query() - 执行原始SQL getlist() - 获取列表数据 get_one() - 获取单条数据 add_one() - 添加数据 updatelist() - 更新数据 delist() - 删除数据 getquery() - 通过特定格式字符串执行查询 三、安全过滤机制分析 系统存在安全过滤函数 Base::safeword() ,但存在以下问题: 仅在特定安全等级(level=6)时才会进行严格过滤 过滤内容包括: 敏感字符替换 进制转换 特殊字符处理 许多数据库操作方法未调用过滤函数 四、SQL注入漏洞分析 1. 漏洞函数列表 审计发现以下方法存在SQL注入风险: delist() getquery() updatelist() get_one() getlist() 2. 具体漏洞点分析 (1) delist() 方法注入 位置 :Article类、CMS类(继承自Article类) 漏洞代码 : 利用方式 : 通过 id 参数注入 Payload示例: 27) or 1=1# 延时注入Payload: 27) or sleep(5)# 验证过程 : 使用Burpsuite发送请求 观察到延时响应(5秒) 确认存在三次注入执行(共延时15秒) (2) getlist() 方法注入 位置 :多个类中调用 漏洞代码 : 利用方式 : 通过 $wheres 参数注入 Payload示例: 2 and sleep(5)%23 注意不能使用 or ,因为存在短路逻辑 (3) updatelist() 方法注入 位置 :Category类 漏洞代码 : 利用方式 : 通过 idArray 参数注入 Payload示例: 1) or sleep(4)# (4) tags参数注入 位置 :relations表查询 漏洞代码 : 利用方式 : 字符型注入,需闭合单引号 Payload示例: test' or sleep(2)%23 五、漏洞利用验证 1. 手工验证步骤 使用Burpsuite拦截请求 修改相关参数(id、where等) 注入延时语句观察响应时间 使用注释符 # 或 %23 终止SQL语句 2. SQLMap自动化验证 命令示例: 参数说明: -v 3 :详细级别3 --level 5 :测试级别5 --risk 3 :风险级别3 --random-agent :随机User-Agent --current-user :获取当前用户 --technique T :使用基于时间的盲注 --dbms mysql :指定MySQL数据库 六、漏洞修复建议 参数化查询 : 使用预处理语句替代字符串拼接 示例: 严格输入过滤 : 对所有用户输入应用 safeword() 过滤 提高默认安全等级到最高级 白名单验证 : 对ID等参数进行数字验证 示例: 最小权限原则 : 数据库连接使用最小必要权限 避免使用root或高权限账户 错误处理 : 禁用错误信息直接显示 使用自定义错误页面 七、总结与经验 核心模块审计重要性 : 基础数据库操作类漏洞会影响整个系统 一个漏洞点可能衍生出多个实际注入点 过滤机制缺陷 : 部分过滤不等于安全 需要统一的安全处理策略 注入类型多样性 : 数字型注入 字符型注入 时间盲注 布尔盲注 开发建议 : 使用ORM框架 建立统一的安全编码规范 定期进行代码审计 通过本次审计,我们深入理解了SQL注入的产生原理和利用方式,强调了安全编码在Web开发中的重要性。开发者应当重视所有用户输入的过滤和验证,避免直接拼接SQL语句,从根本上杜绝此类漏洞。