环境搭建
源码链接如下所示 https://gitee.com/openbaijia/baijiacms 安装至本地后
直接解压到phpstudy
的www
目录下即可
接下来去创建一个数据库用于存储CMS信息。(在Mysql命令行中执行)
接下来访问CMS,会默认跳转至安装界面
数据库名称和账密注意一下就好,其他随便写
审计
准备工作
对具体文件夹进行一次分析,这样才能对CMS有一个初步的印象,为后续审计做一些铺垫。 根目录如下所示:
其对应目录解释如下
addons 插件
api 接口
assets 静态文件
attachment 上传目录
cache 缓存目录
config 系统文件
include 系统文件
system 后端代码
针对system
目录,这个较为常用,我们可以对其进行进一步分析
system 系统模块目录├─alipay 支付宝服务窗模块├─bonus 优惠券模块├─common 公共函数模板├─index 登录页├─member 会员模块├─modules 可再扩展模块和模块管理├─public 公共模块├─shop 后台商城模块├─shopwap 前台商城模块├─user 系统用户└─weixin 微信模块
对这些有过了解后,还需要看的就是一些后端支撑文件,例如这种xxxinc.php
文件,他们常常存在一些漏洞,进而导致CMS出现漏洞
路由解析
对一个CMS进行漏洞探测前,我们需要首先需要对CMS的路由有所了解。 这里我们直接访问默认页面baijiacms-master/index.php
,然后登录后台,这里说一下找路由还可以的方法,就是关注一些特别点,好找一些,比如这里的修改密码界面
我们点击它,发现此时的路由如下
/baijiacms-master/index.php?mod=site&act=manager&do=changepwd&beid=1
可以发现act
其实是system
文件夹下的文件夹名称,do
是所选择具体文件的名称,对这些有个初步的了解,待会找到文件时能在网页中访问即可。
漏洞查找
任意目录删除
源码分析:
漏洞点位于:includes/baijiacms/common.inc.php
首先关注的是unlink函数,他会删除文件,只要$path不是目录就会进入改分支。
但如果你是目录呢,会对目录中非.、..、qrcode的文件内循环一次,就是会删除文件
循环了一次退出来还会判断改目录是否是/cache目录,不是的话直接删除目录。
综上,因为$path来自于参数,会发现有可能可以实现 “任意” 文件的删除,也包括删除目录
全局搜索,位于system/manager/class/web/database.php的一处调用了rmdirs函数,且发现$_GP['id']可控,也就是整个参数路径可控,但只有通过is_dir()才可以调用,因此可以实现任意目录的删除了。
此外这段代码可以猜出是数据文件的备份删除功能
可以发现这里对变量进行了base64_decode
处理,这下我们想删除的目录的话,我们首先需要对他进行一个base64编码,同时我们可以看到这里指定了路径
$path = WEB_ROOT . '/config/data_backup/';
但这个我们其实是可以绕过的,后续只校验了是不是目录,而未限定目录,所以我们通过burpsuite抓包修改目录就可以实现任意目录删除。
$_GP
是三个数组的整合,故$_GP['id']
也能通过GET、POST请求得到
实操:
进入备份与还原模块,点击备份商城数据
然后进入数据还原模块
点击删除 数据备份,使用burp抓包
发现url中的id参数为删除的数据库备份文件名称,既然这是文件,就试试能不能删除其他文件。
在WWW目录下创建一个123目录(目录,重要的事情说两遍),然后将../../../123路径base64加密为Li4vLi4vLi4vMTIz ,然后使用burp发包删除。
远程文件上传
源码分析:
该漏洞由于调用file_put_contents函数但未对文件名或文件内容做任何过滤操作而造成的。位于includes/baijiacms/common.inc.php
后缀是通过pathinfo()得到的,然后直接将其拼接进$extpath中,然后拼接成一个文件名,文件后缀则取决于url的文件后缀
文件内容则是直接来自file_get_contents($url)
全局搜索,只有一个地方调用了fetch_net_file_upload
函数。位于system/public/class/web/file.php
。
只需要令do=fetch
即可,且url
可通过GET
传递,那么完全可以通过url指定获取远程文件的内容
实操:
命令执行
源码分析:
没有对相应的参数进行过滤而直接使用。位于includes/baijiacms/common.inc.php
的file_save()
中,其中有个system函数,而$file_full_path
来自于该调用该函数的参数,那么可以猜想使用命令分隔符即可执行到命令了。
全局搜索,发现system/weixin/class/web/setting.php
调用了file_save()
,这个$file['name']
来自于一个上传文件的名称。可控
实操:
首先在附件中有个开启选项,选择此选项,否则在file_save()
中会执行不下去
在微信号的设置中上传并提交,抓包并在文件名中命令注入
存储型XSS
使用安装时使用的管理员账号密码登录系统。
点击店铺管理 -->添加店铺
在店铺名称的位置输入测试XSS payload:<script>alert(11);</script>
点击提交
再次查看店铺管理,发现弹出xss