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

漏洞环境搭建

  1. 创建测试项目:
composer create-project --prefer-dist topthink/think=5.0.10 tpdemo
  1. 修改composer.json:
"require": {
    "php": ">=5.4.0",
    "topthink/framework": "5.0.10"
}
  1. 执行更新:
composer update
  1. 设置控制器代码(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);
    }
}
  1. 配置数据库(config/database.php)并开启调试模式(config/app.php中设置app_debug和app_trace为true)

  2. 创建测试数据库:

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报错信息。

漏洞分析

漏洞触发流程

  1. 用户输入通过Request类的input方法处理
  2. 数据经过filterValue方法过滤,但该方法漏过滤了NOT LIKE关键字
  3. 程序调用Query类的where方法,通过parseWhereExp分析查询表达式
  4. 调用select方法构建select语句
  5. 使用Builder类的select方法填充SQL模板
  6. 用户可控数据被传入buildWhere函数
  7. 数据最终进入parseWhereItem方法处理

关键代码分析

  1. filterValue方法缺陷

    • 位于Request.php
    • 负责过滤表单中的表达式
    • 漏过滤了NOT LIKE关键字
  2. parseWhereItem方法漏洞

    • 位于Mysql类中
    • 当操作符等于NOT LIKE时,MYSQL逻辑操作符可由用户输入控制
    • 攻击者可构造恶意输入拼接SQL语句
  3. 版本差异

    • 5.0.10之前版本:默认允许的表达式中不存在"not like"(带空格),无法触发漏洞
    • 5.0.10版本:默认允许的表达式中存在"not like",可以触发漏洞

漏洞修复

官方在5.0.11版本中修复了此漏洞,修复方法为:

  • 在Request.php文件的filterValue方法中,添加对NOT LIKE关键字的过滤

攻击流程图解

  1. 用户提交恶意参数 → Request类处理 → filterValue漏过滤NOT LIKE
  2. Query类处理where条件 → parseWhereExp分析表达式
  3. Builder类构建SQL → buildWhere处理条件
  4. parseWhereItem处理单元条件 → 用户控制操作符 → SQL注入完成

防御建议

  1. 升级到ThinkPHP 5.0.11或更高版本
  2. 对所有用户输入进行严格过滤和转义
  3. 使用参数化查询而非字符串拼接
  4. 生产环境关闭调试模式(app_debug设为false)
  5. 最小化数据库操作权限

技术总结

该漏洞的核心在于:

  1. 程序未充分过滤用户输入(NOT LIKE关键字)
  2. SQL语句构建过程中直接拼接用户可控数据
  3. 特定版本中默认允许的表达式包含可被利用的关键字

通过精心构造的数组参数,攻击者可以控制SQL查询的逻辑操作符,最终实现SQL注入攻击。

ThinkPHP5 SQL注入漏洞分析(select方法注入) 漏洞概述 本漏洞存在于ThinkPHP 5.0.10版本中,是一个SQL注入漏洞,主要涉及Mysql类的parseWhereItem方法和Request类的filterValue方法。由于程序未对数据进行充分过滤,直接将用户输入拼接进SQL语句,同时漏过滤NOT LIKE关键字,导致攻击者可以构造恶意输入实现SQL注入。 影响版本 ThinkPHP = 5.0.10 漏洞环境搭建 创建测试项目: 修改composer.json: 执行更新: 设置控制器代码(application/index/controller/Index.php): 配置数据库(config/database.php)并开启调试模式(config/app.php中设置app_ debug和app_ trace为true) 创建测试数据库: 漏洞复现 访问以下URL触发漏洞: 注意:需要开启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注入攻击。