ThinkCMF框架任意内容包含漏洞的讲解
本文来自无问社区,更多网安资料可前往查看http://www.wwlib.cn
背景描述
ThinkCMF是一款基于PHP+MYSQL开发的中文内容管理框架,底层采用ThinkPHP3.2.3构建。
ThinkCMF提出灵活的应用机制,框架自身提供基础的管理功能,而开发者可以根据自身的需求以应用的形式进行扩展。每个应用都能独立的完成自己的任务,也可通过系统调用其他应用进行协同工作。
在这种运行机制下,开发商场应用的用户无需关心开发SNS应用时如何工作的,但他们之间又可通过系统本身进行协调,大大的降低了开发成本和沟通成本。
0x01 影响版本
ThinkCMF X1.6.0
ThinkCMF X2.1.0
ThinkCMF X2.2.0
ThinkCMF X2.2.1
ThinkCMF X2.2.2
ThinkCMF X2.2.3
漏洞危害
攻击者可利用此漏洞构造恶意的url,向服务器写入任意内容的文件,达到远程代码执行的目的。
漏洞分析
安装过程就简单忽略吧,贴个安装完成能正常访问的主页。
首先打开主入口index.php文件,查看到程序的项目路径,如下显示项目路径在application目录之中。
而后打开 Portal 下的 Controller 目录 ,选择IndexController.class.php控制类文件。
可以看到这里IndexController类中只有一个方法display方法,那么看一下父类HomebaseController文件,根据ThinkPHP框架规则,可以通过g\m\a参数指定分组\模块\方法,这里可以通过a参数直接调用Portal\IndexController父类(HomebaseController)中的一些权限为public的方法。
这边有问题的是display函数和fetch函数:
display函数的作用是加载模板和页面输出 返回输出内容,所对应的参数为:
$templateFile 模板文件名,$charset 模板输出字符集,$contentType 输出类型,$content 模板输出内容。
而后的templateFile参数会经过parseTemplate函数处理确定模版路径,判断模板是否存在,若当模板不存在时会在当前目录下开始查找,然后调用THinkphp Controller 函数的display方法,可以配合一处上传形成文件包含。
fetch函数的作用是获取输出页面内容,调用内置模板引擎fetch方法,thinkphp的模版引擎使用的是smarty,在smarty中当key和value可控时便可以形成模板注入。
这里fetch函数的三个参数分别对应$templateFile 指定要调用的模板文件,$content 模板输出内容,$prefix 模板缓存前缀*。利用时templateFile和prefix参数可以为空,我们可以在在content参数传入待注入的php代码即可。
漏洞利用
我们将上述的漏洞分析完成之后,我们就来看看这漏洞如何进行利用吧。
方法一:构造a参数的display方法,实现任意内容包含漏洞
payload:
/index.php?a=display&templateFile=README.md
方法二:构造a参数的fetch方法,可以不需要知道文件路径就可以把php代码写入文件。
payload:
/index.php?a=fetch&content=
写入xy.php一句话shell文件之后,发现页面显示空白。
我们发现本地电脑成功写入xy.php,之后我们利用中国蚁剑链接访问即可。
漏洞修复
将 HomebaseController.class.php 和 AdminbaseController.class.php 类中 display 和 fetch 函数的修饰符改为 protected 。