ThinkPHP5漏洞分析之SQL注入(四)
字数 1369 2025-08-18 11:38:45
ThinkPHP5 SQL注入漏洞分析(select方法注入)
漏洞概述
本漏洞存在于ThinkPHP 5.0.10版本中,是一个SQL注入漏洞,主要涉及Mysql类的parseWhereItem方法和Request类的filterValue方法。由于程序未对数据进行充分过滤,直接将用户输入拼接进SQL语句,同时漏过滤NOT LIKE关键字,导致攻击者可以构造恶意输入实现SQL注入。
影响版本
ThinkPHP = 5.0.10
漏洞环境搭建
- 创建测试项目:
composer create-project --prefer-dist topthink/think=5.0.10 tpdemo
- 修改composer.json:
"require": {
"php": ">=5.4.0",
"topthink/framework": "5.0.10"
}
- 执行更新:
composer update
- 设置控制器代码(application/index/controller/Index.php):
<?php
namespace app\index\controller;
class Index
{
public function index()
{
$username = request()->get('username/a');
$result = db('users')->where(['username' => $username])->select();
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');
漏洞复现
访问以下URL触发漏洞:
http://localhost:8000/index/index/index?username[0]=not like&username[1][0]=%%&username[1][1]=233&username[2]=) union select 1,user()#
注意:需要开启app_debug才能看到SQL报错信息。
漏洞分析
漏洞触发流程
- 用户输入通过Request类的input方法处理
- 数据经过filterValue方法过滤,但该方法漏过滤了NOT LIKE关键字
- 程序调用Query类的where方法,通过parseWhereExp分析查询表达式
- 调用select方法构建select语句
- 使用Builder类的select方法填充SQL模板
- 用户可控数据被传入buildWhere函数
- 数据最终进入parseWhereItem方法处理
关键代码分析
-
filterValue方法缺陷:
- 位于Request.php
- 负责过滤表单中的表达式
- 漏过滤了NOT LIKE关键字
-
parseWhereItem方法漏洞:
- 位于Mysql类中
- 当操作符等于NOT LIKE时,MYSQL逻辑操作符可由用户输入控制
- 攻击者可构造恶意输入拼接SQL语句
-
版本差异:
- 5.0.10之前版本:默认允许的表达式中不存在"not like"(带空格),无法触发漏洞
- 5.0.10版本:默认允许的表达式中存在"not like",可以触发漏洞
漏洞修复
官方在5.0.11版本中修复了此漏洞,修复方法为:
- 在Request.php文件的filterValue方法中,添加对NOT LIKE关键字的过滤
攻击流程图解
- 用户提交恶意参数 → Request类处理 → filterValue漏过滤NOT LIKE
- Query类处理where条件 → parseWhereExp分析表达式
- Builder类构建SQL → buildWhere处理条件
- parseWhereItem处理单元条件 → 用户控制操作符 → SQL注入完成
防御建议
- 升级到ThinkPHP 5.0.11或更高版本
- 对所有用户输入进行严格过滤和转义
- 使用参数化查询而非字符串拼接
- 生产环境关闭调试模式(app_debug设为false)
- 最小化数据库操作权限
技术总结
该漏洞的核心在于:
- 程序未充分过滤用户输入(NOT LIKE关键字)
- SQL语句构建过程中直接拼接用户可控数据
- 特定版本中默认允许的表达式包含可被利用的关键字
通过精心构造的数组参数,攻击者可以控制SQL查询的逻辑操作符,最终实现SQL注入攻击。