简介
本次漏洞存在于 ThinkPHP 模板引擎中,在加载模版解析变量时存在变量覆盖问题,而且程序没有对数据进行很好的过滤,最终导致 文件包含漏洞 的产生。
漏洞影响版本: 5.0.0<=ThinkPHP5<=5.0.18 、5.1.0<=ThinkPHP<=5.1.10。
环境搭建
composer create-project --prefer-dist topthink/think=5.0.18 thinkphp_5.0.18
修改json文件
index控制器改成如下:
<?php
namespace app\index\controller;
use think\Controller;
class Index extends Controller
{
public function index()
{
$this->assign(request()->get());
return $this->fetch(); // 当前模块/默认视图目录/当前控制器(小写)/当前操作(小写).html
}
}
创建 application/index/view/index/index.html 文件,内容随意(没有这个模板文件的话,在渲染时程序会报错)
在public目录下放入图片马(模拟上传图片操作)
访问:
http://127.0.0.1/thinkphp_5.0.18/public/index.php/index/index/index?cacheFile=2.png
分析
首先是经过$this->assign(request()->get());
得到$this->data的值:
接着看$this->fetch();
会跳转到View类下的fetch方法,然后因为这样一行代码:
$this->engine->$method($template, $vars, $config);
会进入//thinkphp/library/think/view/driver/Think.php
的fetch方法
一路下去…这里的模板文件就是我们之前创建的,可见如果没有这文件会抛出异常!
然后到Template类下的方法,生成了缓存文件,然后read()方法读取这个缓存文件
这个read()方法里面就是;漏洞的重点了,里面使用了extract()函数,而在这儿$vars
变量是可以实现变量覆盖的。且$vars
正是我们所控制的!最后的include的是$cacheFile
变量,而include是放在了extarct后面执行的,因而可以实现包含我们图片马的操作!
在进入extract()函数前:
extarct()函数后:实现变量覆盖
七月火师傅的流程图:
修复
先将缓存文件$cacheFile
赋值给$this->cacheFile
,再使用extract函数,而最后include的变量是$this->cacheFile
,也就不受extarct函数影响了