0x00 环境搭建
首先去thinkcmf下载5.0的最新版
https://github.com/thinkcmf/thinkcmf/archive/5.0.190111.zip
切换到web根目录下,比如/var/www,然后新建一个目录:ThinkCMF-5.0.190111
把除public目录外的文件都移动到ThinkCMF-5.0.190111下。然后修改index.php,将其中的
|
修改为
|
然后一步步完成安装。
参考:https://blog.csdn.net/youaregoo/article/details/82219722
0x01 利用过程:
后台登录状态下,
1、将payload插入数据库并读取然后写入data/conf/route.php文件
2、然后访问:
触发
操作,执行payload。下图以执行sleep(5)作为演示。
0x02 利用过程与分析
1、将payload插入数据库,写入data/conf/route.php文件
程序的入口是index.php,在index.php中\think\App::run()执行应用。
在App.php的run()函数139行,执行sef::exec();
通过解析url,得到处理此次请求的控制器、类、函数,即AdminCategoryController.php
的addPost
函数。然后调用self::invokeMethod()
。
通过反射执行AdminCategoryController.php
的addPost
函数。
在addPost函数中,从$this->request->param()函数中得到请求中的参数传递给$data。
然后通过$this->validata调用父类(./simplewind/thinkphp/library/think/Controller.php)的validata函数进行过滤。然后将$data传入./app/portal/model/PortalCategoryModel.php
的addCategory函数进行实际的”添加分类”操作。
在addCategory函数中,184行这一句:
|
通过查询数据中是否存在对应的url,由于是第一次插入,所以这里并没有查到。
154行和155行通过setRoute
函数对数据库进行了两次插入操作。
根入setRoute
函数,
其中$fullUrl和$url的值如截图所示。
继续跟,
在34行从数据库中查询查询相关数据,
|
在addCategory
函数的157行调用
|
最终得到$allroutes
的值,创建data/conf
目录,然后拼接待写入的route.php
文件的完整路径,最后调用file_put_contents()
完成写入。可见这个漏洞在于没有对alias
参数中的单引号进行过滤,导致可通过闭合前后的单引号插入用户可控的payload。
写入前后对比如下:
2、触发payload执行
带着登录的cookie访问/portal/admin_category/index.html
,调用routeCheck
函数进行url路由检测
这里先
|
然后,
|
最终执行我们的payload:phpinfo()
。
0x03 Demo
0x04 PoC:
|
0x05 后记
2月7日分配了CVE编号:CVE-2019-7580
ThinkCMF 5.0.190111 allows remote attackers to execute arbitrary PHP code via the portal/admin_category/addpost.html alias parameter because the mishandling of a single quote character allows data/conf/route.php injection.
这个漏洞是在复现thinkcmf的CVE-2019-6713的时候发现的。
根据其描述
by using vectors involving portal/List/index and list/:id to inject this code into data\conf\route.php, as demonstrated by a file_put_contents call.
提到file_put_contents
,猜想这可能是一个文件写入漏洞。然后搜索route.php,发现添加分类
处可以写入该文件。