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

image-20240914110900875

搭环境

这里可以直接用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 版本的新项目的命令。以下是命令各部分的解释:

  1. composer create-project: 这是 Composer 的命令,用于从指定的包创建一个新项目。Composer 是 PHP 的依赖管理工具。
  2. --prefer-dist: 这个选项表示 Composer 会优先下载压缩后的分发版本,而不是从源代码仓库克隆整个项目。这可以加快安装速度。
  3. topthink/think=5.0.18: 这是指定的项目包名和版本。topthink/think 是 ThinkPHP 框架的 Composer 包名,5.0.18 是指定的版本号,表示安装 5.0.18 版本的 ThinkPHP。
  4. 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 文件

image-20240914111839294

用phpstydy跑起来,根目录设置为public

image-20240914111919945

访问主页

image-20240914111950972

在public的上级目录随便放一个flag.txt

payload

http://127.0.0.1:999/index.php?cacheFile=php://filter/read=convert.base64-encode/resource=../flag.txt

image-20240914112006772

漏洞分析

官方发布的 5.0.19 版本更新说明中,发现其中提到该版本包含了一个安全更新。

https://github.com/top-think/framework/compare/v5.0.18...v5.0.19

image-20240914150504067

我们可以查阅其 commit 记录,发现其改进了模板引擎,其中存在危险函数 extract ,有可能引发变量覆盖漏洞。

image-20240914150707954

调用assign

image-20240914151817676

调用到view的assign

image-20240914151921866

存储到view的data里

image-20240914152023710

调用view的fetch

image-20240914152142517

调用Think的fetch

image-20240914153044271

再调用到template的fetch

image-20240914153319661

最终调用到file的read

image-20240914153433058

把cacheFile给覆盖以后直接include

image-20240914153609828

再看一下官方是怎么修复的

image-20240914154055878

原本是直接直接extract,现在是检查var里面有没有cachefile存在,然后再extract

借用红日的图

https://github.com/hongriSec/PHP-Audit-Labs/blob/master/Part2/ThinkPHP5/ThinkPHP5%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90%E4%B9%8B%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB7.md

7

0%