ThinkPHP 5.0.15中的update注入漏洞

漏洞demo:

    public function inc()
    {
        $username = request()->get('name/a');
        db('user')->insert(['name' => $username]);
        return 'Update success';
    }

首先看TP的数据获取:$username = request()->get('name/a');

 

request(助手函数就是获取thinkphp/library/think/Request.php 的实例,然后调用其get方法:

 

重点跟进input(方法:

 

 

 

 

 

 

 

exp数据这种就是在这里过滤的。

input助手函数干的事:

1.使用默认的过滤器进行过滤

2.过了EXP这种表达式关键字符

3.对数据类型进行强制转化,默认是字符串格式

 

然后接着看操作数据库一块:db('user')->insert(['name' => $username]);

db助手函数:

 

thinkphp/library/think/Db.php 数据库的工厂类:

 

 

return \think\db\connector\Mysql 对象的实例:

 

继承于:thinkphp/library/think/db/Connection.php 类。

然后继续执行 ->name($name); 则会触发thinkphp/library/think/db/Connection.php 类中的 __call 方法:

 

 

 

这里回调的类就是:\think\db\Query 类中的name( 方法:

\think\db\Query 中的__construct( 方法:

 

 

 

builder 属性就是 \think\db\builder\Mysql 类的实例:

 

父类:thinkphp/library/think/db/Builder.php

整个TP的DB类库我们就已经理完了,TP5相对TP3来说代码也更加优化了,代码逐渐组件化,各自的职责也更加明显了,实现了代码分离。

 

下面开始分析漏洞代码:

db('user')->insert(['name' => $username]);

db('user')主要还是进行了name属性的设置,并且return thinkphp/library/think/db/Query 实例。

继续调用了:think/db/Query 类中的 insert( 方法:

 

跟进:$options = $this->parseExpress();

 

将链式操作中设置的$this->options属性进行解析合并。

eg: db('name')->where()->order()->select(); 这种操作。

然后看重点:

$sql = $this->builder->insert($data, $options, $replace);

通过前面的分析,我们已经知道$this->builder 属性就是 \think\db\builder\Mysql 类的实例:

 

 

 

 

 

 

 

因为input数据获取函数并没有过滤inc,dec这两个值,导致可以进入到这里,造成注入。

漏洞exp:

/public/index.php/index/index/inc?name[0]=inc&name[1]=updatexml(1,concat(0x23,user(),0x7e),1)&name[2]=1

网上说的漏洞版本: 5.0.13<=ThinkPHP<=5.0.15 、 5.1.0<=ThinkPHP<=5.1.5 

 

 主要还是为了照顾一个朋友,所以写的细一点,自己也刚好记录一下。

posted @ 2020-03-18 22:08  xiaozhiru  阅读(764)  评论(0编辑  收藏  举报