前言
这是我审计的第一个CMS,从一个大佬处听说这个CMS的洞比较多比较好审就想着审一下试试,因为最近的CTF比赛中,Web题目的魔爪已经伸向了各种各样的CMS,像是之前西湖论剑的信呼OA、以及再往前的蝉知CMS等等,为了紧跟潮流,提高个人代码审计能力,接下来的一段时间里我还会去审计更多的CMS、复现分析框架利用链等等。
因为实在是太菜了,文章中的不足之处还望大佬们多包涵、多指教,提前感谢师傅们QAQ
结构分析
在审计之前我们先明确一下整个CMS的架构,可以发现V4和V2的整体架构完全不一样了,但是主要文件还是在include文件夹下,类似于V2时的init.php,进去之后首先是大面积的defined
然后下面还有参数获取方式,这都是我们审计这个CMS要具备的基础
在extends.inc.php中还有补充
然后分析一下整个CMS在文件上体现出来的大体结构
在文件结构中还可以看出来使用了微擎、eshop来进行开发,同时system中除了eshop还新增了部分功能,包括与钉钉、微信、QQ的接口等等。
但其实这里很容易看得出来大部分的内容还是eshop的内容:
审计
首先扔进Seay自动筛一遍危险函数,当然基本上全是误报,在我不懈的努力之下,侥幸挖到了一点点...
前面的大片MYSQL操作都使用了PDO预处理,没用预处理的地方也用了intval函数进行处理,没什么机会。
文件上传漏洞
下面这里存在一个文件上传的漏洞
这里一看就能看出来是一个对远程的URL上的图片进行提取并上传的一个功能,因为最后进行了 return 我们理论上也能够获得文件名以及路径,同时函数内对后缀等等也没有任何的过滤,我们跟进一下试试。
仍然没什么过滤.. 这个操作本身我们也非常好找
将这里的URL换成我们远程服务器上的恶意文件
可以看到我们的恶意文件已经上传了,由于没有任何过滤,我们可以随意上传webshell、针对服务器的木马文件等等
三处任意文件删除
继续往下,在文件删除的方法这里又让我发现了可乘之机
这里$settings['system_isnetattach']
为空的时候就会直接进入下面的else中的文件删除内容,从这个方法的编写中我们可以看到这里对我们要删除的这个参数没有任何的过滤,我们完全可以拼上目录穿梭来进行任意文件的删除。
继续跟下去,函数有三处调用,我们依次来看一下:
第一处是在uploader.php中,这里很显然对输入的file也没有任何过滤,我们很可能能够实现任意文件删除
定位真的是一件非常困难的事情,这一部分怎么找也找不到,在经过了很久很久的交互之后,请教了大佬,选择了根据参数的构造来进行文件删除。
参数分析
我们通过这个页面来进行分析,这是用户端的购物车页面,我们很容易就能反向找到对应的源码
那么我们来根据它分析一下参数的组成:
首先顺着system中的层级来看eshop
是 m参数、core
这里没有对应的参数,应该是表明进入了模块的划分,moblie
对应 mod,shop
对应 do,cart
对应 act,然后后面的 id 以及 cookie 中包含的参数都是代码中的内容了
第一处
那么我们也可以根据这个原理来定位我们上面的 uploader 并配好相应的参数即可
前面的类似,从 do 开始不同,这里的 do 应该对应为 util
,act 对应为 uploader
通读代码,这里要构成任意文件删除的话实际上只需要两个参数,op
为 remove,file
为 要删除的文件。
结合这里,我们可以建个文档删除一个试试
构造、发包、成功删除
第二处
第一处的中间有点小插曲,但是在被自己弱智到之后审起来就越来越顺了,接下来来看第二处
这里实际上是可以很容易在前端找到的
这里 web 对应的就是 mod 的 site
,然后和上面同样的 do 和 m ,这里代码中的参数非常多,对应的任意文件删除的函数在 op 为 post
的这一部分内,是创建时发的包,我们可以简单抓包看一下
这次因为参数的内容过多,没有采用构造的方式,直接通过对在新建分类处抓到的包补充id
参数以及thumb_old
,成功删除了对应文件
失败的第三处
可以看到,这里的file_delete的参数我们不可控了,是传入uniacid
、id
进行一个PDO预处理之后的结果,这里没有办法进行任意文件删除。
成功的第三处
继续向下看Seay的审计结果,又发现了一处很可能存在文件上传的方法
追到database.php
我们可以先在前端找一下,还是比较好找的
抓包
这里尝试了很久一直没有成功删除,去重新分析了一遍源码,发现这里存在一点问题,如果想任意文件删除的话我们过不了它的文件夹校验,这里应该只能删除任意文件夹。
构造如下包
成功删除! id为base64加密后的 ../../sp4c1ous
删除了网站根目录下的该文件夹
继续往下看
大面积的误报和根本利用不了的
由于大面积审不出来,就没有再继续往下审,看了几篇其他大佬的文章以及CNNVD上的漏洞简单做一做补充
SQL注入
没有测试成功,应该是老版本中的,已经被修复了。
payload:
http://localhost/baijiacmsV4-master/index.php?act=index&beid=1&by=&cate=&do=goods&isdiscount=&ishot=&isnew=&isrecommand=&issendfree=&istime=&keywords=&m=eshop&merchid=&mod=mobile&op=get_list&order=(SELECT * FROM (SELECT(SLEEP(5))))
RCE
审漏了一个RCE 太让人心痛了
确实写得很有问题
过于相信用户的输入了,对用户的输入没有进行处理就直接放进了system函数内,我们跟进一下这个方法的调用
显然,这里的filename我们是能够控制的,我们的filename只要能将前后隔开,在中间进行命令的执行即可。
这里要注意在方法中要过一个if,这里的if的内容我们可以通过全局搜索来进行一下跟踪
是这个位置
这里需要把它开启来确保进入存在命令执行的那个 if(!empty($settings['image_compress_openscale']))
一个小坑,然后我们就需要去定位文件上传的位置了
找到了这个位置,显然就是这里文件上传了
文件名还是很受限制的,这里还需要进行一些思考...
没过多久我就在一道CTF题目里学习到了可以稍加利用的操作 是[N1CTF 2018]eating_cms这道题,里面的情形和这个cms中的差不多,也是将文件名作为参数拼接到了system内,左思右想不知道该怎么得到flag吗,在看过WP之后终于有了一些灵感。
像这样,我们可以通过cd ..
来绕过一些//
,因为如果根目录为当前目录的话就不需要/
了。