Thinkphp框架 3.2.x sql注入漏洞

Thinkphp框架 3.2.x sql注入漏洞

前言:

北京时间 2018年8月23号11:25分 星期四,tp团队对于已经停止更新的thinkphp 3系列进行了一处安全更新,经过分析,此次更新修正了由于select(),find(),delete()方法可能会传入数组类型数据产生的多个sql注入隐患。

环境搭建:

程序下载地址:地址 PHPstudy:Apache+php7.1+MySQL 工具:PHPstorm

        首先建立一个数据库名为:thinkphp

        建立一个表名为:user

        添加两个字段:name,pass

       

thinkphp3.2版本和之前的5版本略有不同,它的数据库信息文件是在 这个文件:thinkphp/ThinkPHP/Conf/convention.php 在这里面填上刚才建立的数据库信息:

 

打开thinkphp的调试模式: 在刚才的文件:thinkphp/ThinkPHP/Conf/convention.php 然后修改为true:

 'SHOW_ERROR_MSG' => true, // 显示错误信息

3.2版本的控制器位置和5版本有点区别。文件位置thinkphp/Application/Home/Controller/IndexController.class.php在里面写一个简单的update的例子

<?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller
{
    public function index()
    {
        $tj['name'] = I('name');
        $data['pass'] = '111111';
        $res = M("user")->where($tj)->save($data);


    }
}

I函数和5版本的input助手函数差不多,地址

因为仅仅执行基本的CURD操作,所以用M方法来实例化数据库对象就行了。 实例化模型可以看:地址  

漏洞分析:

这里也是用phpstorm+debug进行动态分析,如有不懂可以去查阅。 我们先在I函数这里下一个断点,看下I函数有没有过滤掉我们的输入。

然后访问我们payload,它会跳到入口文件,我们只要分析的是I函数执行的地方,所以我们直接F8跳到执行I函数地方: 

F7跟进,它会跳到文件:thinkphp/ThinkPHP/Common/functions.php这里。 判断传入的值是用什么方式:

接下来就是对我们传入的值进行过滤:

对我们传入的bind值进行过滤:

然后执行我们的数据库更新的操作:

我们F7继续跟下去,有些影响不大的函数可以直接F8跳过去,到save函数:

执行到update函数我们F7跟进去:

我们继续往下,F7进入parseSet函数,可以看到赋值了一个占位符0给pass,代替我们的密码111111

parseSet函数执行完后,我们继续F7进入parseWhere函数。

我们再往下面的parseWhereItem函数进行分析,这里写到,$exp=$val[0]也就是我们传入的bind

$exp    =   strtolower($val[0])

这里判断如果我们传入的数组[0]为bind就进行拼接:

从拼接这里也能看出我们为什么要把第二个数组构造的时候填0,因为是要对应上面parseSet函数,赋值了一个占位符为0,用来代替上面的密码111111,而接下来就没有这种赋值操作了,所以我们如果填其他值得话执行SQL语句的时候就会报错,到后面我会点出在哪里的。

我们继续,F7进去执行预处理语句的地方:

我们可以看到这里用到了bindValue,绑定一个值到一个参数,也就是把111111密码绑定到:0这里。

继续跟下来,到SQL语句执行报错的地方,可以很清楚看到直接了我们的报错语句updatexml的值: 

我们再往error函数跟,可以看到替换掉占位符的语句:

  1. 如果我们把0换成1会是怎么样的结果呢? 访问payload,注意已经把数组第二个0改成1了。 http://127.0.0.1/thinkphp/index.php?name[0]=bind&name[1]=1 and updatexml(2,concat(0x7e,user()),0)

我们把断点直接断在SQL执行的地方:

F7进去然后F8直接走,走到执行报错的地方,我们就会看到如果为1的话那SQL就无法执行下去了。

漏洞复现:

Payload:http://127.0.0.1/thinkphp/index.php?id[]=bind&id[]=1%27&money[]=1123&user=liao

那么我们将id[1]数组的参数变为0呢?id[]=bind&id[]=0%27&money[]=1123&user=liao

 最终Payload: http://127.0.0.1/thinkphp/index.php?name[0]=bind&name[1]=0 and updatexml(2,concat(0x7e,user()),0)

 修复建议:

 更新最新补丁ht#tps#:/#/githu#b.com/t#op-think/thi#nkphp/commit/7e47e34af72996497c90c20bcfa3b2e1cedd7fa4

猜你喜欢

转载自blog.csdn.net/qq_48985780/article/details/121327708