測試微軟SQL Injection漏洞掃瞄工具
微軟日前推出了可以掃瞄ASP原始碼是否有SQL Injection漏洞的工具,我的第一個念頭是,They really did it?
在我的認知裡,原始碼分析工具最有挑戰性的部分在於要能順著程式的邏輯跑,而不單只從字面上查,例如: Request("id")被指定成變數id,傳給函數GetInfo(id),函數中再呼叫RunGetInfoSel(id),使用者輸入的參數經過三手才被拿來組SQL指令字串(危險,勿學),除非分析工具一路追進函數中,才能解析出這裡隱含了SQL Injection的漏洞。換著角度想,分析工具幾乎要有假裝自己在執行程式碼的能力,才不容易發生疏漏。
高深的工程被做成免費的工具,當然是好事。但我對它的犀利度存疑,於是下載了工具,並寫了以下的程式來考驗它一下。以下的ASP程式裡,我故意搞了三處SQL Injection漏洞(再次警告,錯誤示範,勿學),用msscasi_asp.exe掃瞄:
1: <%
2: Dim id, sql, cnStr
3: cnStr = "Provider=MSDAORA;Data Source=TTT;User Id=xxx;Password=xxx;"
4: id = Request("id")
5: '以下寫法隱含SQL Injection漏洞,千萬不可學
6: sql = "SELECT * FROM X WHERE ID='" & id & "'"
7: RunSql sql
8: RunSql2 id
9:
10: Dim cnY,rsY
11: Set cnY=Server.CreateObject("ADODB.Connection")
12: cnY.Open cnStr
13: Set rsY=Server.CreateObject("ADODB.Recordset")
14: rsY.Open sql, cnY
15: Response.Write rsY("D")
16: rsY.Close
17: cnY.Close
18: Set cnY=Nothing
19:
20: Sub RunSql(sql)
21: Dim cnY,rsY
22: Set cnY=Server.CreateObject("ADODB.Connection")
23: cnY.Open
24: Set rsY=Server.CreateObject("ADODB.Recordset")
25: rsY.Open sql, cnY
26:
27: Response.Write rsY("D")
28: rsY.Close
29: cnY.Close
30: Set cnY=Nothing
31: End Sub
32:
33: Sub RunSql2(id)
34: Dim cnY,rsY
35: Set cnY=Server.CreateObject("ADODB.Connection")
36: cnY.Open
37: Set rsY=Server.CreateObject("ADODB.Recordset")
38: '以下寫法隱含SQL Injection漏洞,千萬不可學
39: sql = "SELECT * FROM X WHERE ID='" & id & "'"
40: rsY.Open sql, cnY
41: Response.Write rsY("D")
42: rsY.Close
43: cnY.Close
44: Set cnY=Nothing
45: End Sub
46: %>
執行結果不太理想,工具只抓到第14列一處,將有問題的SQL傳入函數執行,或是將Request("id")傳入函數中再直接組SQL,都成了漏網之魚。因此,若把第14列Remark起來,工具就找不出任何漏洞!!
結果讓人有些失望,但不意外! 要寫出可以"跑"VBScript程式的工具本來就不是簡單的事,更何況它是免費工具。大家在使用這類工具時,要把握一個原則: 有抓到表示有問題,沒抓到不代表沒問題。
自動化工具可以偷懶省工,但總難免疏漏,腳踏實地逐一人工Review,對我來說還是最可靠的方法。如果你不幸有幸在帶領團隊開發網站,記得要在動手前再三強調SQL Injection知識的宣導,可以省去事後補破網要花的龐大人力物力。
PS: 之前保哥寫過文章介紹HP提供的另一套免費偵測工具--scrawlr。做法與MS的這個工具上不太相同,並不分析程式碼本身,而是模擬這陣子很流行的游擊式SQL Injection攻擊的手法,以QueryString方式測試網站有沒有漏洞,比較屬於黑箱測試性質,涵蓋度有限,但如果只是想拿來證明網站沒穿衣服,倒是夠用。
留言列表