freeBuf
thinkphp3.2.3 系列sql注入分析
2021-12-07 10:16:32
所属地 辽宁省

where注入

复现

搭建环境


通过id可以查询数据

注入payload
?id[where]=3%20and%201=updatexml(1,concat(0x7,(select%20name%20from%20users%20limit%201),0x7e),1)#

漏洞分析

从find函数入手,跟进
如果是数字或字符串,就会把它变为数组形式
例如id=1,变为where=>[id=>1]
如果不是数字或字符串
例如id[where]=3%20and%201=updatexml(1,concat(0x7,user(),0x7e),1)#,则变为,where=>3%20and%201=updatexml(1,concat(0x7,user(),0x7e),1)#

继续跟进
$this->db->select
$this->buildSelectSql
$this->parseSql

$this->selectSql是查询模板'SELECT%DISTINCT% %FIELD% FROM %TABLE%%FORCE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%%LOCK%%COMMENT%'
parseSql是直接对模板进行替换
SELECT * FROM usersWHERE 3 and 1=updatexml(1,concat(0x7,(select name from users limit 1),0x7e),1)# LIMIT 1

这里的parseWhere
如果where是字符串,则直接返回,如果不是,则继续向下,解析数组

所以,如果传入参数是id=1,在find中,转化为where=>[id=>1],在parseWhere中,转化为where id = 1

如果传入参数是id[where]=3 and 1=updatexml(1,concat(0x7,user(),0x7e),1)#,在find中,转化为where=>3 and 1=updatexml(1,concat(0x7,user(),0x7e),1)#
在parseWhere中,转化为where 3 and 1=updatexml(1,concat(0x7,user(),0x7e),1)#

最后拼接到sql语句中,造成sql注入

总结

还是thinkphp老毛病,没对用户输入做过滤,用户数据对sql语句的形成造成了影响

orderby注入

复现

payload

http://tptest.cc/index.php/home/index/test2
?order[updatexml(1,concat(0x3a,user()),1)]=2
&XDEBUG_SESSION_START=17221


复现失败
原因是这里多个2

去掉2就可以了

和网上同样的版本,同样的payload,不知道为什么多个2
没事,调试看看

漏洞分析

跟踪调试
和where注入同理,,直接对order替换,造成注入

为什么我的payload运行时会多出个2呢?
这里将key和value拼接,造成的

那我把2去掉,使value值为空就好了

总结

和where注入同理,几乎一模一样

bind注入

复现

环境搭建


payload

?name=admin
&age=1
&id[]=bind
&id[]=1 and updatexml(1,concat(0x7,(select user()),0x7e),1)

漏洞分析

先看参数
id变为了数组,元素分别是bind1 and updatexml(1,concat(0x7,(select user()),0x7e),1)
先进入where看一下
,,,什么都没做
再进save看一下

跟进update

遇到了parseWhere
然后进入了parseWhereItem

bind是thinkphp自定义的一种运算符
将key和var[1]拼接,拼接结果就是`id` = :1 and updatexml(1,concat(0x7,(select user()),0x7e),1)

总结

thinkphp的注入系列都差不多,
因为没有对用户输入进行限制,导致用户输入使用thinkphp自定义的运算符,对sql语句进行构造

本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
文章目录