汪廣舟 方少卿
(1.安徽理工大學(xué),安徽 淮南 232001;2.銅陵職業(yè)技術(shù)學(xué)院,安徽 銅陵 244000)
隨著當(dāng)今的網(wǎng)絡(luò)應(yīng)用全面普及, 基于B/S 模型Web 應(yīng)用系統(tǒng)應(yīng)用越來(lái)越廣泛,但是由于這個(gè)領(lǐng)域的入門門檻不高,程序員的水平及經(jīng)驗(yàn)也良莠不齊,相當(dāng)一部分程序員在編寫代碼的時(shí)候, 沒(méi)有對(duì)用戶輸人數(shù)據(jù)的合法性進(jìn)行判斷和檢查, 使應(yīng)用程序存在極大安全隱患。
SQL 注入主要因?yàn)槌绦騿T對(duì)程序中動(dòng)態(tài)SQL語(yǔ)句沒(méi)有作嚴(yán)格的過(guò)濾或檢測(cè), 導(dǎo)致攻擊者能在注入點(diǎn)提交非法的SQL 語(yǔ)句, 使得程序和服務(wù)器的信息被泄漏。注入攻擊是互聯(lián)網(wǎng)Web 安全所面臨的最大威脅之一。 根據(jù)美國(guó)國(guó)家漏洞數(shù)據(jù)庫(kù)(National Vulnerability Database)的統(tǒng)計(jì)[1],2008 年,SQL 注入漏洞占全年所有漏洞總數(shù)的19.41%,2009 年這個(gè)比例為16.85%。 OWASP 的統(tǒng)計(jì)結(jié)果表明[2],Web 應(yīng)用十大安全漏洞中,SQL 注入漏洞的比例約為18%, 名列第二。
SQL 注入(SQL Injection)技術(shù)最早出現(xiàn)在1999年,微軟中國(guó)技術(shù)中心從兩個(gè)方面進(jìn)行了描述:腳本注入式的攻擊和惡意用戶輸入用來(lái)影響被執(zhí)行的SQL 腳本。 利用SQL 注入技術(shù)來(lái)實(shí)施的網(wǎng)絡(luò)攻擊常被稱為SQL 注入攻擊(SQLIA,SQL Injection Attack),其本質(zhì)是利用Web 應(yīng)用程序中所輸入的SQL 語(yǔ)句的語(yǔ)法處理,針對(duì)的是Web 應(yīng)用程序開發(fā)者在編程過(guò)程中未對(duì)SQL 語(yǔ)句傳入的參數(shù)做出嚴(yán)格的檢查和處理所造成的漏洞。
如上面代碼所示,如果用戶輸入的loginname 和password 的值分別為“admin”和“123456”,
服務(wù)器得到用戶輸入,交給login.asp 腳本處理,在腳本的第4、5 行將用戶輸入保存到變量中, 在第13 行將用戶輸入放在SQL 查詢語(yǔ)句中。自動(dòng)生成查詢語(yǔ)句為:
select * from users where username='admin' and password='123456'
正常情況下,上述SQL 查詢?nèi)绻祷匾粭l用戶記錄,則說(shuō)明身份驗(yàn)證成功;反之,則說(shuō)明身份驗(yàn)證失敗。 然而,當(dāng)用戶的輸入為“'admin' or 1=1 --”和“123456”,該服務(wù)器端腳本構(gòu)造的SQL 查詢語(yǔ)句為:
select * from users where username='admin' or 1=1 -- and password='123456'
輸入的 “'” 閉合了SQL 語(yǔ)句的 “'”,“--”是SQL 語(yǔ)言中的注釋。 所以“--”后面的所有內(nèi)容被忽略,where 判斷語(yǔ)句后面的 “or 1=1” 的恒成立,因此,系統(tǒng)將身份驗(yàn)證判斷為成功,攻擊者也即成功獲得驗(yàn)證。
目前對(duì)SQL 注入攻擊的通用防范是過(guò)濾SQL關(guān)鍵字或者敏感字符串, 包括:“'”,“--”,“exec”,“xp_”,“sp_”,“declare”,“union",“and”,“+”,“//”,“..”,“%”,“0x”等,然而,SQL 語(yǔ)句是千變?nèi)f化的,一種語(yǔ)句可以等價(jià)成其他形式, 利用編碼或數(shù)據(jù)庫(kù)命令動(dòng)態(tài)構(gòu)造變異的SQL 語(yǔ)句能繞過(guò)這類防范。 如上例中“' or 1=1”可以變異成:“' or 'unusual' = 'unusual'”、“' or 'something'='some'+'thing'”、“' or something like 'some%'”、“' or 2 >1”、“'or' text' >'t'”、“'or whatever in (whatever')”、“'or 2 between 1 and 3”;而SQL 變異注入歸納起來(lái)有以下常用手段。
過(guò)濾函數(shù)通常會(huì)過(guò)濾select、update、delete 這些關(guān)鍵字, 但偏偏忘記區(qū)分大小寫, 因此在構(gòu)造SQL注入語(yǔ)句時(shí)可以將關(guān)鍵字進(jìn)行大小寫切換往往可以繞過(guò)程序的限制。
假設(shè)某網(wǎng)站有一條新聞的頁(yè)面為:
http://site/news.asp?id=1
id 為參數(shù)名,1 為頁(yè)面接受的參數(shù)值,攻擊者可以構(gòu)造如下URL:
http://site/news.asp?id=1 and (selecT count(*)from admin)>=0
猜解數(shù)據(jù)庫(kù)中是否存在admin 表, 若返回頁(yè)面與id=1 頁(yè)面相同, 說(shuō)明附加條件成立, 即表admin存在,反之,即不存在。
攻擊者喜歡用“'”來(lái)測(cè)試注入漏洞。 所以也有很多程序會(huì)過(guò)濾“'”號(hào)的方法來(lái)“防止”注漏洞。 然而可以利用相關(guān)的函數(shù),構(gòu)造不含有單引號(hào)的SQL 注入語(yǔ)句,達(dá)到繞過(guò)程序限制的目的。如where xtype='a'。字符a 對(duì)應(yīng)的ASCII 碼是97, 所以可以用where xtype=char(97)代替,如果字符是中文的,比如where name=' 用戶', 可以用where name=nchar (29992)+nchar(25143)代替。
URL 編碼是一種瀏覽器用來(lái)打包表單輸入的格式。 瀏覽器從表單中獲取所有的name 和其中的值,將它們以name/value 參數(shù)編碼(移去那些不能傳送的字符, 將數(shù)據(jù)排行等) 作為URL 的一部分或者分離地發(fā)給服務(wù)器。
URL 編碼遵循下列規(guī)則: 每對(duì)name/value 由&符分開;每對(duì)來(lái)自表單的name/value 由=符分開。 如果用戶沒(méi)有輸入值給這個(gè)name, 那么name 還是出現(xiàn),只是無(wú)值。 實(shí)質(zhì)是一個(gè)字符的ASCII 碼十六進(jìn)制前面加上 “%”。 比如http://site/name 與http://site/nam%65 對(duì)于瀏覽器來(lái)說(shuō)是等效的。 若注入語(yǔ)句為“http://site/news.asp?id=1 or 1=1”,經(jīng)過(guò)編碼后為:http://site/news.asp?id=1%20%6f%72%20%31%3d%31
防注入程序過(guò)濾了通過(guò)Get、Post 方式提交的數(shù)據(jù),而忽略了Cookie 方式提交的數(shù)據(jù)。 若獲取數(shù)據(jù)方式直接使用:request (" 參數(shù)名稱"), 這時(shí)就產(chǎn)生Cookie 注入。 上例猜解數(shù)據(jù)庫(kù)中是否存在admin 表注入語(yǔ)句可以變?yōu)椋?/p>
Javascript:alert(document.cookie=”id=”+escape(1 and (select count(*) from admin)>=0)
在ASP 中Request 對(duì)象在省略具體的集合名稱而直接使用“id=request(“id”)”來(lái)獲取數(shù)據(jù)對(duì),總是接Request.OueryString,Request.Form,Request.cookies,Request.servervariables 集合的順序來(lái)搜索的,而Cookies 可以在客戶端進(jìn)行修改,這樣一來(lái),攻擊者就可以使用誘使服務(wù)器接收Request.Cookies 方式提交變量的值,從而繞過(guò)防注入程序進(jìn)行注入攻擊。判定方式和Get 方式一樣, 如網(wǎng)頁(yè)返回的正常,則admin 表存在,反之則不存在。
(1)繞過(guò)空格過(guò)濾
使用注釋/**/來(lái)替換空格, 類似C 語(yǔ)言一樣,C語(yǔ)言在編譯之前注釋會(huì)被用個(gè)空格替換。 如:http://site/news.asp?id=1/**/or/**/1=1/**/,或者變異的如下:
http://site/news.asp?id=1/*o*/or/*o*/1=1/*o*/,然而許多過(guò)濾程序也會(huì)將“/”過(guò)濾掉,此種方法就行不通了,但是可以使用“( )”來(lái)分割關(guān)鍵字,如:http://site/news.asp?id=(1)or(1)=(1),此外空格還可以用Tab鍵或“+”來(lái)代替。
(2)整句賦值繞過(guò)多關(guān)鍵字過(guò)濾
SQL 防注入程序通常過(guò)濾掉許多關(guān)鍵字, 這時(shí)可套用DECLARE @S NVARCHAR(4000) SET @S=CAST(0x16 進(jìn)制語(yǔ)句AS NVARCHAR(4000)) EXEC(@S)語(yǔ)句來(lái)繞過(guò)限制,比如要執(zhí)行:
exec master.dbo.xp_cmdshell "net user"--
現(xiàn)將此句轉(zhuǎn)換為十六進(jìn)制,然后提交:
若返回正常的頁(yè)面,則說(shuō)明該語(yǔ)句成功執(zhí)行了。
(3)xor 異或
對(duì)于SQL 注入來(lái)說(shuō), 用得最多的邏輯詞就是“and”、“or”了,但是上面的邏輯詞肯定會(huì)被SQL 防注入程序過(guò)濾掉。 但是除了“and”、“or”還有另外的邏輯詞,如xor 異或,異或就是相同為假,不同為真。
現(xiàn)有防御SQL 注入技術(shù)主要基于靜態(tài)程序分析和動(dòng)態(tài)檢測(cè)兩大類, 包括: 輸入過(guò)濾、 參數(shù)化查詢、信息流分析[3-5]、專用API 等。
1.輸入過(guò)濾往往僅憑預(yù)先定義好的敏感字符進(jìn)行過(guò)濾, 比如SQL 通用防注入系統(tǒng), 此種方法容易產(chǎn)生誤報(bào)和漏報(bào)。而且,因?yàn)镾QL 注入技術(shù)不斷更新和發(fā)展, 如對(duì)注入的關(guān)鍵字進(jìn)行編碼, 因此基于敏感字符過(guò)濾的技術(shù)存在很多問(wèn)題。同時(shí), SQL 語(yǔ)句是千變?nèi)f化的, 一種語(yǔ)句可以等價(jià)成其他形式, 利用編碼或數(shù)據(jù)庫(kù)命令動(dòng)態(tài)構(gòu)造結(jié)構(gòu)字符串都可繞過(guò)這類防范。
2.在使用參數(shù)化查詢的情況下,數(shù)據(jù)庫(kù)服務(wù)器不會(huì)將參數(shù)的內(nèi)容視為SQL 指令的一部份來(lái)處理,而是在數(shù)據(jù)庫(kù)完成SQL 指令的編譯后,才套用參數(shù)運(yùn)行,因此就算參數(shù)中含有惡意的指令,由于已經(jīng)編譯完成,就不會(huì)被數(shù)據(jù)庫(kù)所運(yùn)行。此種方法缺點(diǎn)在于不是所有數(shù)據(jù)庫(kù)都支持參數(shù)化查詢。 目前Access、SQL Server、MySQL、SQLite、Oracle 等常用數(shù)據(jù)庫(kù)支持參數(shù)化查詢。
3.動(dòng)態(tài)的信息流分析技術(shù)主要根據(jù)語(yǔ)法樹推斷原程序查詢語(yǔ)句的目的, 而這類方法面對(duì)的最主要問(wèn)題是能否準(zhǔn)確分析和推斷原語(yǔ)句的目的和注入語(yǔ)句目的的不同。
4.專用API 是特定的WEB 程序?qū)⒊S玫臄?shù)據(jù)庫(kù)操作封裝成一些專用的API 函數(shù),一般是一些商業(yè)系統(tǒng)。 這種方法可能不會(huì)存在SQL 注入的風(fēng)險(xiǎn),但對(duì)于每個(gè)WEB 應(yīng)用都采用專用API 是不可能的, 同時(shí)需要編程人員學(xué)習(xí)這些專用API 函數(shù)的調(diào)要語(yǔ)法。
人們的網(wǎng)絡(luò)安全意識(shí)越來(lái)越強(qiáng), 絕大多數(shù)Web站點(diǎn)對(duì)SQL 注入進(jìn)行防范,但是各種SQL 注入變異攻擊隨之出現(xiàn),就目前提出的一些防御SQL 攻擊的方法都有各自的優(yōu)缺點(diǎn), 還沒(méi)有一個(gè)完美的解決方案,防范SQL 注入攻擊任重而道遠(yuǎn)。
[1]National Vulnerability Database.National vulnerability database(NVD) CVE statistics[EB/OL].(2012-12).http://web.nvd.nist.gov/view/vuln/statistics-results?cid=4,2012-09-10.
[2]OWASP.Top 10 2007 [EB/OL]. (2012 -11).http://www.owasp.org/index.php/Top_10_2007,2012-10-02.
[3]Sabelfeld A,Myers AC.Language -based infoumation -flow security[J]. IEEE JSA,2003.
[4]周敬利,曉 鋒,等.一種新的反SQL 注入策略的研究與實(shí)現(xiàn)[J].計(jì)算機(jī)科學(xué),2006,33(11):64-68.
[5]Carl Gould, Zhendong Su, and Premkumar Devanbu.Static checking of dynamically generated queries in database applications.ACM Transactions on Software Engineeringand Methodology(TOSEM)[C]. U.S.A:ACM,2007,16.