参考学习连接
- https://github.com/Mochazz/ThinkPHP-Vuln/blob/master/ThinkPHP5/ThinkPHP5%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90%E4%B9%8BSQL%E6%B3%A8%E5%85%A52.md
漏洞简介
thinkphp/library/think/db/builder/Mysql.php
中的parseArrayData没有对传入的数据进行过滤,导致可拼接sql语句,造成sql注入
配置
1 | github上没有5.1.7了所以下的5.1.8 |
payload
1 | http://localhost/index.php/index/index?username[0]=point&username[1]=1&username[2]=updatexml(1,concat(0x7,user(),0x7e),1)^&username[3]=0 |
漏洞分析
这个漏洞前半部分跟5.0.13-5.0.15
,5.1.0-5.1.5
的sql注入差不多,简单点理解,有问题的方法出现在parseArrayData
首先传入username数组,用$username
接收,然后进入到Query类的update
方法
这个where方法就是获取一些连接数据库的选项,没什么好说的,下面进入thinkphp/library/think/db/Connection.php
的update
方法
关键部分依旧在Builder
的update
方法,我们传入的数组此时在$this->options[‘data’]里面,跟进update
方法
数据在$query
的options['data']
里面,调用了parseData
方法,主要部分是下面的switch语句
val[0]就是我们传入的username[0],值为point,进入default分支,跟进parseArrayData方法
list函数用于把数组中的值赋给一组变量,此处type是point
,value是1
,进入switch的point分支,fun为updatexml(1,concat(0x7,user(),0x7e),1)^
,point为0
,通过result拼接为如下
层层返回,最终在thinkphp/library/think/db/Connection.php
的execute方法处执行
总结图
修复方法
官方直接删除函数,从根上解决问题