ThinkPHP5的文件包含漏洞
加载模版解析变量时存在变量覆盖问题,导致文件包含漏洞的产生 漏洞影响版本:5.0.0<=ThinkPHP5<=5.0.18 、5.1.0<=ThinkPHP<=5.1.10
tp框架由两部分组成 应用项目: https://github.com/top-think/think 核心框架: https://github.com/top-think/framework 框架下载好后,需要更名为thinkphp
搭环境
这里可以直接用composer来获取代码 通过以下命令获取测试环境代码:
composer create-project --prefer-dist topthink/think=5.0.18 tp5.0.18
GPT:
composer create-project --prefer-dist topthink/think=5.0.18 tp5.0.18
是用于使用 Composer 创建一个基于 ThinkPHP 5.0.18 版本的新项目的命令。以下是命令各部分的解释:
composer create-project
: 这是 Composer 的命令,用于从指定的包创建一个新项目。Composer 是 PHP 的依赖管理工具。--prefer-dist
: 这个选项表示 Composer 会优先下载压缩后的分发版本,而不是从源代码仓库克隆整个项目。这可以加快安装速度。topthink/think=5.0.18
: 这是指定的项目包名和版本。topthink/think
是 ThinkPHP 框架的 Composer 包名,5.0.18
是指定的版本号,表示安装 5.0.18 版本的 ThinkPHP。tp5.0.18
: 这是创建项目时指定的目录名称。该命令执行后,Composer 会在当前目录下创建一个名为tp5.0.18
的目录,并将 ThinkPHP 5.0.18 版本的项目文件下载到该目录中。
将 composer.json 文件的 require 字段设置成如下:
"require": {
"php": ">=5.6.0",
"topthink/framework": "5.0.18"
},
然后执行 composer update
,并将 application/index/controller/Index.php 文件代码设置如下:
<?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 文件
用phpstydy跑起来,根目录设置为public
访问主页
在public的上级目录随便放一个flag.txt
payload
http://127.0.0.1:999/index.php?cacheFile=php://filter/read=convert.base64-encode/resource=../flag.txt
漏洞分析
官方发布的 5.0.19 版本更新说明中,发现其中提到该版本包含了一个安全更新。
https://github.com/top-think/framework/compare/v5.0.18...v5.0.19
我们可以查阅其 commit 记录,发现其改进了模板引擎,其中存在危险函数 extract ,有可能引发变量覆盖漏洞。
调用assign
调用到view的assign
存储到view的data里
调用view的fetch
调用Think的fetch
再调用到template的fetch
最终调用到file的read
把cacheFile给覆盖以后直接include
再看一下官方是怎么修复的
原本是直接直接extract,现在是检查var里面有没有cachefile存在,然后再extract
借用红日的图