Thinkphp3.2 任意文件删除Pop链

Thinkphp3.2 在查找反序列化链时发现其存在一条任意文件删除的反序列化链

0x01 发现过程

搜索全局__destruct 魔术方法,发现在文件ThinkPHP\Library\Vendor\Smarty\sysplugins\smarty_internal_template.php 675

可以看出是Thinkphp第三方扩展Smarty 模板引擎的类文件

1
2
3
4
5
6
public function __destruct()
{
if ($this->smarty->cache_locking && isset($this->cached) && $this->cached->is_locked) {
$this->cached->handler->releaseLock($this->smarty, $this->cached);
}
}

其中$this->cached->handler->releaseLock($this->smarty, $this->cached); 发现可以调用任意类的releaseLock方法,查找全局releaseLock 方法 在路径ThinkPHP\Library\Vendor\Smarty\sysplugins\smarty_internal_cacheresource_file.php 257 行

1
2
3
4
public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached){
$cached->is_locked = false;
@unlink($cached->lock_id);
}

可以看到进行了unlink操作,$cached 需要为Smarty_Template_Cached 类 其中的lock_id我们可控

__destruct中我们看到要进入该分支需要满足$this->smarty->cache_locking && isset($this->cached) && $this->cached->is_locked 这些条件我们都可控

cache_locking属性在类Smarty中 所以$this->smarty 需赋值为类Smarty 并修改cache_locking为true

is_locked 存在类Smarty_Template_Cached 中 所以$this->cached 需要赋值为Smarty_Template_Cached类

进入该分支后 需要访问Smarty_Internal_Cacheresource_File 类的releaseLock方法 则修改Smarty_Template_Cached中的handler属性的值为Smarty_Internal_Cacheresource_File

删除的文件为$cached(Smarty_Template_Cached)中的lock_id属性 修改该对象的lock_id属性的值即可

构造Poc

略。。。

触发位置,直接在控制器里面进行反序列化是无法触发的,需要在模板文件中对传入的值进行反序列化

利用过程 在Application目录下的Home目录下的Conf目录中配置config.php 文件的值为

1
2
3
4
5
<?php
return array(
'TMPL_ENGINE_TYPE'=>'Smarty'//意思为使用Smarty作为模板引擎
//'配置项'=>'配置值'
);

Index控制器中写如下代码

1
2
3
4
5
6
7
8
9
10
11
<?php
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller {
public function index(){
$a = $_GET['code'];

$this->assign('a',$a);
$this->display();
}
}

在Home的View模板文件目录创建index目录编写一个index.html

1
{{unserialize(base64_decode($a))}}

在根目录建一个1.txt文件

传入序列化后的恶意对象

1.txt 成功被删除