ZZCMS2019 代码审计学习
zzcms
站长招商网内容管理系统简称 ZZCMS,由ZZCMS团队开发,融入数据库优化,内容缓存,AJAX等技术,使网站的安全性 、稳定性 、负载能力得到可靠保障。源码开放,功能模块独立,便于二次开发。
ZZCMS突出招商及供求功能,适用于网上招商、加盟的行业。例如医药招商行业, 保健品招商行业, 化妆品招商行业, 副食类行业等等
目录结构
/ 根目录为主程序内容显示页面 ../admin 默认后台管理目录(可任意改名) ../user 注册用户管理程序存放目录 ../image 程序设计图片存放目录 ../database IP数据库,系统数据库备份文件存放目录 ../editor 编缉器程序存放目录 ../alipay 支付宝在线支付系统存放目录 ../tenpay 财富通在线支付系统存放目录 ../skin 用户网站模板程序存放目录 ../skin_index 系统模板程序存放目录 ../TemporaryFiles 临时文件存放目录 ../uploadfiles 上传文件存放目录 ../inc 系统所用包含文件存放目录
下载
http://www.zzcms.net/about/6.htm
搭建成功截图:
漏洞点
重装漏洞
配置安装好后,如果没有删除/install目录,重新进入/install目录后
全局查找,在setp1.php中发现这句提示
漏洞点在于/install/index.php中
直接通过post传值来选择setp,可以直接跳过install.lock,实现重装
任意文件删除(CVE-2019-8411)
漏洞点:/admin/dl_data.php
最新版本的我看源代码已经修复了。
<?php include("admin.php"); ?> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <link href="style.css" rel="stylesheet" type="text/css"> <title></title> </head> <body> <table width="100%" border="0" align="center" cellpadding="0" cellspacing="0"> <tr> <td class="admintitle">从Excel(要保存为97-2003兼容格式)导入<?php echo channeldl?>商信息</td> </tr> </table> <div class="border2" style="padding:10px"> <strong>第一步:调整列顺序,字段名可以不同,少字段也可以<br> </strong>列顺序为:classid,<?php echo channeldl?>商姓名,电话,Email,<?php echo channeldl?>产品,<?php echo channeldl?>区域,<?php echo channeldl?>商简介<br> <strong>第二步:上传调整过列顺序的Excel(要保存为97-2003兼容格式)表格文件到/dl_excel目录</strong> </div> <form action="" method="post" name="myform" id="myform" onSubmit="return CheckForm();"> <table width="100%" border="0" cellpadding="5" cellspacing="1"> <tr class="trtitle"> <td width="33%" >文件名</td> <td width="33%" > <div class="boxlink">文件大小</div></td> <td width="33%" >操作</td> </tr> <?php $dir = opendir("../dl_excel"); while(($file = readdir($dir))!=false){ if ($file!="." && $file!="..") { //不读取. .. //$f = explode('.', $file);//用$f[0]可只取文件名不取后缀。 ?> <tr class="trcontent"> <td > <?php echo "<a>".$file."</a>"; ?> </td> <td ><?php $fp="../dl_excel/".$file; echo filesize($fp)/1024 ?>K</td> <td ><a href="dl_data_add.php?filename=<?php echo $file?>">导入到数据库</a></td> </tr> <?php } } closedir($dir); ?> </table> </form> </body> </html>
这里拿先知社区的文章来看把。
payload:
action = del&filename = .. / 1.php
这个漏洞产生的很大原因是开发者没有按照正确的安全开发,对敏感操作没有进行认证。
打开admin/dl_data.php,发现只要把del赋值action参数,然后添加需要删除的文件,就可以删除了,没有进行任何的认证。
从下面的图片可以看出,只要action参数等于'del'时,就能进随意的删除了,无需什么认证这个操作是极其危险。
进行简单的添加认证后,这个Payload 就失效了,当然这个认证只是我个人的随意添加的,更多细节需要开发者团队自己增加。
漏洞一开始的问题就是没有经过任何认证,导致任何人都可以达到任意文件删除,经过简单添加认证后,就变成了后台任意文件删除漏洞,需要后台权限。
存储xss漏洞(CVE-2019-9078)
漏洞来源文章:https://github.com/NS-Sp4ce/ZZCMS-XSS/blob/master/xss.md
漏洞位置:/user/ask.php
直接通过get传参获取do参数
查看modify()函数
modify()函数
function modify(){ global $username; ?> <div class="admintitle">修改问答信息</div> <?php $page = isset($_GET['page'])?$_GET['page']:1; checkid($page); $id = isset($_GET['id'])?$_GET['id']:0; checkid($id,1); $sqlzx="select * from zzcms_ask where id='$id'"; $rszx =query($sqlzx); $rowzx = fetch_array($rszx); if ($id<>0 && $rowzx["editor"]<>$username) { markit(); showmsg('非法操作!警告:你的操作已被记录!小心封你的用户及IP!'); } ?>
存在问题的是markit()函数,对于非法的操作,会被记录下来
function markit(){ $userip=$_SERVER["REMOTE_ADDR"]; //$userip=getip(); $url="http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; query("insert into zzcms_bad (username,ip,dose,sendtime)values('".$_COOKIE["UserName"]."','$userip','$url','".date('Y-m-d H:i:s')."')") ; } function admindo(){ $adminip=getip(); $url="http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; $f=zzcmsroot2."admindoes.txt"; $fp=fopen($f,"a+");//fopen()的其它开关请参看相关函数 $str=date('Y-m-d H:i:s')." ".$_COOKIE["admin"]." ".$adminip." ".$url."\r\n"; fputs($fp,$str); fclose($fp); }
用户访问:/user/ask.php?do=modify&id=1
触发记录非法操作
可惜的是这个漏洞在最新更新的zzcms源代码中也被修复了
bad.php根本不存在。源码下下来就没有bad.php。所以这里仍然用原文章里的分析了。
其中的$url没有经过过滤,直接插入数据库,因此我们可以注册一个用户,访问 http://www.zzcms2019.cc/user/ask.php?do=modify&page=1&id=1,会出现
这时我们可以用Burpsuite抓包,修改包体的URI路径为/user/ask.php?do=modify&page=1&id=1&aaa=<sCrIpT>alert(/xss/)</ScRiPt>
使用<sCrIpT>alert(/xss/)</ScRiPt>是因为在/inc/stopsqlin.php中有一段检测函数
<?php //主要针对在任何文件后加?%3Cscript%3E,即使文件中没有参数 if (strpos($_SERVER['REQUEST_URI'],'script')!==false || strpos($_SERVER['REQUEST_URI'],'%26%2399%26%')!==false|| strpos($_SERVER['REQUEST_URI'],'%2F%3Cobject')!==false){ die ("无效参数");//注意这里不能用js提示 }
完整包体如下
GET /user/ask.php?do=modify&page=1&id=1&aaa=<sCrIpT>alert(/xss/)</ScRiPt> HTTP/1.1 Host: www.zzcms2019.cc User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Cookie: __tins__713776=%7B%22sid%22%3A%201551009070949%2C%20%22vd%22%3A%205%2C%20%22expires%22%3A%201551010962798%7D; __51cke__=; __51laig__=12; bdshare_firstime=1551002231060; PHPSESSID=8o9ms5t57q6dag7ofku75fn2j7; UserName=test; PassWord=e10adc3949ba59abbe56e057f20f883e Connection: keep-alive Upgrade-Insecure-Requests: 1
当管理员访问后台中的用户→用户不良操作记录时
即可触发
.htaccess
.htaccess文件是Apache中相当重要的配置文件,其格式为纯文本,它提供了针对目录改变配置的方法,通过在一个特定的文档目录中放置一个包含一个或多个指令的文件,以作用于此目录及其所有子目录。
通过.htaccess文件,可以实现简单地很多在IIS中很繁琐甚至无法实现的功能,如密码保护、禁止显示目录列表、阻止/允许特定的IP地址、实现网址的301 重定向等等。
正如上面所说,.htaccess文件将影响其所在的目录及其子目录,因此,如果我们要保护的内容(此处以防止图片盗链为例,即图片)位于网站内多个目录下,可以考虑将其放在根目录下;而如果图片有单独的子目录如“/images/”,则只需将其放置在该目录下(当然也可以放到根目录中)。
需要注意的是,如果通过FTP方式将创建好的.htaccess上传到服务器上,传输模式应为ASCII而非Binary。上传到服务器后,应将其属性通过 CHMOD修改为644 或“RW-R–R–”,这样,可以保证服务器能够使用同时无法通过浏览器修改,当然,.htaccess的可读属性也存在一定的风险:攻击者可通过它找出您要保护的对象或认证文件位置——解决办法是将认证文件.htpasswd放到网站根目录之外,这样,便无法通过网络找到它了。
.htaccess不能随意添加文字,添加后直接返回500。