ThinkPHP5漏洞分析之文件包含
字数 1004 2025-08-18 11:38:45

ThinkPHP5 文件包含漏洞分析与复现

漏洞概述

本漏洞存在于ThinkPHP5的模板引擎中,由于在加载模板解析变量时存在变量覆盖问题,且未对数据进行有效过滤,导致文件包含漏洞的产生。

影响版本

  • 5.0.0 ≤ ThinkPHP5 ≤ 5.0.18
  • 5.1.0 ≤ ThinkPHP ≤ 5.1.10

环境搭建

  1. 创建测试环境:
composer create-project --prefer-dist topthink/think=5.0.18 tpdemo
  1. 修改composer.json文件:
"require": {
    "php": ">=5.6.0",
    "topthink/framework": "5.0.18"
}
  1. 执行更新:
composer update
  1. 修改控制器文件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();
    }
}
  1. 创建模板文件application/index/view/index/index.html(内容随意)

  2. public目录下放置图片马1.jpg(模拟上传操作)

漏洞复现

访问以下URL触发漏洞:

http://localhost:8000/index/index/index?cacheFile=demo.php

漏洞分析

漏洞触发流程

  1. 用户可控数据通过Controller类的assign方法进行模板变量赋值
  2. 数据存储在think\View类的data属性中
  3. 调用fetch方法加载模板输出
  4. 如果没有指定模板名称,使用默认路径模板(当前模块/默认视图目录/当前控制器(小写)/当前操作(小写).html)
  5. 进入Template类的fetch方法,将可控变量$vars赋值给$this->data
  6. 最终传入File类的read方法
  7. read方法中使用extract函数后,直接包含$cacheFile变量

关键问题点

  • 使用extract函数处理用户可控数据,导致变量覆盖
  • 直接包含被覆盖后的$cacheFile变量值
  • 缺乏对用户输入的有效过滤

漏洞修复

官方修复方法(5.0.19版本):

  1. 先将$cacheFile变量存储在$this->cacheFile
  2. 使用extract函数后,include的变量是$this->cacheFile
  3. 避免了直接包含被覆盖的变量值

攻击流程图

  1. 攻击者构造恶意请求参数cacheFile
  2. 参数通过assign方法赋值给模板变量
  3. fetch方法加载模板时处理变量
  4. extract函数覆盖$cacheFile变量
  5. 被覆盖的$cacheFile被直接包含执行

防御建议

  1. 及时升级到安全版本(5.0.19或更高)
  2. 避免直接使用用户输入作为包含路径
  3. 对模板变量进行严格过滤
  4. 使用固定路径包含而非可变路径
ThinkPHP5 文件包含漏洞分析与复现 漏洞概述 本漏洞存在于ThinkPHP5的模板引擎中,由于在加载模板解析变量时存在变量覆盖问题,且未对数据进行有效过滤,导致文件包含漏洞的产生。 影响版本 5.0.0 ≤ ThinkPHP5 ≤ 5.0.18 5.1.0 ≤ ThinkPHP ≤ 5.1.10 环境搭建 创建测试环境: 修改 composer.json 文件: 执行更新: 修改控制器文件 application/index/controller/Index.php : 创建模板文件 application/index/view/index/index.html (内容随意) 在 public 目录下放置图片马 1.jpg (模拟上传操作) 漏洞复现 访问以下URL触发漏洞: 漏洞分析 漏洞触发流程 用户可控数据通过 Controller 类的 assign 方法进行模板变量赋值 数据存储在 think\View 类的 data 属性中 调用 fetch 方法加载模板输出 如果没有指定模板名称,使用默认路径模板(当前模块/默认视图目录/当前控制器(小写)/当前操作(小写).html) 进入 Template 类的 fetch 方法,将可控变量 $vars 赋值给 $this->data 最终传入 File 类的 read 方法 read 方法中使用 extract 函数后,直接包含 $cacheFile 变量 关键问题点 使用 extract 函数处理用户可控数据,导致变量覆盖 直接包含被覆盖后的 $cacheFile 变量值 缺乏对用户输入的有效过滤 漏洞修复 官方修复方法(5.0.19版本): 先将 $cacheFile 变量存储在 $this->cacheFile 中 使用 extract 函数后, include 的变量是 $this->cacheFile 避免了直接包含被覆盖的变量值 攻击流程图 攻击者构造恶意请求参数 cacheFile 参数通过 assign 方法赋值给模板变量 fetch 方法加载模板时处理变量 extract 函数覆盖 $cacheFile 变量 被覆盖的 $cacheFile 被直接包含执行 防御建议 及时升级到安全版本(5.0.19或更高) 避免直接使用用户输入作为包含路径 对模板变量进行严格过滤 使用固定路径包含而非可变路径