thinkphp5文件包含漏洞分析

wind-5940755_1280

thinkphp5文件包含漏洞的源码审计与分析

文件包含漏洞

环境复现

直接官网下载对应版本的源码包,使用docker部署即可。

使用已有开源环境复现:

(1)执行命令 docker pull p0ison/thinkphp:5.0.18

(2)执行命令 docker run -itd -p 80:80 p0ison/thinkphp:5.0.18

(3)访问地址 :http://xx.xx.xx.xx/tp/public

版本影响: 5.0.0<=ThinkPHP5<=5.0.18 、5.1.0<=ThinkPHP<=5.1.10

漏洞利用

启动环境,请求http://x.x.x.x/public/ tp5自带的公共模块

修改application/index/controller/Index.php内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
namespace app\index\controller;
use \think\Controller;
class Index extends Controller
{
public function index()
{
$this->assign($this->request->get());
echo "this is test tp5 readfile vul";
return $this->fetch("index"); //当前的模块/view目录/当前控制器/当前操作 这里我定义了一个index模块
}
}

application/index/目录下新增view文件夹;

view文件夹下新增与模块名同名的文件夹index;

index文件夹下新建文件index.html,内容随意即可;

最后请求http://x.x.x.x/public/index.php/index/index/index?cacheFile=/etc/passwd,成功读取文件

漏洞分析

首先我们新建的类方法中调用模板渲染函数的assign,跟进函数assgin的源码,直接进入\thinkphp\library\think\Controller.php

发现调用view类中的assgin方法,跟进代码,进入\thinkphp\library\think\view.php

分析源码发现这里对模板变量值进行了赋值,并且存入到了数组中;

这里基本没什么问题。赋值完成后,会去调用fetch方法加载模板输出,这里如果没有指定模板名称,就会使用默认的文件作为模板当前模块/默认视图目录/当前控制器(小写)/当前操作(小写).html进行渲染,如果没有默认文件程序就回报错。继续跟进fetch方式,进入\thinkphp\library\think\Controller.php

发现直接调用view类中fetch,直接跟进代码,进入\thinkphp\library\think\view.php

继续跟进代码内容进入\think\view\driver\Think.php

发现代码继续调用template类的fetch方法,跟进代码

我们发现在这里变量$vars直接赋值给$this->data,并且直接被带入到template类中文件引擎调用read方法,跟进read方法,\think\template\driver\File.php

卧槽,这里的read方法竟然对$vars调用了extract的函数,这样就可以直接覆盖cacheFile变量了,因为这里的$vars变量是可以用户控制的;最终达成了利用。

整体利用链

作者

丨greetdawn丨

发布于

2019-03-07

更新于

2022-04-01

许可协议

评论