Thinkphp5 文件包含漏洞复现分析

Thinkphp5 文件包含漏洞复现分析_第1张图片

漏洞概要

漏洞存在于 ThinkPHP模板引擎中,在加载模版解析变量时存在变量覆盖问题,而且程序没有对数据进行很好的过滤,最终导致文件包含漏洞 的产生。

影响版本

5.0.0 <= Thinkphp <= 5.0.18

5.1.0 <= ThinkPHP <= 5.1.10

环境搭建

Phpstudy:

  • OS: Windows
  • PHP: 7.3.4
  • ThinkPHP: 5.0.18

创建测试环境:

composer create-project topthink/think=5.0.18 thinkphp5.0.18

composer.json 文件的 require 字段设置成如下:

"require": {
     
    "php": ">=5.4.0",
    "topthink/framework": "5.0.18"
},

执行composer update

控制器:application/index/controller/Index.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 文件,内容任意,作为这个index控制器的index方法的模板。

在public目录放置一个图片马,模拟文件上传操作

漏洞复现

http://localhost:8090/public/?cacheFile=1.jpg

访问即可文件包含

Thinkphp5 文件包含漏洞复现分析_第2张图片

漏洞分析

public function index()
    {
     
        $this->assign(request()->get());
        return $this->fetch(); 
    }

跟进assign()方法

Thinkphp5 文件包含漏洞复现分析_第3张图片

跟进$this->view->assign

在:thinkphp/library/think/View.php

Thinkphp5 文件包含漏洞复现分析_第4张图片

将参数赋值后返回,跟进fetch

image-20211201093317181

继续跟进

Thinkphp5 文件包含漏洞复现分析_第5张图片

变量$vars为我们get传入的参数并赋值给$this->data

跟进$this->engine->$method($template, $vars, $config);

think/view/driver/Think.php

Thinkphp5 文件包含漏洞复现分析_第6张图片

可以看到,$data是get传参。parseTemplate()函数获取模板文件名,得到默认文件名

继续跟进fetch方法

public function fetch($template, $vars = [], $config = [])
    {
     
        if ($vars) {
     
            $this->data = $vars;
        }
        ...
        if ($template) {
     
        	...
            // 读取编译存储
            $this->storage->read($cacheFile, $this->data);
            // 获取并清空缓存
            ...
            echo $content;
        }
    }

跟进$this->storage->read($cacheFile, $this->data);

在:think/template/driver/File.php

Thinkphp5 文件包含漏洞复现分析_第7张图片

这里有extract($vars, EXTR_OVERWRITE);。在EXTR_OVERWRITE标记的情况下,如果有冲突,覆盖已有的变量。那么我们可以通过变量覆盖$cacheFile变量,从而实现文件包含。

方法调用栈:

Thinkphp5 文件包含漏洞复现分析_第8张图片

漏洞修复

判断get传参里是否有cacheFile键,有的话就删掉,也删掉_think_cacheFile键,然后再进行文件包含。

Thinkphp5 文件包含漏洞复现分析_第9张图片

你可能感兴趣的:(Web安全,php反序列化,php,web安全)