如何利用sql注入進行爆庫


SQL注入能做什么

在《SQL注入基礎》一文介紹了SQL注入的基本原理和實驗方法,那接下來就要問一下,SQL注入到底能什么?

估計很多朋友會這樣認為:利用SQL注入最多只能獲取當前表中的所有記錄,但無法獲取其它表的內容,事實果真的如此?

正像小偷從窗戶爬進入房間,難道他只能在房間內偷東西?非也,他可以將整個房子洗劫一空。

不相信?那來看看如何對MySQL進行爆庫。

如何將MySQL數據庫連根拔起

如果作為一名黑客,根本無法知道系統中有哪些表,表中有哪些字段,那如何將數據庫的內容竊取出來呢?

答案是MySQL數據有一個元數據庫,它會描述整個MySQL服務器有哪些數據庫,每個數據有哪些表,每個表有哪些字段,這就相當於把自家房子有什么寶貝統統告訴別人了。

那這個元數據庫就一個根,只要抓住了這根據,沿着:

元數據庫 -> 數據庫列表->表列表->字段列表->表內容

這個樹狀分層的檢索順序,就可以將整個數據庫內容全部竊取出來,下面就跟大家演示。

元數據庫在哪

剛才談到MySQL里面有個元數據庫,但它在藏在哪里呢?別急,請登錄MySQL數據庫,並運行show databases;命令,就可以獲取所有數據庫列表,如下圖所示:

show databases命令可查詢所有數據庫名

圖片中標紅色的數據庫information_schema就是元數據庫,里面應用盡有,可以盡情開拓處女地。

進入information_schema數據庫,看看里面有哪些數據表,使用如下命令:

這里寫圖片描述

我們所說的根就在SCHEMATA表,它里面描述了整個MySQL 下所有數據庫。 
然后再利用TABLES表,則可以看到數據下的表名,再利用COLUMNS表,則可以看到每個表下的字段名。下面依次展示如何查看這些數據。

查看所有數據庫

SCHEMATA表描述所有數據庫信息,只需標准的select語句:

SELECT * FROM information_schema.SCHEMATA

即可將該表的內容全部顯示出來:

查看所有數據庫列表

請注意,從這里開始不再入進入某個數據庫之后再訪問表,而是采用<數據庫名>.<表名>的標准格式來訪問某個數據庫下的表。上述的information_schema.SCHEMATA表示查詢information_schema數據庫下的SCHEMATA表。

圖中SCHEMA_NAME字段為數據庫名,從查詢結果可以知該MySQL服務器有5個數據庫。

查看表

有了數據庫列表,就可以進一步查看某個數據庫下所有表(當前也可以查看所有數據庫下的所有表)。比如查看lyt_test數據庫下的所有表,使用SQL語句:

SELECT TABLE_SCHEMA, TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'lyt_test'

查詢結果如下圖所示:

查詢lyt_test數據庫下的所有表

TABLE_NAME表示表名,左列TABLE_SCHEMA為數據庫名,由於lyt_test數據庫下只有accounts這個表,所以輸出結果只有一列。

查看表中的所有字段

然后使用COLUMNS表可以查詢表的所有字段信息,使用下面SQL語句可查詢accounts表的所有字段名類型: 
SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE FROM information_schema.COLUMNS WHERE TABLE_NAME = 'accounts'

查詢出accounts表所有字段和類型信息如下圖所示:

查看accounts表下所有字段信息

查看表中的所有記錄

查看accounts表中的內容更是小菜一碟了,學過數據庫的都知道SQL寫成下面這樣: 
SELECT * FROM lyt_test.accounts

結果如下: 
查看account表下所有記錄

好了,到這里相信你已經學習如何從MySQL中竊取所有數據庫內容了。

尋找個支點

偉大的物理學家阿某米德曾經說過:

給我一個支點,我可以撬起整個地球

前面從技術上介紹了在不知道MySQL數據如何設計的情況下,通過元數據庫informatio_schema,一步步將整個數據庫內容竊取出來。

那么如何利用SQL注入來竊取整個數據庫呢?,這就是要尋找的支點

還記得上篇文章介紹的實驗嗎?利用SQL注入技術,可以將userinfo表中的所有數據都竊取出來。但該SQL能注入的部分只是WHERE部分,而SELECT ... FROM ...部分中的字段和表名卻是無法注入的,那怎么可以將其它表的數據竊取出來呢?

這個密秘就就是利用UNION語句。是的,標准SQL提供了UNION語句,可以將兩個SELECT結果聯合起來(即對兩個SELECT結果作並集)。UNION語句的語法如下:

SELECT column_name1(s) FROM table_name1 UNION SELECT column_name2(s) FROM table_name2
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

唯一的要求就是兩個SELECT語句的列數要相等。

有了UNION語句,就可以將SELECT * from userinfo WHERE ...和 SELECT * from lyt_test.accounts兩個結果聯合起來。

等等,作為一個黑客,沒有拿到源代碼,怎么知道SELECT * from userinfo查詢結果有多少列呢? 
顯然是不知道的,但可通過試探方法拿到這個數值:依次注入UNION SELECT 1, ... N這樣的語句來試探。先嘗試SELECT 1, 再SELECT 1,2, 然后SELECT 1,2,3,直到不運行出錯為止。可以先在MySQL上測試一下,結果下圖所示:

列數試探結果

從上圖測試結果可知UNION后面跟的SELECT結果必須是兩列,否則會出錯。

對了,還記得注入時WHERE后是兩個條件嗎?(name = ‘nameANDpasswd=passswd ‘),在實際代碼中可能會是更復雜的條件,甚至黑客也很難猜測的條件,那這個UNION語然該插在那個變量呢?使得整個SQL還是個合法的查詢語句。

最好安全的做法是將UNION SELECT ...注入到第一個變量中,然后注入的尾部增加一個注釋符號,將后的語句注釋掉,就不會考慮后面的是什么語句了。在MySQL數據庫,使用#符號即可實現注釋。

說了這么多,可以做一下注入測試,驗證一下:

username文本框中輸入:ivan' union select 1,2#,如下圖:

輸入username內容

login 按鈕后的運行結果如下圖所示:

union注入結果

請留注下紅框中生成的SQL語句:

SELECT * FROM userinfo WHERE name = ‘ivan’ union select 1,2# AND passwd = ”

#將后面的SQL內容注釋掉了,MySQL解析時直接將它干掉,相當於下面的SQL語句:

SELECT * FROM userinfo WHERE name = ‘ivan’ union select 1,2

select 1, 2的結果是常數行, 在后面的例中嘗試從表中查詢數據,而不完全是常數行。

好了 ,UNION#就是撬動爆庫的那個支點

實踐爆庫

萬事俱備,只欠東風。那就讓吹起東風吹起來吧,吹得更猛烈一些。

以下實驗都是基於《SQL注入基礎》一文開發的數據庫應用demo來實驗的,如果讀者沒有SQL注入的基礎知識,建議看看這篇文章;同時建議SQL注入的初學者也按此文搭建相同的數據應用demo來實驗測試一把。

爆數據庫列表

username中注入:

ivan’ union select 1,SCHEMA_NAME from information_schema.SCHEMATA #

即可查詢所有數據庫列表如下圖:

注入獲取所有數據庫

圖示標紅色框的就是數據庫列表。我們在UNION SELECT ...語句中第一列為常數1,第二列是information_schema.SCHEMATA表中SCHEMA_NAME這一列,它剛好就是數據庫名。

爆某個數據庫下的所有表名

為了精減輸出結果,這里只爆lyt_test數據庫下的表名,往username中注入:

ivan’ union select 1,TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA = ‘lyt_test’#

即可查詢得lyt_test數據庫下所有表,如下圖所示:

注入獲取lyt_test數據庫下的表

不同的地方是lyt_test數據庫下只有accounts一個表,其它與爆數據庫原理相同,不作過多解釋。

爆某個表下所有字段

這里只爆accounts表下的所有字段,往username中注入:

ivan’ union select 1, COLUMN_NAME from information_schema.COLUMNS WHERE TABLE_NAME = ‘accounts’ #

結果如下圖所示:

注入獲取字段名

標紅的是字段名。那么類型呢? 修改注入內容為:

ivan’ union select 1, DATA_TYPE from information_schema.COLUMNS WHERE TABLE_NAME = ‘accounts’ #

就可以獲取字段類型信息,如下圖所示:

注入獲了字段類型

標紅色的分別是前面兩個字段的類型,即ID類型為charbalance類型為float

從上面可以發現規律:每個注入可以獲取到目標表中的每個列表數據, 如果表中有N表,注入N次可以獲取完整的表信息。

爆某個表下的所有記錄

這里就不寫的,讀者可以自己練習一下,原來跟上面完全一樣。

總結

原來SQL注入爆數據庫是這么容易的,但有幾個必備條件

  1. MySQL中出現一個元數據庫information_schema,它描述整個MySQL服務器所有數據庫->表->字段關系樹
  2. SQL語言提供了UNION語句,可以新增竊取其它數據合並到被注入SELECT結果
  3. MySQL對SQL做擴展,提供注釋符#,讓注入可以為所欲為

爆庫的精髓掌握了嗎?快來試試。

 

 

 

 

注:本文轉自http://blog.csdn.net/linyt/article/details/52966555#


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM