趙 星
(中北大學(xué) 軟件學(xué)院,山西 太原 030051)
?
針對(duì)SQL注入的策略研究
趙星
(中北大學(xué) 軟件學(xué)院,山西 太原 030051)
摘要:在計(jì)算機(jī)技術(shù)高速發(fā)展的今天,讓人們頭疼的是面臨越來(lái)越多的威脅網(wǎng)站的技術(shù)。近年來(lái),SQL注入事件頻發(fā),本文主要介紹了SQL注入及其危害,并提出了使用預(yù)編譯語(yǔ)句,過(guò)濾URL中傳參等安全策略以消除SQL注入的存在,可進(jìn)一步提高網(wǎng)站安全。
關(guān)鍵詞:網(wǎng)絡(luò)安全;SQL注入;防護(hù)
在計(jì)算機(jī)技術(shù)高速發(fā)展的今天,讓人們頭疼的是面臨越來(lái)越多的威脅網(wǎng)站的技術(shù),黑客們利用Internet執(zhí)行各種惡意活動(dòng),如身份竊取、私密信息竊取、帶寬資源占用等。近年來(lái),SQL注入事件頻發(fā),例如某網(wǎng)站的會(huì)員信息泄露事件,造成的損失不可估量,本文主要介紹了SQL注入以及如何防止SQL注入,可進(jìn)一步提高安全意識(shí)。
1SQL注入及SQLMap工具介紹
注入漏洞是Web安全領(lǐng)域中一種最為常見(jiàn)的漏洞。許多Web應(yīng)用系統(tǒng)采用某種數(shù)據(jù)庫(kù),接受用戶從Web頁(yè)面中輸入,完成展示相關(guān)存儲(chǔ)的數(shù)據(jù)(如檢查用戶登錄信息)、將輸入數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù)(如用戶輸入表單中數(shù)據(jù)域并點(diǎn)擊提交后,系統(tǒng)將信息存入數(shù)據(jù)庫(kù))等操作。在有些情況下,將用戶輸入的數(shù)據(jù)和設(shè)計(jì)好的SQL框架拼接后提交給數(shù)據(jù)庫(kù)執(zhí)行,就可能存在用戶輸入的數(shù)據(jù)并非設(shè)計(jì)的正確格式,從而給惡意用戶提供破壞的機(jī)會(huì),即SQL注入。SQL注入攻擊的本質(zhì)就是拼接了用戶輸入的代碼,并予以執(zhí)行,涉及到兩個(gè)關(guān)鍵的因素:第一就是用戶可以隨意輸入內(nèi)容;第二就是原本程序要執(zhí)行的代碼拼接了用戶輸入的數(shù)據(jù)。
SQLMap是一個(gè)自動(dòng)化的SQL注入測(cè)試工具,是一款開(kāi)源軟件,其主要功能是掃描、發(fā)現(xiàn)并利用給定的URL的SQL注入漏洞,目前支持的數(shù)據(jù)庫(kù)是MySQL,Oracle,PostgreSQL,Microsoft SQL Server,Microsoft Access,IBM DB2,SQLite,F(xiàn)irebird,Sybase和SAP MaxDB。當(dāng)給SQLMap這么一個(gè)URL的時(shí)候,它會(huì)判斷可注入的參數(shù)(包括GET參數(shù),POST參數(shù),HTTP Cookie參數(shù));判斷可以用哪種SQL注入技術(shù)來(lái)注入;識(shí)別出哪種數(shù)據(jù)庫(kù);根據(jù)用戶選擇,讀取哪些數(shù)據(jù)。SQLMap采用五種獨(dú)特的SQL注入技術(shù),分別是:
1) 基于布爾的盲注,即可以根據(jù)返回頁(yè)面判斷條件真假的注入。
2) 基于時(shí)間的盲注,即不能根據(jù)頁(yè)面返回內(nèi)容判斷任何信息,用條件語(yǔ)句查看時(shí)間延遲語(yǔ)句是否執(zhí)行(即頁(yè)面返回時(shí)間是否增加)來(lái)判斷。
3) 基于報(bào)錯(cuò)注入,即頁(yè)面會(huì)返回錯(cuò)誤信息,或者把注入的語(yǔ)句的結(jié)果直接返回在頁(yè)面中。
4) 聯(lián)合查詢注入,可以使用union的情況下的注入。
5) 堆查詢注入,可以同時(shí)執(zhí)行多條語(yǔ)句的執(zhí)行時(shí)的注入。
2SQL注入的危害及SQLMap工具演示
惡意用戶輸入不期望的數(shù)據(jù),拼接后提交給數(shù)據(jù)庫(kù)執(zhí)行,可能造成數(shù)據(jù)泄露,還可能修改數(shù)據(jù)庫(kù)的結(jié)構(gòu),甚至刪除應(yīng)用的數(shù)據(jù)庫(kù)表等嚴(yán)重后果。如某系統(tǒng)實(shí)現(xiàn)時(shí),對(duì)成績(jī)更新所用的SQL語(yǔ)句如下:
“UPDATE StuScore SET score=“+ SubmitScore +” WHERE StuID=‘ “+ StuID + ” ‘ ; ”
當(dāng)用戶輸入的SubmitScore為90--,StuID為20150001時(shí),則該SQL變?yōu)椋?/p>
“UPDATE StuScore SET score = 90 -- WHERE StuID = ‘20150001‘;”
--在SQL中是注釋符號(hào),以后的內(nèi)容為注釋?zhuān)@樣上述語(yǔ)句中--之后的內(nèi)容變?yōu)樽⑨專(zhuān)灰荢tudentScore表中所有的記錄的score都變?yōu)?0,而沒(méi)有受到WHERE字句后的學(xué)號(hào)限制。
再比如SubmitScore為80,StuID為20150001’ or ‘a(chǎn)’ = ‘a(chǎn)’時(shí),則該SQL語(yǔ)句變?yōu)椋?/p>
“UPDATE StuScore SET score = 80 -- WHERE StuID = ‘20150001‘ or ‘a(chǎn)’ = ‘a(chǎn)’;”
因?yàn)椤痑’ = ‘a(chǎn)’條件總是成立,因此,SQL執(zhí)行結(jié)果把所有在StuScore表內(nèi)同學(xué)的成績(jī)都更新為80分。
更嚴(yán)重的情況下,用戶輸入DROP等功能性命令,會(huì)造成數(shù)據(jù)庫(kù)表的永久刪除等嚴(yán)重后果,如StuID為20150001;DROP TABLE StuScore --,則SQL語(yǔ)句變?yōu)椋?/p>
“UPDATE StuScore SET score = 80 -- WHERE StuID = ‘20150001‘; DROP TABLE StuScore --”;
手工測(cè)試是一個(gè)繁瑣的過(guò)程,可以借助自動(dòng)化的注入工具SQLMap高效地完成注入測(cè)試,首先檢查該站點(diǎn)是否存在注入:python sqlmap.py-u URL(將URL替換成真實(shí)測(cè)試地址),會(huì)得到類(lèi)似圖1的效果,通過(guò)工具很容易判斷出存在哪種類(lèi)型的注入,注入點(diǎn)相關(guān)信息,以及數(shù)據(jù)庫(kù)系統(tǒng)信息。
圖1 注入點(diǎn)信息
通過(guò)此注入點(diǎn),可以進(jìn)一步探測(cè)存在哪些數(shù)據(jù)庫(kù),命令為python sqlmap.py -u URL-databases,如圖2所示。
圖2 存在數(shù)據(jù)庫(kù)
選定數(shù)據(jù)庫(kù)后,可查看其中存在的數(shù)據(jù)表,命令為python sqlmap.py -u URL -D DB -tables,如圖3所示。
然后判斷表中存在哪些字段以及字段的數(shù)據(jù)值,這樣直接可獲取數(shù)據(jù)庫(kù)內(nèi)的信息,包括一些核心敏感信息,如后臺(tái)管理員用戶名和密碼,用戶的隱私數(shù)據(jù),如圖4所示。
3防御措施
未知攻焉知防,了解攻擊的目的是為了更好地防御,針對(duì)SQL注入攻擊的防御措施如下。
3.1使用預(yù)編譯語(yǔ)句
防御SQL注入的最佳方式就是使用預(yù)編譯語(yǔ)句,進(jìn)行變
圖3 數(shù)據(jù)表信息
圖4 敏感信息
量綁定。因?yàn)槭褂妙A(yù)編譯后的SQL語(yǔ)句的語(yǔ)義不會(huì)發(fā)生改變。在SQL語(yǔ)句中使用?表示,攻擊者無(wú)法改變SQL的結(jié)構(gòu)。下邊用PHP代碼演示變量的綁定過(guò)程。
$query = “INSERT INTO StuScore (StuID ,Name ,Sex ,Score) VALUES(?,?,?,?)”;
$bind = $mysqli -> prepare($query);
$bind -> bind_param(“test” ,$stuID,$name,$sex,$score);
$stuID = “20150001”;
$name = “Zebra”;
$sex = “male”;
$score = “60”;
$bind -> excute();
在JAVA語(yǔ)言中有與PHP類(lèi)似的預(yù)編譯語(yǔ)句,在JAVA中有個(gè)類(lèi)是PreparedStatement,這個(gè)類(lèi)的對(duì)象是通過(guò)參數(shù)?來(lái)傳值的,例:
String sql = "select * from table where id = ?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setInt(1,id);
這里的數(shù)據(jù)庫(kù)語(yǔ)句所用到的參數(shù)要被設(shè)置的,如果你傳入了錯(cuò)的值,或不同類(lèi)型的值,它在插入到數(shù)據(jù)庫(kù)語(yǔ)句中會(huì)編譯不通過(guò),這樣也就防止了SQL注入。
3.2使用安全函數(shù)與安全編碼
為了防止SQL注入攻擊,PHP自帶一個(gè)功能可以對(duì)輸入的字符串進(jìn)行處理,可以在較底層對(duì)輸入進(jìn)行安全上的初步處理,即Magic Quotes。如果magic_quotes_gpc選項(xiàng)啟用,那么輸入的字符串中的單引號(hào),雙引號(hào)和其它一些字符前將會(huì)被自動(dòng)加上反斜杠/。
但Magic Quotes并不是一個(gè)很通用的解決方案,沒(méi)能屏蔽所有有潛在危險(xiǎn)的字符,并且在許多服務(wù)器上Magic Quotes并沒(méi)有被啟用,所以需要使用其它多種方法來(lái)防止SQL注入。
現(xiàn)在各類(lèi)Web語(yǔ)言都實(shí)現(xiàn)了一些編碼函數(shù),可以用來(lái)對(duì)抗SQL注入。比如在MySQL中,可以按照以下思路對(duì)字符進(jìn)行編碼:
“(0x22)-->”
‘(0x27)-->’
(0x5c)-->
同時(shí)可以參考OWASP ESAPI中的實(shí)現(xiàn)。
3.3過(guò)濾URL傳參的變量
在PHP程序中,我們可以使用str_replace()函數(shù)對(duì)字符串變量的內(nèi)容進(jìn)行字符替換。
語(yǔ)法如下:str_replace(“需要替換的字段”,”替換為的字段”,”字符串內(nèi)容”);套用到上面的例子中,假如我們需要過(guò)濾掉”and”我們可以這樣寫(xiě):
$id = $_GET[‘id’];
$id=str_replace(“and”,””,$id);
這樣一來(lái),變量id字符串中的”and”被替換為空字符,可以理解為被刪除了。在不同的使用環(huán)境下,某一個(gè)程序需要替換十幾個(gè)字符。所以需要使用數(shù)組的方式,將字符替換封裝為一個(gè)函數(shù),便于在任何時(shí)候調(diào)用它。
字符替換函數(shù)核心代碼[1]如下:
function fliter_sql($value) {
$sql = array(“select” , ”insert” , ”update” , ”delete” , ” ’ ” , ”/*” , ”../” , ”union” , “into” );
$sql_re = array(“”,””,””,””,””,””,””,””,””);
return str_replace($sql, $sql_re, $value);
}
這是經(jīng)常使用的過(guò)濾函數(shù),通過(guò)它基本上可以過(guò)濾掉絕大多數(shù)的SQL注入。使用的時(shí)候只需要調(diào)用這個(gè)函數(shù),$id = fliter_sql($_GET[“id”]);即可。
3.4檢查數(shù)據(jù)類(lèi)型
檢查數(shù)據(jù)類(lèi)型對(duì)于防止數(shù)字型注入有很大的幫助,特別是在強(qiáng)類(lèi)型的語(yǔ)言中。比如在下邊這段代碼中,就限制了輸入數(shù)據(jù)的類(lèi)型只能為integer,在這種情況下,一般的注入攻擊將失效[2]。
Settpye($offset , ‘integer’);
$query = “SELECT score,id FROM StuScore ORDER BY id LIMIT 10 OFFSET $offset;”;
檢查數(shù)據(jù)類(lèi)型對(duì)防錯(cuò)是大有裨益的,比如用戶在輸入郵箱時(shí),可以使用正則表達(dá)式對(duì)輸入的格式加以驗(yàn)證,輸入時(shí)間、日期時(shí),必須嚴(yán)格按照時(shí)間、日期的格式等等,這樣做的目的是為了防止對(duì)用戶數(shù)據(jù)的破壞。
4總結(jié)
SQL注入攻擊是違背了數(shù)據(jù)與代碼分離原則導(dǎo)致的,它有兩個(gè)條件:一是用戶能夠控制數(shù)據(jù)的輸入,二是原本程序要執(zhí)行的代碼拼接了用戶輸入的數(shù)據(jù),并把數(shù)據(jù)當(dāng)作代碼執(zhí)行了。針對(duì)可能存在的SQL注入問(wèn)題,本文提出了使用預(yù)編譯語(yǔ)句,過(guò)濾URL中傳參等安全策略以消除SQL注入的存在。通過(guò)設(shè)計(jì)和實(shí)施合理的安全解決方案,注入攻擊是可以徹底杜絕的。
參考文獻(xiàn)
[1]吳翰清.白帽子講Web安全[M].北京:電子工業(yè)出版社,2014.
[2]張炳帥.Web安全深度剖析[M].北京:電子工業(yè)出版社,2015.
收稿日期:2015-11-10
作者簡(jiǎn)介:趙星(1990- ),男,安徽人,研究生,研究方向:網(wǎng)絡(luò)安全。
文章編號(hào):1674- 4578(2016)02- 0041- 02
中圖分類(lèi)號(hào):TP309.2
文獻(xiàn)標(biāo)識(shí)碼:A
Strategies for SQL Injection
Zhao Xing
(SoftwareCollege,NorthUniversityofChina,TaiyuanShanxi030051,China)
Abstract:For today’s rapid development of computer technology, the problem for people is facing more and more threat technology to the Website, the SQL injection events frequently occur. This article introduces the SQL injection and its hazards, and proposes the use of pre-compiled statement, URL filtering and other security policies to eliminate the existence of SQL injection which can further improve the site security.
Key words:cyber security; SQL injection; protection