Thinphp3.2.3--Sql注入复现

前言

学习了Yii框架,接下来进入TP的世界。

复现

环境

官方源码下载https://www.thinkphp.cn/donate/download/id/610.html

ThinkPHP/Conf/convention.php配置数据库即可.

image-20211203094733738

连接数据库

image-20211203094758620

image-20211203092113564

配置控制器 Application/Home/Controller/IndexController.class.php

image-20211203092408312

在这里需要了解tp3的内置方法

A 快速实例化Action类库
B 执行行为类
C 配置参数存取方法
D 快速实例化Model类库
F 快速简单文本数据存取方法
L 语言参数存取方法
M 快速高性能实例化模型
R 快速远程调用Action类方法
S 快速缓存存取方法
U URL动态生成和重定向方法
W 快速Widget输出方法

比如:
//使用M方法实例化
$User = M('User');
//和用法$User = new \Think\Model ('User');等效

echo I('get.id'); // 相当于 $_GET['id']
echo I('get.name'); // 相当于 $_GET['name']
// 采用htmlspecialchars方法对$_GET['name'] 进行过滤,如果不存在则返回空字符串
echo I('get.name','','htmlspecialchars');

注入分析:

image-20211203101425184

先看看正常查询的过程

image-20211203153924715

给options赋array(),继续跟进

image-20211203154013233

重点在这里,正常会进入这个判断

image-20211203154240662

继续跟进

image-20211203154353210

应为这里id是varcahr,都不匹配,直接跳出。进行查询

image-20211203154643872

查询成功,返回即可

试试 1',仍然回显正常,可能存在过滤。跟进一下

先看 I函数

elseif(isset($input[$name])) { // 取值操作
        $data       =   $input[$name];
        $filters    =   isset($filter)?$filter:C('DEFAULT_FILTER');
  //$filter的默认方法是DEFAULT_FILTER,也就是htmlspecialchars
        if($filters) {
            if(is_string($filters)){
                $filters    =   explode(',',$filters);
            }elseif(is_int($filters)){
                $filters    =   array($filters);
            }
            
            foreach($filters as $filter){
                if(function_exists($filter)) {
                    $data   =   is_array($data) ? array_map_recursive($filter,$data) : $filter($data); // 参数过滤
                  

htmlspecialchars函数过滤后,值仍然不变

返回data,回到find函数,发现新的函数

image-20211203143302851

此时的id没有变化,跟进函数,成功进入了这个if条件

image-20211203143813879

此时

image-20211203144116001

继续跟进 __parseType函数

image-20211203144231189

可以看到这是数据检测的功能,由于 id的类型是 varchar,所以直接跳出了循环

继续回到了find()函数,此时id的值仍然没有变

image-20211203153447422

进入select语句中,

image-20211204163447669

我们这里是 options['where'],所以根据 parseWhere,进入了parseValue

image-20211204165208492

跟进

this->escapeString($value) : '\''.$this->escapeString($value).'\'';
# id=1'  ---> id='1\''

image-20211204165444086

发现最终的sql语句为

SELECT * FROM `users` WHERE `id` = '1\'' LIMIT 1  
#查询失败

所以常规注入是不行。。

数组绕过

payload:?id[where]=1

这样会直接绕过这个if判断语句。即对id的类型不做判断,inval函数无法执行

image-20211203143813879

这里直接赋值,不会进入else数组表达式

image-20211204170535729

也就是 where 1

image-20211204170636224

发现sql语句

"SELECT * FROM `users` WHERE 1 LIMIT 1  "
# 注入成功

两种方法的区别

$options=array(
'where'=>array(
'id'=>'1'
)
);
现在是
$options=array(
'where'=>'1'
);

tp32---blind注入

复现环境

index控制器中输入:

        $User = M("Users");
        $user['id'] = I('id');
        $data['tp'] = I('tp');
        $value = $User->where($user)->save($data);
        var_dump($value);

漏洞复现

传输 id[0]=bind&id[1]=aa

跟进 M方法

image-20211206105125706

正常返回了 数据库信息 $_model[$guid],继续跟进 I方法,读取到get参数

image-20211206105953674

tp参数也一样

然后跟进 save函数,此函数将 tp=“1”变成了 tp=1

image-20211206112205945

又进入了 parseOptions

image-20211206112319877

跟进

image-20211206112355032

可以看到,使用 array_mergethis->options赋给了options,然后返回值仍然是

image-20211206113103798

继续跟进,发现 update,跟进

image-20211206113201483

image-20211206113850841

函数array_walk:对数组中的每个元素应用用户自定义函数:

implode:数组连成字符串

跟进 parseSet函数

image-20211206114359198

is_scalar() 函数用于检测变量是否是一个标量。

标量变量是指那些包含了 integer、float、string 或 boolean 的变量,而 array、object 和 resource 则不是标量。

trim() 函数移除字符串两侧的空白字符或其他预定义字符。

跟进parseKey,只是对 key,也就是 tp过滤,并且添加反引号,继续跟进 bindParam

image-20211206115023526

此时的sql语句

image-20211206115245284

继续跟进,进入了 parseWhere,也就是拼接where后的语句

image-20211206134712277

跟进

image-20211206134909931

parseWhereItem发现注入点

image-20211206135115066

构造sql语句

image-20211206135359444

最后,进入excute()函数

image-20211206135836134

strtr() 函数转换字符串中特定的字符。

array_map() 函数将用户自定义函数作用到数组中的每个值上,并返回

可以看到前后sql语句变化,将 :0替换成 '1'

image-20211206141043591

Payload:

?id[0]=bind&id[1]=0%20and%20updatexml(1,concat(0x7e,user(),0x7e),1)&tp=1

image-20211206141732870

posted @ 2022-02-06 17:32  kzd的前沿思考  阅读(84)  评论(0编辑  收藏  举报