配置
通过以下命令获取测试环境代码:
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中