分享一个伪0Day
一个看似牢固的CMS,不存在什么0day,就一定会安全么?
之前在一次授权的入侵中,碰到了一例论坛,使用的是phpwind,这个CMS貌似早就被阿里巴巴收购了,从漏洞库和网上的各项漏洞情报来看,这个CMS漏洞相对来讲并不多,且版本受限很大。
目标版本为phpwind7.3.2,默认管理路径且存在弱口令,但作为一个成熟的论坛CMS,虽然拥有后台最高权限,但依然无法轻易对服务器造成威胁,所以在这里笔者选择先获取源码并进行代码审计,然而并未发现明显的可利用漏洞,参照网上的RCE和SQL注入,并未在当前版本复现。
数据备份
然而在卡壳的时候,数据库中的一张表引起了我的注意,pw_attachs:
该表记录的是论坛发帖功能附件指向存储目录下的真实文件名:
显然借助论坛前台的访问我们是无法知道它的真实文件名的,因为这里做了封装,服务端检索数据库并进行文件流输出:
#下载链接:
http://127.0.0.1:84/job.php?action=download&pid=tpc&tid=1&aid=1
简单看一下这个方法,对于download请求,服务端通过匹配tid、pid等参数查找对应文件,用来给后边的文件流输出功能提供内容。
#job.php
elseif ($action == 'download') {
set_time_limit(300);
InitGP(array('aid','pid'));
(!$tid || !is_numeric($aid)) && Showmsg('job_attach_error');
if (is_numeric($pid)) {
$table = GetPtable('N',$tid);
$where = 'pid='.pwEscape($pid);
$post = $db->get_one("SELECT fid,aid,author,authorid FROM $table WHERE pid=".pwEscape($pid));
} else {
$table = GetTtable($tid);
$where = 'tid='.pwEscape($tid);
$post = $db->get_one("SELECT t.fid,t.author,t.authorid,tm.aid FROM pw_threads t LEFT JOIN $table tm USING(tid) WHERE t.tid=".pwEscape($tid));
}
看到了这些,突然想到了后台中的数据备份功能:
值得吐槽的是,该CMS备份内容前端可见:
我们借助本地搭建的demo,便可轻松获取它的真实路径,并借助前端访问:
借此猜解到它的网络路径:
#网络路径
127.0.0.1:84/attachment/2_1_ef0f5e6ba17177c.scp_php
是的,这个文件采用了自定义的拓展名,换句话说,什么拓展名根本无所谓,我们翻车了么?不,才刚刚开始。
解析漏洞
本地部署环境为phpstudy,但目标服务器却是OpenResty:
关于OpenResty我最认同的一句话概括:OpenResty是一个通过 Lua 扩展 NGINX 实现的可伸缩的 Web 平台,说白了,它是基于NGINX的,这里我们就自然会想到NGINX的解析漏洞。
比如以下形式,当然我本地是不可能解析的:
#网络路径
127.0.0.1:84/attachment/2_1_ef0f5e6ba17177c.scp_php/x.php
但是使用完全相同的套路,借助本地demo指路,在目标站点再次复现,自然会成功解析,懒得打码了,反正目标机在内网:
总结
之所以分享这个案例,主要是想引起各CMS使用者重视,代码审计审不出的漏洞配合中间件的配置不当依然会对服务器产生极大的威胁,本文提到的漏洞其实都十分基础、古老,但在特定环境下的结合却让我们无法再忽视。
修复建议
- 避免默认路径、弱口令的使用
- 中间件配置安全和应用安全同等重要