初学代码审计之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()- 执行原始SQLgetlist()- 获取列表数据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类)
漏洞代码:
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)#
验证过程:
- 使用Burpsuite发送请求
- 观察到延时响应(5秒)
- 确认存在三次注入执行(共延时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. 手工验证步骤
- 使用Burpsuite拦截请求
- 修改相关参数(id、where等)
- 注入延时语句观察响应时间
- 使用注释符
#或%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数据库
六、漏洞修复建议
-
参数化查询:
- 使用预处理语句替代字符串拼接
- 示例:
$stmt = $conn->prepare("SELECT * FROM users WHERE id = ?"); $stmt->bind_param("i", $id); $stmt->execute();
-
严格输入过滤:
- 对所有用户输入应用
safeword()过滤 - 提高默认安全等级到最高级
- 对所有用户输入应用
-
白名单验证:
- 对ID等参数进行数字验证
- 示例:
if (!is_numeric($id)) { die("Invalid input"); }
-
最小权限原则:
- 数据库连接使用最小必要权限
- 避免使用root或高权限账户
-
错误处理:
- 禁用错误信息直接显示
- 使用自定义错误页面
七、总结与经验
-
核心模块审计重要性:
- 基础数据库操作类漏洞会影响整个系统
- 一个漏洞点可能衍生出多个实际注入点
-
过滤机制缺陷:
- 部分过滤不等于安全
- 需要统一的安全处理策略
-
注入类型多样性:
- 数字型注入
- 字符型注入
- 时间盲注
- 布尔盲注
-
开发建议:
- 使用ORM框架
- 建立统一的安全编码规范
- 定期进行代码审计
通过本次审计,我们深入理解了SQL注入的产生原理和利用方式,强调了安全编码在Web开发中的重要性。开发者应当重视所有用户输入的过滤和验证,避免直接拼接SQL语句,从根本上杜绝此类漏洞。