SQL Injection的深入探討
SQL injection可以說是一種漏洞,也可以說成是一種攻擊方法,程序中的變量處理不當,對用戶提交的數據過濾不足,都可能產生這個漏洞,而攻擊原理就是利用用戶提交或可修改的數據,把想要的SQL語句插入到系統實際SQL語句中,輕則獲得敏感的信息,重則控制服務器。SQL injection并不緊緊局限在Mssql數據庫中,Access、Mysql、Oracle、Sybase都可以進行SQL injection攻擊。
一、SQL Injection的原理
SQL Injection的實現方法和破壞作用有很多,但萬變不離其宗,其原理可以概括為一句話 :SQL Injection就是向服務器端提交事先準備好的數據,拼湊出攻擊者想要的SQL語句,以改變數據庫操作執行計劃。這句話主要包含這么三層意思:
- 攻擊者通過何種途徑注入?
存在SQL Injection漏洞的地方都是應用程序需要根據客戶端環境構造SQL語句的地方。由此可以推論,只要存在"客戶端數據替換預定義變量"的地方,就有可能被注入。 客戶端提交數據可以有很多種方式:GET,POST,Client-Agent,Cookie,Server Enviroment... - 攻擊者為什么可以將它想要的語句"注入"?
因為服務器端應用程序采用拼湊SQL語句的方式,這使得攻擊者有機會在提交的數據中包含SQL關鍵字或者運算符,來構造他們想要的語句。 - SQL Injection最終結果是什么?
改變數據庫操作執行計劃。這個結果不一定是惡意的,只要你的SQL語句沒有按照你預期的計劃(plan)執行,那么就可以視為被注入了,不管提交數據的人是不是惡意的。
注:這里只是簡單的列出SQL 注入的方式,展開來說明可參看SQL Injection的源由與防範之道,駭客的 SQL填空遊戲(上) ,駭客的 SQL填空遊戲(下)
二、ASP.NET應用程序如何避免SQL Injection攻擊
發生SQL Injection攻擊的根源是SQL語句的拼湊方式,如果是通過直接拼接SQL的方式就非常容易發生SQL Injection攻擊,SQL Server的SQL語句拼湊還有另一種更加安全的方式:參數查詢。如果用戶需要創建每次使用不同值的查詢,則可以在查詢中使用參數。那么這個參數到底是什么呢?其實確切的說,應該把這個參數叫做占位符。即參數是在運行查詢時提供值的占位符。在SQLServer數據庫中,在需要顯示的內容(Select子句)與查詢條件(Where子句)中都可以采用參數,從其他地方接收輸入的值。不過大部分情況下,都只在查詢條件中使用參數。即在單個行或者組的搜索條件中使用參數作為占位符。
在SQLServer中,參數可以分為兩種,即未命名參數與命名參數。通常情況下,如果SQL語句中只需要一個參數的話,那么可以采用未命名參數。如需要查詢某個員工上班到現在的全部出勤信息。此時就只需要用到員工編號這個參數即可。此時可以采用未命名的參數。不過有的時候可能查詢時需要不止一個參數。
如現在需要查詢某個員工在4月份的出勤情況。此時就需要兩個參數,分別為員工編號、月份。或者需要三個參數,分別為員工編號、開始日期、結束日期等等。總之要多于一個參數。此時就需要使用命名參數。因為如果使用未命名參數的話,則數據庫并不知道要把哪個參數對應到哪個地方。所以說,如果要在查詢中使用多個參數,那么此時命名參數就會非常有用。
SqlCommand代表了在SQL Server 數據庫中執行的SQL或者存儲過程,它有一個屬性是Parameters 包含了SQL 語句中用到的參數集合,對于SQL命令中要用到的每一個參數都對應一個SqlParameter對象。添加SqlParameter對象到Parameters集合有兩個方法:Add()和AddWithValue()。他們都有多個重載方法,Add()有一系列的重載方法,我一般是使用方法Add(String, SqlDbType),然后單獨賦值。
ADO.NET的參數查詢到達SQL Server數據庫的時候是通過系統存儲過程sp_executesql執行的:
上述查詢上包含了參數的數據類型和參數值,傳入的值是字符串只是代表了一個文本,而不會成為SQL的一部分,這樣就避免了SQL Injection。
通過使用參數查詢還有另一個好處是可以提高SQL 的性能,當 SQL Server 會看到 SQL 語句時,它首先檢查其緩存中是否存在一個完全相同的語句。 如果找到了一個,它將執行優化的執行計劃,以確保盡可能有效地執行該語句。如果它找不到完全匹配,它通過創建一個緩存,在執行語句中使用該執行計劃。 您可以看到 sp_executesql 調用的第一部分包含該語句,和它始終都是一樣。它的所有后續使用將使用緩存優化的計劃。 如果此語句動態生成使用字符串串聯,并且在 ProductID 更改的時候,需要創建并為每個值的 ProductID 存儲執行計劃。 "....WHERE ProductID = 13"與"....WHERE ProductID = 96"不一樣。
三、微軟發布的3款SQL Injection攻擊檢測工具
隨著 SQL INJECTION 攻擊的明顯增多,微軟發布了三個免費工具,幫助網站管理員和檢測存在的風險并對可能的攻擊進行攔截。
- Scrawlr :這個微軟和 HP合作開發的工具,會在網站中爬行,對所有網頁的查詢字符串進行分析并發現其中的 SQL INJECTION 風險。Scrawlr 使用了部分 HP WebInspect 相同的技術,但只檢測 SQL INJECTION 風險。Scrawlr 從一個起始 URL 入口,爬遍整個網站,并對站點中所有網頁進行分析以找到可能存在的漏洞。 下載地址:https://download.spidynamics.com/Products/scrawlr/
- Microsoft Source Code Analyzer for SQL Injection:這款被稱作 MSCASI 的工具可以檢測 ASP 代碼并發現其中的 SQL INJECTION 漏洞(ASP 代碼以 SQL INJECTION 漏洞著稱),你需要向 MSCASI 提供原始代碼,MSCASI 會幫你找到存在風險的代碼位置。
下載地址:http://www.microsoft.com/downloads/details.aspx?FamilyId=58A7C46E-A599-4FCB-9AB4-A4334146B6BA&displaylang=en - URLScan 該工具會讓 IIS 限制某些類型的 HTTP 請求,通過對特定 HTTP 請求進行限制,可以防止某些有害的請求在服務器端執行。UrlScan 通過一系列關鍵詞發現惡意請求,并阻止惡意請求的執行。 下載地址: http://www.iis.net/downloads/default.aspx?tabid=34&g=6&i=1697