分析
与上一个漏洞类似,这个也是前端可以传入一个数组变量,如['exp','123','123'],后端根据array[0]来将array[1]和array[2]直接拼接到SQL语句中。
由于TP只是框架,为了保证应用业务正常运行,不能为主应用做过多的安全防御(如转义、去除危险字符等)。
上一个漏洞点存在于处理where语句的parseWhere()处,而这个点则在处理insert和set的data的parseData()处。
本文以insert为例,首先payload如下:
http://127.0.0.1/thinkphp/thinkphp_5.0.15_full/public/index.php/index/index/sqli?username[0]=inc&username[1]=updatexml(1,concat(0x7e,user(),0x7e),1)&username[2]=1
15行,以数组的格式获取$_GET中的username变量,然后作为参数传入insert(),跟进一下
parseExpress在这里主要就是把表名放到$options['table']中,用于后面拼装SQL语句。$data在这里就是['name'=>$_GET['username']]。
到2085行,跟进insert函数,这个函数用来拼接整条SQL语句
首先调用parseData()来解析$data,跟进一下
这里经过101行的foreach,在119行将我们的payload拼接到了$result[$item]中,继续往下看
这里直接返回了$result。回到insert(),在728行将parseData()返回的$data拼接到整条SQL语句中,最后返回完整的SQL语句。
回到最外层的insert()
2094行直接执行了insert()返回的SQL语句。