漏洞介绍
在fetch渲染模板的方法中,调用了File类的read方法中使用了extract
方法造成了变量覆盖,覆盖掉了模板文件,造成文件包含漏洞
漏洞演示
现将图片马上传public目录(实际情况是文件上传上传图片马)
传入?cacheFile=hello.jpg
进行文件包含
漏洞分析
在application/index/controller/Index.php
中添加如下代码触发漏洞
1 |
|
传入?cacheFile=hello.jpg
之后,通过request()->get()
获取GET变量,形式是cacheFile=>hello.jpg
,然后跟进assign方法
进入了thinkphp/library/think/Controller.php
的assign
方法
再进入thinkphp/library/think/Controller.php
的assign方法,通过array_merge
将cacheFile
变量整合到$this->data
中,现在继续跟进到fetch
方法
调用了thinkphp/library/think/Controller.php
类的fetch
方法,接着调用thinkphp/library/think/View.php
类的fetch方法
关键在于,将$this->data
中的值通过array_merge
整合到$vars
中,然后调用了$this->engine
也就是think\view\drive\Think
调用fetch
方法
通过parseTemplate
获取默认的渲染文件application/index/view/index/index.html
,否则抛出异常。接着调用$this->template
也就是think\Template
的fetch
方法
进行了一些赋值和获取Template
文件的操作之后就调用了think\template\driver\File
类的read方法(这里的$cacheFile
不是我们传入的cacheFile,是ThinkPHP的缓存文件)
这里首先判断$vars
和$vars
是否是数组且不为空,然后直接对变量进行extract
操作之后就include
了$cacheFile
文件,因此造成了文件包含
漏洞修复
官方将$cacheFile
直接赋值到$this->cacheFile
中防止被变量覆盖,然后include $this->cacheFile
避免bug出现