Thinkphp5 文件包含漏洞复现分析

image-20211117223456251

漏洞概要

漏洞存在于 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

<?php
namespace appindexcontroller;
use thinkController;
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

访问即可文件包含

image-20211130235551702

漏洞分析

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

跟进assign()方法

image-20211201002846035

跟进$this->view->assign

在:thinkphp/library/think/View.php

image-20211201093144107

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

image-20211201093317181

继续跟进

image-20211201093932731

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

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

think/view/driver/Think.php

image-20211201095558659

可以看到,$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

image-20211201115020846

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

方法调用栈:

image-20211201115312700

漏洞修复

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

image-20211201120146191

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>