實驗吧因缺思汀的繞過註入解析
題目地址:http://ctf5.shiyanbar.com/web/pcat/index.php
我沒記錯應該是某道CTF比賽的題目
直接上代碼:
1 <?php 2 error_reporting(0); 3 4 if (!isset($_POST[‘uname‘]) || !isset($_POST[‘pwd‘])) { 5 echo ‘<form action="" method="post">‘."<br/>"; 6 echo ‘<input name="uname" type="text"/>‘."<br/>"; 7 echo ‘<input name="pwd" type="text"/>‘."<br/>"; 8 echo ‘<input type="submit" />‘."<br/>"; 9 echo ‘</form>‘."<br/>"; 10 echo ‘<!--source: source.txt-->‘."<br/>"; 11 die; 12 } 13 14 function AttackFilter($StrKey,$StrValue,$ArrReq){15 if (is_array($StrValue)){ 16 $StrValue=implode($StrValue); 17 } 18 if (preg_match("/".$ArrReq."/is",$StrValue)==1){ 19 print "水可載舟,亦可賽艇!"; 20 exit(); 21 } 22 } 23 24 $filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)"; 25 foreach($_POST as $key=>$value){26 AttackFilter($key,$value,$filter); 27 } 28 29 $con = mysql_connect("XXXXXX","XXXXXX","XXXXXX"); 30 if (!$con){ 31 die(‘Could not connect: ‘ . mysql_error()); 32 } 33 $db="XXXXXX"; 34 mysql_select_db($db, $con); 35 $sql="SELECT * FROM interest WHERE uname = ‘{$_POST[‘uname‘]}‘"; 36 $query = mysql_query($sql); 37 if (mysql_num_rows($query) == 1) { 38 $key = mysql_fetch_array($query); 39 if($key[‘pwd‘] == $_POST[‘pwd‘]) { 40 print "CTF{XXXXXX}"; 41 }else{ 42 print "亦可賽艇!"; 43 } 44 }else{ 45 print "一顆賽艇!"; 46 } 47 mysql_close($con); 48 ?>
14行定義了一個攻擊過濾函數.首先判斷了傳入的是不是數組,倘若是數組那麽就進行分割處理,implode是分割.分割以後的類型仍為數組(因為沒有寫以什麽分割,所以是整體分割,也就是你傳aaa結果還是aaa這裏的 PS:作用搞不懂他)
然後再是使用了正則過濾,而且是使用了預編譯的{$_POST[‘pwd‘]} 可參考 :https://www.t00ls.net/viewthread.php?tid=46325
所以註入是不可能的了.(個人覺得這個預編譯可能部分人沒註意看會認為是拼接的仍然有註入.所以在這個情況之下會一直話費時間在繞過註入)
加了雙引號可以看打是被轉義的這就是{$_POST[‘uname‘]}的作用
所以綜上所述通過or之類的繞過沒戲的.
這時就要用到註入的一個小技巧,我們使用group by pwd with rollup 來在查詢結果後加一行,並且這一行pwd字段的值為NULL
在mysql官方文檔中是這樣描述rollup函數的:
大概的意思就是在GROUP BY子句中使用WITH ROLLUP會在數據庫中加入一行用來計算總數,ROLLUP子句的更加詳細的用法,可以參考mysql的官方文檔,此處就不多做贅述了。
再結合limit和offset就可以寫出一個payload
即:輸入的用戶名為:‘ or 1=1 group by pwd with rollup limit 1 offset 2 #密碼為空
這裏解釋一下此時執行的SQL:
SELECT * FROM interest where uname=‘ ‘ or 1=1
group by pwd with rollup (在數據庫中添加一行使得pwd=NULL)
limit 1 (只查詢一行)
offset 2 (從第二行開始查詢)
#註釋
此時密碼只要為空即可查詢成功
實驗吧因缺思汀的繞過註入解析