秦廣贊,郭 帆,徐 芳,余 敏
(江西師范大學計算機信息工程學院,江西 南昌 330022)
SQL注入(SQL Injection)漏洞是網(wǎng)站中普遍存在的安全隱患之一,在Web應用程序使用越來越廣泛的同時,SQL 注入攻擊也成為Web應用系統(tǒng)中最嚴重的安全威脅之一。
著名的SQL注入攻擊事件發(fā)生在2005年的上半年,銀行卡系統(tǒng)的數(shù)據(jù)庫被攻破。該事件中,超過25萬的信用卡數(shù)據(jù)被盜,造成1 000萬美元的欺詐事件[1]。
2011年3 月,一個被命名為LizaMoon 的SQL注入攻擊席卷全球,許多網(wǎng)站遭受攻擊,網(wǎng)頁內容中被塞了lizamoon字串,疑似掛馬鏈接,透過Google查詢lizamoon.com關鍵詞,被稙入惡意鏈接的URL 數(shù)在兩天內由28 000 個急速增加到380 000個,甚至蘋果的iTune網(wǎng)站也名列其中[2]。
國際上Web 安全聯(lián)盟OWASP[3]的報告指出,當前SQL 注入的危害非常嚴重。在OWASP前十大Web應用攻擊中,SQL 注入排第一位,占30%。
因此,對SQL注入攻擊檢測和防御方法的研究已經(jīng)成為解決網(wǎng)站安全問題的一個十分重要的途徑。
防范SQL 注入攻擊最常用的方法是輸入過濾[4]。過濾和轉義容易導致SQL注入攻擊的特殊字符,以保證用戶輸入的安全性,從而防御SQL注入攻擊。這種技術的思想基礎是,在網(wǎng)絡服務前端增加一個應用級的防火墻,當接收到用戶輸入信息時進行集中檢查,過濾危險字符,或者使數(shù)據(jù)庫將危險字符按文字對待。這種方法處理漢字查詢時,效果明顯。但是,其缺點也很明顯,存在極高的誤報率和漏報率。有人提出了一種基于正則表達式的過濾方法,但是其準確性依賴于規(guī)則庫的準確性和完整性。Ke Wei等人[5]提出了一種利用應用程序中存儲過程存在的漏洞,實現(xiàn)對SQL 注入攻擊檢測的方法。但是,該方法在用戶正常輸入單引號時容易產(chǎn)生誤報,對于控制流復雜的存儲結構存在漏報。Halfond W G J[6]等人提出了一種名為AMNESIA 的防SQL注入攻擊的技術,其核心思想是靜態(tài)分析源程序中存在的SQL 注入漏洞,建立查詢模型,動態(tài)執(zhí)行時檢測是否包含SQL 注入攻擊。但是,該方法存在一種局限性,如果不能確定一個字符串是SQL關鍵字,會假設該字符串為用戶輸入,即不能準確地區(qū)分用戶輸入和SQL關鍵字。
靜態(tài)分析技術通過發(fā)現(xiàn)源代碼中的安全漏洞來防止入侵攻擊。靜態(tài)分析程序時不需要執(zhí)行所測試的程序,掃描所測試程序的正文,對程序的數(shù)據(jù)流和控制流進行分析,然后產(chǎn)生人性化的錯誤報告。最典型的靜態(tài)分析方法是基于約束的分析[7]:檢查定義的約束與源代碼是否一致來發(fā)現(xiàn)潛在的安全漏洞,可以對類型修飾符、數(shù)據(jù)類型、函數(shù)參數(shù)、返回地址和結構域等定義約束,也可以動態(tài)分析污染數(shù)據(jù)的傳播途徑,判定污染數(shù)據(jù)是否會對系統(tǒng)的安全性造成威脅。
該方法沿用了文獻[5]和文獻[6]的思想,主要由兩部分構成:(1)靜態(tài)分析源程序查找Web應用程序潛在的SQL 注入漏洞,提取執(zhí)行參數(shù)的構造路徑,形成檢測規(guī)則;(2)動態(tài)執(zhí)行時查找檢測規(guī)則,替換執(zhí)行參數(shù)中輸入?yún)?shù)值為用戶輸入,通過比對源SQL語句和得到的SQL 語句在結構和語義上的異同,判別是否存在SQL 注入攻擊。該部分沿用了輸入過濾的思想,以過濾模塊的形式存在。
其優(yōu)勢在于:依據(jù)應用程序中潛在的SQL 注入點形成檢測規(guī)則,過濾用戶輸入,既提升了輸入過濾方法的準確性,又沿用了輸入過濾方法的簡單有效性。與文獻[5]中提出的方法相比,不需要預先在數(shù)據(jù)庫編譯文件,不需要額外的環(huán)境支持。與文獻[6]中提到的方法相比主要有兩點優(yōu)勢。第一,靜態(tài)分析時增加了對自定義函數(shù)體的分析,有效地提升了靜態(tài)分析的準確性。第二,動態(tài)檢測階段,根據(jù)用戶輸入動態(tài)構造自動機模型,確保了動態(tài)檢測的實時性和準確性,通過查找規(guī)則庫,分別為源SQL語句和代入用戶輸入值的SQL 語句建立自動機模型,比對兩個SQL 語句在結構和語義上的異同來判斷是否存在SQL 注入攻擊,而文獻[6]采用的是為每個可注入點建立一個通用的檢測模型。故本文在靜態(tài)分析和檢測的準確性方面存在優(yōu)勢,部署也比較簡單。
整體流程如圖1所示。
Figure 1 Overall flow chart圖1 整體流程圖
源程序的靜態(tài)分析[8]主要包括三個步驟:
步驟1 掃描源程序,查找源程序存在的SQL點,并抽象化形式描述源程序。
步驟2 根據(jù)步驟1的結果,提取執(zhí)行參數(shù)的構造路徑。
步驟3 依據(jù)執(zhí)行參數(shù)的構造路徑,生成檢測規(guī)則。
3.1.1 抽象化描述程序
借助于一款經(jīng)典的靜態(tài)分析工具Checkstyle[9]對源程序進行掃描。自定義了執(zhí)行參數(shù)、變量賦值、函數(shù)三種檢測規(guī)范,依據(jù)掃描結果抽象化形式描述源程序。
若一個函數(shù)不包含全局變量或者沒有接受外界參數(shù)的傳入,那么這個函數(shù)一定是安全的,為了描述方便,本文稱此類函數(shù)為污染數(shù)據(jù)不可到達的函數(shù),反之則稱為污染數(shù)據(jù)可到達的函數(shù)。定義如表1所示。
Table 1 Definition of the abstract description of the source表1 抽象描述源程序的定義
依據(jù)Checkstyle的掃描結果將用戶輸入存到集合I中,將源程序的執(zhí)行參數(shù)存到集合S 中;對S 中的執(zhí)行參數(shù)進行詞法分析[10],提取輸入?yún)?shù),并存到集合P 中,P 的存儲順序和S 中的相對應;將可污染函數(shù)存到集合Fy中;不可污染函數(shù)存到集合Fn中;變量值傳遞的表達式存在集合M 中。例如,如程序1:
程序1 jsp登陸界面的簡單描述〈%
掃描源程序后可得到如表2所示的結果。
Table 2 Results of the abstract description of the source表2 程序抽象描述的結果
3.1.2 路徑的提取算法
在2.1.1節(jié)結果的基礎上,沿用經(jīng)典遞歸算法的思想給出執(zhí)行參數(shù)構造路徑提取算法。其核心思想描述如下:
(1)取S 中一條執(zhí)行參數(shù)為樹T 的根結點,對應的輸入?yún)?shù)為其子結點,以根結點的最左葉子結點為當前根結點。
(2)查找集合M,以對當前根結點的賦值作為其子結點,并以該子結點為當前根結點。重復該步操作。
(3)若對當前根結點賦值為函數(shù)則取函數(shù)的傳入?yún)?shù)或者外部變量為其子結點。若當前根結點的賦值不唯一,則記錄該結點在樹中的相對位置。
(4)若集合M 中查不到對當前根結點的賦值,并且記錄結點相對位置的集合為空則算法結束;反之,返回集合中記錄的相對位置繼續(xù)查找。
算法的形式描述如下:
輸入:S,P,F(xiàn)y,F(xiàn)n,M,G。
輸出:T。
說明:算法描述過程中,以R 表示樹T 的根結點,如果子結點不是葉子結點,稱為當前根結點,用RC表示。用RL表示一個結點的最左邊的葉子結點。用index 表示結點在樹中的相對位置。用flag=true表示變量賦值由函數(shù)提供,flag=false表示變量賦值由變量提供,num=true表示函數(shù)的傳入?yún)?shù)或外部變量唯一,num=false表示大于一個。以V 表示對RC賦值的變量。以C 表示RC的子結點。以F 表示對RC賦值的函數(shù),F(xiàn)P 表示該函數(shù)的輸入?yún)?shù)。集合L 表示index 的集合。
算法開始:
選取值為用戶輸入?yún)?shù)值的葉子結點到根結點的路徑即是執(zhí)行參數(shù)S[1]的一個輸入?yún)?shù)的構造路徑。重復上述步驟可得到S[1]的構造路徑。例如,對于依據(jù)程序1的抽象描述結果表2可得到如圖2所示的路徑。
Figure 2 Construct path by executing parameter圖2 執(zhí)行參數(shù)構造路徑
3.1.3 檢測規(guī)則的生成
檢測規(guī)則的存儲策略:
檢測規(guī)則庫以XML文檔的形式存在,每一個頁面對應一個節(jié)點,節(jié)點中間的每一行代表一條規(guī)則,每條規(guī)則對應于一個SQL注入漏洞。
XML文檔的優(yōu)勢分析:
XML最大的優(yōu)勢在于對各種數(shù)據(jù)的管理;異構系統(tǒng)間的信息互通。任何系統(tǒng)都可以通過XML的解析器來讀取XML數(shù)據(jù);支持精確搜索。
結論1 當且僅當執(zhí)行參數(shù)中包含用戶輸入或被用戶輸入污染的數(shù)據(jù),SQL 注入攻擊才可能發(fā)生。
結論2 設有兩個執(zhí)行參數(shù)S1、S2(S1∈S;S2∈S)且S1?S2。若S2是安全的,那么S1肯定也是安全的[5]。
結論3 若樹T 的葉子結點包含于集合I 中,則此執(zhí)行參數(shù)為潛在的SQL注入點。
很明顯結論1是成立的。前人已經(jīng)證明結論2的正確性。樹T 表示的是一條執(zhí)行參數(shù)的構造路徑,葉子結點表示路徑的起始點,I 表示用戶輸入的集合,由結論1可知結論3成立。
檢測規(guī)則的生成和優(yōu)化原則:
若樹T 滿足結論3 所述條件,則取樹的葉子結點(即用戶輸入)和根結點存儲至規(guī)則庫中,葉子結點與相應的執(zhí)行參數(shù)的輸入?yún)?shù)對應;若檢測規(guī)則中的執(zhí)行參數(shù)滿足結論2,則存儲父集執(zhí)行參數(shù)至規(guī)則庫。規(guī)則庫中規(guī)則的形式如下:
UserInput 表示用戶輸入,sql表示對應的執(zhí)行參數(shù)?!埃!北硎居脩糨斎牒蛨?zhí)行參數(shù)的分隔符,“,”表示用戶輸入的分隔符。pagename表示執(zhí)行參數(shù)所在的頁面的名稱。例如,有頁面index.jsp靜態(tài)分析后提取的路徑如圖2所示。那么,將形成如下規(guī)則:
本節(jié)描述過濾模塊設計的思想來源,可執(zhí)行參數(shù)是否存在SQL 注入攻擊的檢測,檢測規(guī)則的查找方法以及過濾的流程策略。
過濾模塊的設計思想來源于JSP 過濾器Filter的設計。其優(yōu)勢在于:以一種模塊化或可重用的方式封裝公共行為;將高級訪問決策和表現(xiàn)代碼分離;能夠對許多不同的資源批量修改;以常規(guī)方式請求資源;利用修改過的請求信息調用資源;阻止調用資源等。
可執(zhí)行參數(shù)是否存在SQL 注入攻擊的檢測:替換規(guī)則中的輸入?yún)?shù)為用戶輸入。建立自動機模型[10],比較原SQL 語句和代入用戶輸入值的SQL語句在語義和結構上的不同,判斷是否發(fā)生SQL注入攻擊。例如,有SQL 語句Select info From users where name=′"+un+"′′and pwd=′"+up+"′",自動機模型如圖3 所示(其中In是用戶的輸入變量,粗圓代表終點狀態(tài))。當用戶輸入un=′or l=l--,up=′′時形成SQL如下語句:Select info From users where name="or l=l--"And pwd="",自動機模型如圖4所示。
形成的SQL語句不能到達自動機模型的終止狀態(tài),而且語句的結構也被改變,故為惡意查詢語句。
規(guī)則庫以XML 文檔的形式存在,而XML 文檔支持精確查找,故檢測規(guī)則可以依據(jù)關鍵字查找。首先根據(jù)過濾模塊截獲的http請求頁面的名稱查找規(guī)則庫中對應的結點,然后以用戶輸入為關鍵字,逐行查找。查找到完全匹配的則提取該規(guī)則,查找不到全匹配的則提取其父集為其檢測規(guī)則。
假設規(guī)則庫如2.1.3節(jié)中所描述的,則依據(jù)截獲的http 請求查找到〈index〉結點,然后以uname,upwd為關鍵字逐行匹配規(guī)則。
結論1 若用戶輸入不含有敏感字符或SQL關鍵字,則用戶輸入必不含SQL注入。
結論2 若用戶輸入含敏感字符或SQL關鍵字,但查找不到相應的規(guī)則,則用戶輸入不會造成SQL注入攻擊,若查找到相應規(guī)則,則用戶輸入可能造成SQL注入攻擊。
很明顯結論1是正確的。查找不到規(guī)則意味著用戶輸入未影響任何執(zhí)行參數(shù),故結論2是正確的。結論1和結論2是過濾策略的理論基礎,過濾流程如圖5所示。
為了驗證方法的有效性和可行性,我們分別對添加過濾模塊和僅作簡單輸入過濾的JSP 論壇(包含SQL注入漏洞)做了注入實驗。服務器采用Tomcat6.0,數(shù)據(jù)庫采用SQL Server 2000。并且對添加過濾模塊后的系統(tǒng)性能進行了分析。實驗表明,該方法有效可行。
Figure 5 Filter flowchart圖5 過濾流程圖
為驗證方法的準確性,我們分別采用SQLIer、SQLMap、SQLID 自動構造了大量的SQL 注入語句,包括正常但含有敏感字符的語句、常規(guī)攻擊類型的語句(永真式攻擊、集合查詢和捎帶查詢式攻擊)。并手動構造了替換編碼攻擊類型的語句。實驗結果如表3所示。
通過表3可以看出,添加了過濾模塊可以保證含有敏感字符的正常語句通過,并且能夠檢測出替換編碼式的攻擊類型。未添加過濾模塊則出現(xiàn)了誤報和漏報的現(xiàn)象。故該方法能準確地檢測SQL注入攻擊,并且有效地提高了SQL 注入檢測的準確性。
Table 3 Results of SQL injection表3 SQL注入檢測結果
由于動態(tài)檢測時需要查找規(guī)則庫并且需要動態(tài)構造自動機模型,故對系統(tǒng)的性能進行了分析。靜態(tài)分析是獨立于Web應用程序運行之外的,不會造成時間消耗[5]。系統(tǒng)時間的消耗主要包括三個方面:(1)查詢規(guī)則庫消耗的時間,與規(guī)則庫內含有的規(guī)則數(shù)有關;(2)自動機構造的時間,與自動機包含的狀態(tài)數(shù)有關;(3)自動機檢測的時間,與自動機包含的狀態(tài)數(shù)有關。
對時間消耗的分析,可以獨立于Web應用程序之外。實驗采用Java語言模擬自動機的構造和自動機的檢測以及規(guī)則庫的查找。記錄分析了自動機包含5~80個狀態(tài)時所消耗的時間數(shù)據(jù)以及規(guī)則庫中含有10~350條規(guī)則時所消耗的時間數(shù)據(jù)。實驗結果如圖6和圖7所示。
由圖6和圖7可以看出,添加過濾模塊后對系統(tǒng)造成的時延是可以忽略不計的,故添加了過濾模塊后,對系統(tǒng)的影響不大。
本文在國內外研究的基礎上,結合靜態(tài)分析和輸入過濾的主流思想,提出了一種防范SQL 注入的靜態(tài)分析方法。實驗表明,該方法準確有效,與同類的研究工作相比,提高了SQL 注入檢測的準確率,簡化了部署,而且在靜態(tài)分析的準確性方面也有提高。添加了過濾模塊后對系統(tǒng)的性能影響不大。
[1]Kemalis K,Tzouramanis T.SQL-IDS:A specification-based approach for SQL-injection detection[C]∥Proc of SAC'08,2.08:2153-2158.
[2]Steve Christey 2011CWE/SANS top 25most dangerous software errors[EB/OL].[2011-06-29]http://cwe.mitre.org/top25/#CWE-79.
[3]van der Stock A.Top 10 2011[EB/OL].[2011-11-15].http://www.owasp.org-/index.php/Top_10_2011.
[4]Xu Lou,Yao Guo-xiang.SQL injection attack prevention approach and its application[J].Microcomputer Information,2006,2.(3-3):10-12.(in Chinese)
[5]Kei Wei,Muthuprasanna M,Suraj K.Preventing SQL injection attacks in stored procedures[C]∥Proc of 2006Australian Software Engineering Conference,2006:191-198.
[6]Halfond W G J,Orso A.Preventing SQL Injection attacks using AMNESIA[C]∥Proc of 2006ICSE'06,2.06:795-798.
[7]Wu Chun-mei,Xia Nai,Mao Bing.Comparation of static analysis technology to prevent the invasion [J].Computer Engineering,2006,32(3):174-176.
[8]Wen Chang-ci,Wang Zhao-shun.Static analysis of software test automation[J].Computer Engineering and Design,2005,2.(4):987-989.
[9]SourceForge.Checkstyle5.4[EB/OL].[2011-11-15].http://checkstyle.sourceforge.net/index.html.
[10]Aho A V,Sethi R,Ullman J D.Compilers principles,techniques and tools[M].Translated by Li Jian-zhong,Jiang Shou-xu.Beijing:Machinery Industry Press,2003.(in Chinese)
附中文參考文獻:
[4]徐陋,姚國祥.SQL 注入攻擊預防辦法及其應用[J].微計算機信息,2006,2.(3-3):10-12.
[7]吳春梅,夏耐,茅兵.防范入侵的靜態(tài)分析技術比較[J].計算機工程,2006,32(3):174-176.
[8]文昌辭,王昭順.軟件測試自動化靜態(tài)分析研究[J].計算機工程與設計,2005,2.(4):987-989.
[10]Aho A V,Sethi R,Ullman J D.編譯原理[M].李建中,姜守旭,譯.北京:機械工業(yè)出版社,2003.