在我的認知裡,原始碼分析工具最有挑戰性的部分在於要能順著程式的邏輯跑,而不單只從字面上查,例如: 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起來,工具就找不出任何漏洞!!