配置
通过以下命令获取测试环境代码:
1 | composer create-project --prefer-dist topthink/think=5.0.10 tpdemo |
将 composer.json 文件的 require 字段设置成如下:
1 | "require": { |
然后执行 composer update
,并将 application/index/controller/Index.php 文件代码设置如下:
1 |
|
在 config/database.php 文件中配置数据库相关信息,并开启 config/app.php 中的 app_debug 和 app_trace 。创建数据库信息如下:
1 | create database tpdemo; |
漏洞简介
由于parseWhereItem
方法中,对$whereStr
直接进行的sql语句的拼接,造成了sql注入
payload
1 | http://localhost/index.php/index/index?username=)='1' union select updatexml(1,concat(0x7,user(),0x7e),1 |
漏洞分析
首先进行参数的传入,然后先进入where
方法Query.php
的where
的parseWhereExp
会分析查询表达式,并使得$option具有如下值
然后进入thinkphp/library/think/db/Query.php
的select
方法调用
这里的builder
是thinkphp/library/think/db/Builder.php
的Builder
类,Builder
的select
方法用于拼接sql语句
上面代码用于对sql语句模板进行变量填充,问题出现在parseWhere
方法中,即对%WHERE%
进行填充出现问题,继续跟进parseWhere
方法又调用了parseWhereItem
子方法进行SQL语句拼接,跟进
在此处又将值带入parseWhereItem
拼接
由于$key
值是EXP
,进入该分支,将sql语句拼接成我们构造的sql语句,最终造成sql注入
总结
修复
由于官方不认为这是个漏洞,因此存在于整个TP5中