ThinkPHP5漏洞分析之文件包含
字数 1004 2025-08-18 11:38:45
ThinkPHP5 文件包含漏洞分析与复现
漏洞概述
本漏洞存在于ThinkPHP5的模板引擎中,由于在加载模板解析变量时存在变量覆盖问题,且未对数据进行有效过滤,导致文件包含漏洞的产生。
影响版本
- 5.0.0 ≤ ThinkPHP5 ≤ 5.0.18
- 5.1.0 ≤ ThinkPHP ≤ 5.1.10
环境搭建
- 创建测试环境:
composer create-project --prefer-dist topthink/think=5.0.18 tpdemo
- 修改
composer.json文件:
"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();
}
}
-
创建模板文件
application/index/view/index/index.html(内容随意) -
在
public目录下放置图片马1.jpg(模拟上传操作)
漏洞复现
访问以下URL触发漏洞:
http://localhost:8000/index/index/index?cacheFile=demo.php
漏洞分析
漏洞触发流程
- 用户可控数据通过
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或更高)
- 避免直接使用用户输入作为包含路径
- 对模板变量进行严格过滤
- 使用固定路径包含而非可变路径