0x00 題目概述
題目地址:http://web2.sniperoj.cn:10004/
拿到題,嘗試注入,發現有過濾。
進行fuzz,發現過濾了 左右括號,分號,等號 ,還有一些查詢關鍵字 。
在username有盲注。
為true時候返回 ‘admin’
同時題目提示flag就為admin的密碼。
0X01 自己解題思路流程
嘗試聯合查詢 : union select 1,2,3 #
發現有回顯。
但是發現過濾了 'like' '=' 'where' 'username' 'password' 等一些關鍵字。
無果。
嘗試盲注。
1. 不含有左右括號的函數。 在網上只找到兩個 @@datadir ,@@user
沒什么用。
2. 嘗試繞過過濾。編碼繞過等等。無效。
嘗試把username構造成數組,看是否有有用的信息顯示。得到如下。
Warning: strtolower() expects parameter 1 to be string, array given in/var/www/html/index.phpon line13
Notice: Array to string conversion in/var/www/html/index.phpon line22
Flag is the password of admin!
可知有一個 strtolower函數。但這些信息還是沒有什么用。
卡殼。
想了挺久的,無果。
0x02 正確的思路
先按個人理解通俗介紹一下 order by 這個東西
select bulabulabula 什么的 接一個 order by , order by 1 表示在查詢這個表返回多行結果的時候,按第一列的字段開頭的值進行排序。數字在前,然后過了是小寫,再過了就是大寫字母。
order by 2 表示按第二列進行排序,從acsii小的值往上排序。如果只有兩列,order by 3 則會報錯,所以order by 也可以用來判斷列的數量。
貼圖如下:
表:
order by 2 查詢結果如下(即按照username開頭的第一個值進行排序,如果第一個相同則比較第二個):
好,上面的介紹只是對新手而言,對很多人來說都是廢話。回到題目。
這題我看了源碼。相關的語句如下:
過濾:
function filter($str){
$filterlist = "/\(|\)|username|password|where|case|when|like|regexp|into|limit|=|for|;/";
if(preg_match($filterlist,strtolower($str))){
die("Go away!");
}
return $str;
}
查詢部分:
$sql = "select * from admin where username ='$username' and password = '$password'";
$res = $conn -> query($sql);
返回結果的部分:
if($res->num_rows>0){
$row = $res -> fetch_assoc();
if($row['id']){
echo $row['username'];
}
}else{
echo "The content in the password column is the flag!";
}
分析如下:
進行查詢,返回結果中 ‘username’ 這一列的值。
paryload思路如下:
我們先看一個在數據庫中的查詢的例子:
這個查詢,我們order by 3, 讓查詢結果 按照 password 進行排序。
可以看到,admin1 的password 為 'admin1' ,是 ‘a’開頭,然而我們union select 是 1,2,'0' ,‘0’ 這個在‘a’ 的前面 ,這個返回 username 就是 我們的 2 了。
改一下。
‘b’ 比 'a'大 ,在他后面,這個時候返回第一行 username 的值就為 'admin1'。
那這題思路就很明顯了。
我們 order by 3 ,讓他按照password 進行排列。 union 1,2,3 在3的位置進行爆破。返回值會有一個臨界變化狀態。
一位一位來。
大概意思是這樣。
0x03 腳本
直接粘貼格式會亂。截圖如下。
運行結果截圖:
0x04 總結
這題真挺有意思的 不看源碼真寫不出來
出題人思路很有新意,都沒寫過這種,點贊。(手動@王一航 大佬)
怎么說,對order by 有了挺深刻的印象,收獲頗豐。
還是要好好看,好好學。
