天天看點

CTF-Web12(涉及PHP代碼審計及mysql中的with rollup , limit offset的利用)12.因缺思汀的繞過

12.因缺思汀的繞過

CTF-Web12(涉及PHP代碼審計及mysql中的with rollup , limit offset的利用)12.因缺思汀的繞過
CTF-Web12(涉及PHP代碼審計及mysql中的with rollup , limit offset的利用)12.因缺思汀的繞過

分析:

先檢視頁面源代碼,收集資訊:

CTF-Web12(涉及PHP代碼審計及mysql中的with rollup , limit offset的利用)12.因缺思汀的繞過
CTF-Web12(涉及PHP代碼審計及mysql中的with rollup , limit offset的利用)12.因缺思汀的繞過

看來這又是一道代碼審計:

<?php
error_reporting(0);
 
if (!isset($_POST['uname']) || !isset($_POST['pwd'])) {
    echo '<form action="" method="post">'."<br/>";
    echo '<input name="uname" type="text"/>'."<br/>";
    echo '<input name="pwd" type="text"/>'."<br/>";
    echo '<input type="submit" />'."<br/>";
    echo '</form>'."<br/>";
    echo '<!--source: source.txt-->'."<br/>";
    die;
}
 
function AttackFilter($StrKey,$StrValue,$ArrReq){  
    if (is_array($StrValue)){#判斷是否為數組
        $StrValue=implode($StrValue);#如果是數組,則連接配接成字元串
    }
    if (preg_match("/".$ArrReq."/is",$StrValue)==1){   
       #隻要比對到就是exciting!/比對到一次就停/比對方式就是正則
        print "水可載舟,亦可賽艇!";
        exit();
    }
}
 
$filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)";
foreach($_POST as $key=>$value){ 
#foreach 可以周遊數組與對象,它會把目前單元的鍵名也會在每次循環中被賦給變量 $key,
#值賦給變量$val,
    AttackFilter($key,$value,$filter);
}
 
 
$con = mysql_connect("XXXXXX","XXXXXX","XXXXXX");
if (!$con){
    die('Could not connect: ' . mysql_error());
}
$db="XXXXXX";
mysql_select_db($db, $con);
 
 
$sql="SELECT * FROM interest WHERE uname = '{$_POST['uname']}'";
$query = mysql_query($sql); #執行語句
if (mysql_num_rows($query) == 1) { #該函數傳回一個整數,表示記錄中有多少行資料
    $key = mysql_fetch_array($query);
#mysql_fetch_array() 函數從結果集中取得一行作為關聯數組,第二個參數,(MYSQL_BOTH - 預設)。
#同時産生關聯和數字數組
    if($key['pwd'] == $_POST['pwd']) {
        print "CTF{XXXXXX}";#很明顯,這是重點
    }else{
        print "亦可賽艇!";
    }
}else{
    print "一顆賽艇!";
}
mysql_close($con);
 
?>
           

總結:

CTF-Web12(涉及PHP代碼審計及mysql中的with rollup , limit offset的利用)12.因缺思汀的繞過

這裡有三層限制,繞過這三層限制就可以得到flag

0X00

$filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)";

在第一層的filter裡面就過濾了常用的SQL關鍵詞,是以正常的SQL 注入就不行了。如果輸入了filter裡面的語句,網頁傳回“水可載舟,亦可賽艇!”

0X01

if (mysql_num_rows($query) == 1) { 
//傳回結果集中行的數目
    $key = mysql_fetch_array($query);
           

第二層是限制從資料庫傳回的資料必須是一行,在滿足第一層條件的情況下可以使用 limit 的傳回來确定資料庫中總共有幾行資料。 

注意它的查詢語句是  $sql = select * from interest where uname = ‘{$_POST[‘uname’]}’于是構造:

1' or 1 limit 1 offset 0#

1' or 1 limit 1 offset 1#

1' or 1 limit 1 offset 2#

發現2#時傳回“一顆賽艇!” 其他都是“亦可賽艇!”———–說明資料庫隻有兩條資訊

舉例解析:

CTF-Web12(涉及PHP代碼審計及mysql中的with rollup , limit offset的利用)12.因缺思汀的繞過

1' or 1 含義如下:

CTF-Web12(涉及PHP代碼審計及mysql中的with rollup , limit offset的利用)12.因缺思汀的繞過

Group by with rollup 會在最後多計算一個總數(更多參考:https://blog.csdn.net/qq_42254088/article/details/81904819)

注:with rollup 與group by一起使用,可以獲得額外的行,提供了更高一層的求和結果。group by 子句:代表分組

CTF-Web12(涉及PHP代碼審計及mysql中的with rollup , limit offset的利用)12.因缺思汀的繞過

0X02

$key['pwd'] == $_POST['pwd']

接下來想辦法繞過第三層,這裡是個if判斷,隻要為true 就可以過,于是可以利用group by with rollup來繞過,用with rollup 來獲得NULL值,然後在pwd裡不寫值,if就為true了。

構造: 1' or 1 group by pwd with rollup limit 1 offset 2#

(注:這裡為什麼用2是因為,在前面的測試中我們知道interest表有兩行資料,那麼利用1' or 1 group by pwd with rollup 又得到了一個pwd為null的額外的行,隻要我們密碼為空,即可查詢成功, null==空字元串  為true)

CTF-Web12(涉及PHP代碼審計及mysql中的with rollup , limit offset的利用)12.因缺思汀的繞過