防注入攻擊指南

來源:互聯網
上載者:User
作者: 風清揚 出處: E代V4
近段時間以來的網路攻擊似乎多了起來,很多網站無故被黑甚至換掉首頁。絕大多數網站被攻擊的原因大都是由於網站程式上的漏洞,由攻擊者得到WebShell後進而提升許可權得到伺服器主機許可權。然而得到WebShell的途徑也就集中到SQL Injection的攻擊手法上。什麼是SQL 插入式攻擊呢?來自官方的詮釋:當應用程式使用輸入內容來構造動態 SQL 陳述式以訪問資料庫時,會發生 SQL 插入式攻擊。如果代碼使用預存程序,而這些預存程序作為包含未篩選的使用者輸入的字串來傳遞,也會發生 SQL 插入式攻擊。SQL 注入可能導致攻擊者能夠使用應用程式登入在資料庫中執行命令。如果應用程式使用特權過高的帳戶串連到資料庫,這種問題會變得很嚴重。換句話說:SQL 插入式攻擊利用易受攻擊的資料存取碼,並允許攻擊者在資料庫中執行任意命令。如果應用程式使用資料庫中不受限制的帳戶,由於攻擊者可以更自由地執行查詢和命令,因此受到的威脅會更大。值得注意的是,傳統的安全措施(如使用 SSL 和 IPSec)不能防止 SQL 插入式攻擊。

使資料存取碼容易受到 SQL 插入式攻擊的常見漏洞包括:本文轉載出處E代時光E3i5.com

· 弱輸入驗證

· 在不使用型別安全的參數時動態構造 SQL 陳述式

· 使用特權過高的資料庫登入

要應對 SQL 插入式攻擊,請務必注意:

· 限制和淨化輸入資料

· 使用型別安全的 SQL 參數進行資料訪問。這些參數可以與預存程序一起使用,也可以是動態構造的 SQL 命令字串。參數執行類型和長度檢查,並同時確保注入資料庫中的代碼被視為文本資料(而非可執行語句)本文轉載出處E代時光E3i5.com

· 使用在資料庫中具有有限許可權的帳戶。理想情況下,只應向資料庫中的選定預存程序授予執行許可權,且不提供直接的表格存取權限

· 驗證輸入內容的類型、長度、格式和範圍。如果您不希望獲得數值,則不要接受它們。應該考慮輸入內容來自何處。如果它來自受信任源,而且您知道已針對該來源執行過徹底的輸入驗證,則可以選擇在資料存取碼中忽略資料驗證。如果資料來自不受信任源或者用於深層防禦,則資料存取方法和組件應該驗證輸入。
綜上所述。

如何很好的預防SQL Injection攻擊就成了現在安全防護的一個重點:本文轉載出處E代時光E3i5.com

由於ASP的易學性和普遍性,很多網站都選擇了使用ASP語言來構建自己的Web網站。ASP語言為指令碼級程式設計語言,是以VBScript或JAVAScript。更多的網站選擇了VBScript指令碼作為編寫的基礎。然而很不幸的一點是VBScript對異常的捕捉(Debug)和資料類型的聲明要求都相對JAVAScript要寬鬆得很多,沒有強制要求,這樣帶來了方便也帶來的隱患。(由於一些程式員的習慣,在使用VBScript編寫ASP程式時常常忽略了對異常的捕捉(Debug)和資料類型的聲明)所以在防止WEB注入攻擊的方面就顯得"心有餘,而力不足"。回到我們的話題:談起SQL Injection,我們首先想到的是尋找注入點。很多情況下Web方式的注入都是以ASP request 對象 為主。

quote: 例(1):http://target/index.asp?id=10

杜絕SQL 注入式攻擊的第一步就是採用各種安全手段監控來自 ASP request 對象 (Request、Request.QueryString、Request.Form、Request.Cookies和 Request.ServerVariables) 的使用者輸入,以確保 SQL 指令的可靠性。像其他一些來自 ASP request 對象 (Reques、Request.QueryString、Request.Form、Request.Cookies和 Request.ServerVariables) 的使用者輸入的攻擊方法的方法,大致都集中在指令碼期望的輸入變數是數字變數 (ID) 上(如例1),當然我們不能只看數字變數:本文轉載出處E代時光E3i5.com

quote: 例(2):http://target/index.asp?username=風清揚

如例(2)中所引用的變數是以字串變數傳遞。
通過URL傳遞變數的方式大概就以以上兩種方式傳遞。第一,為數字變數;第二,為字串變數。SQL Injection漏洞的出現,主要原因在於程式員的疏忽和大意,未採取過濾或是過濾不嚴密都會留給攻擊者攻擊的途徑。下面就具體的介紹一下如何防範:
· 主動防護本文轉載出處E代時光E3i5.com
何為主動防護?主動防護是指並非去對非法字串進行過濾,而是主動的給出字串輸入範圍來防止SQL Injection的攻擊。很多網站的程式上都是以對來自 ASP request 對象的過濾上入手,僅僅被動的對一些已知的攻擊字元進行過濾。比如以下程式:程式塊(1)

quote: function HTMLEncode(Str)

Str=replace(Str,";",";")

Str=server.htmlencode(Str)

Str=replace(Str,"'","'")

Str=replace(Str,"--","--")

Str=replace(Str,"/","/")

Str=replace(Str,vbCrlf,"
")

HTMLEncode=Str

end function

以上程式塊轉自某論壇程式,其過濾了分號,<,>,單引號,--,/,&等特殊字元以及對軟斷行符號的轉換。試想一下,如果以上的過濾有不嚴密的地方,那就是功虧於潰了。如程式塊(1)對形如"../"的字串沒有過濾,在一些單表填寫中可能會造成一些不必要的麻煩和隱患。如果我們採取主動防禦的辦法,以限制輸入字元集為主,使用效率更高的Regex,如[0-9a-zA-Z]:程式塊(2)

quote: 漢字的正則式:/[^/x00-/xff]/g

Email的正則式:/^[/w.-]+@([0-9a-z][/w-]+/.)+[a-z]{2,3}$/I

由數字、26個英文字母或者底線組成的字串:^/w+$

正確的URL:^[a-zA-z]+://(/w+(-/w+)*)(/.(/w+(-/w+)*))*(/?/S*)?$

正整數:^[0-9]*[1-9][0-9]*$

全數字格式:/[^/d]/g

應用:

Function CheckExp(patrn, strng)

Dim regEx, Match

Set regEx = New RegExp

regEx.Pattern = patrn

regEx.IgnoreCase = true

regEx.Global = True

Matches = regEx.test(strng)

CheckExp = matches

End Function

例子:

如果str為由數字、26個英文字母或者底線組成的字串,則返回True,否則返回False。

使用主動的限制輸入的方式來限制字元的輸入類型將對危險字元的過濾的效率上有很大的提高,相對的安全性也大大提高了。僅僅過濾非法的字元,HU~誰知道究竟哪些字元在哪種情況下屬於非法字元呢?所以還是要主動,積極的去做過濾工作。補充一下,我們所提倡的限制輸入字元集,而並非不讓大家使用字元限制,在特定的條件下,過濾字元也會比限制輸入範圍要好得多。大家要學會靈活運用。

· 資料庫的查詢方式本文轉載出處E代時光E3i5.com
發現有很多網站進行資料庫查詢的時候,還是使用rs.eof 或rs.bof作為查詢結果的判斷。RS(遊標)的eof和bof屬性分別表示為遊標在資料末端或資料首端,所表示的意思為沒有尋找到相應的資料。大多數網站對使用者登陸,使用者註冊等過程的對資料庫現有資料的查詢時,都採用的以下的方式:程式塊(3)

quote:

如程式塊(3)顯示的程式段,如果變數username和password由於程式員的疏忽或其他原因沒有進行過濾或是過濾不嚴密,將會造成SQL Injection的漏洞。只是使用rs.bof or rs.eof作為資料庫資料遍曆的依據是很不安全的。從安全形度出發,我們應當使用如下的方式作為判斷的依據:程式塊(4)本文轉載出處E代時光E3i5.com

quote:

有了if rs("username")=username then這個語句的存在(紅色部分),使得驗證時不得不多了一次檢測,不僅僅只是滿足SQL查詢語句的正確性,也使得查詢得到的資料與輸入的資料相一致時才給出正確的判斷。

· 資料庫其他方式查詢的檢測
想必很多網站問題出現都是在這個環節,其實這個環節的問題是最多的也是最容易解決的。很多程式員由於沒有良好的編程習慣,只實現功能,並不注意其程式的安全性,或者對更細節的東西沒有注意到,這也是引起網站程式被攻擊的一個方面。具體的問題主要集中在以下的幾個方面:
1. 查詢的返回欄位值
很多朋友都喜歡使用以下的語句進行查詢工作,如程式塊(5)

quote: Sql="select * from [user] where uid="&id&" order by uid desc"

簡單看來這句語句如果在數字變數 (ID)上有限制的話,整個語句可能是很安全的。但是使用select * 來查詢全部欄位有些時候會帶來更多的安全問題。我很推薦,尤其是個人編寫的程式中盡量少的使用select *來對資料表中的欄位進行查詢,做到將要用哪個欄位就查詢哪個欄位的要求。
2. 數字格式的變數檢測本文轉載出處E代時光E3i5.com
這個應該是ASP程式中使用最多的變數類型,很多人都覺得使用字串型的變數在過濾的時候很難辦,所以很多都是使用數字ID來作為變數的傳遞。而往往過多的使用卻使程式員很容易忘記某個數字ID是否做過變數類型的檢測。在前面我們提到過,VBScript指令碼對資料類型的聲明沒有其他語言的的嚴密。在Java中定義一個新的變數首先就是定義變數的資料類型如:

quote: 1. String a="good day";

2. Int a=3;

3. Public static string MadeThisExample(string pwd, int sold)

{

String key=string.Concant(pwd, sold);

String result=LoopAddr("MADETHISOUT",key);

Return result;

}

有了嚴格的資料類型,我們就可以根據不同的資料類型做不同的過濾或者是異常的捕捉。然而ASP安全在這一點上是最沒有優勢的。如以下的ASP程式片段 :本文轉載出處E代時光E3i5.com

quote: Dim str_a,int_b

Str_a=request("str_a")

Int_b=request("int_b")

以上的程式片段中我們可以看到我們預期想得到的字串str_a,整形數字int_b,然而在ASP可以定義無資料類型的資料,這就使得程式的編寫者不得不注意要強制一些變數的資料類型,並做異常捕捉。比如整形變數int_b作為整形的判斷:

quote: Dim int_b

Int_b=cint(request("int_b"))

這樣以來,int_b被強製為整形變數,當int_b為非整形時,程式會產生錯誤:"字元類型不符"
我們在對數字變數進行判斷的時候一般都採用以下的幾個函數來進行判斷:

quote: Cint,Clng,IsNull,IsEmpty, IsNumeric等等

在我們常用的程式中,以上幾個判斷函數就足夠了,對所有request對象資料類型為整形的變數進行強制整形的操作。甚至可以寫出一個通用的校正函數來進行全域校正。關於校正函數,這裡就不提了,在網上有很多朋友寫出過一些過濾函數,大家可以搜尋一下作為借鑒。

3. 字串格式的校正本文轉載.出處E代時光E3i5.com
使用字串作為變數就沒有類似象整形變數判斷的函數咯,是不是對這樣的變數感到很棘手。在無法變通的情況下只能去硬著頭皮去進行死板的非法字元的過濾,感覺應該過濾的東西太多了,更鬱悶的是要過濾的字元還有使用者在使用,這樣的情況怎麼辦?都怪自己當初寫程式的時候沒注意,等發現問題的時候已經有不少使用者的資料中存在即將要屏蔽的字元了。其實類似字串格式的變數進行校正的方式也和前面所說過的方法差不多。
(一)採用給定字元集合的方式,只能輸入指定的字元。具體方法請查看程式塊(2)
(二)採用遊標資料校正,方法類似使用者登陸的寫法。例如:程式塊(6)

quote: Dim sql,rs

Dim type

Type=request("stype")

sql="select articleid,articletypes,articletitle, articlewrter, Adddate from [article] where articletypes ='"&type&'" order by articleid desc"

Set rs=Conn.Execute(sql)

if not(rs.eof or rs.bof) then

if rs("articletype")=type then

文章列表操作

else

變數錯誤操作

end if

end if

如程式塊(6)所示,不論字串變數的內容是什麼,只要不能通過if rs("articletype")=type then的檢測都被視為這個字串變數的內容是非法的。如此操作將比單一的去過濾非法的字元要好得多。鬼曉得不定哪一天又出現了什麼新的注入方法,即使屏蔽掉一些特殊字元也可以利用其他方法進行注入的。

4. 變數的長度後台檢測本文轉載出處E代時光E3i5.com
為什麼還要在已經檢測過的程式後面加長度檢測呢?(呵呵,有些朋友還是不放心嘛。開玩笑De)這也取決於程式需要,前台指令碼級的限制也只是局限於一個用戶端的過濾,作為攻擊者完全可以通過某些手段來突破用戶端限制,那麼防範這樣的攻擊,我們只能從服務端程式入手,對單表限制的長度再加一次檢測,其一可以防止資料寫入資料庫時由於字串長度過大而寫資料庫失敗的問題;其二可以更有效防範SQL Injection攻擊。限制變數長度:程式塊(7)

quote: 我們使用len() 函數來判斷字串的長度,對於超過長度要求的或重新付值或返回錯誤資訊,並終止程式向下進行。如:

5. 防止遠程注入的問題
這個情況真的是容易讓人遺忘。包括動網論壇也出現如此情況哦,比如檔案上傳的資料處理檔案沒有對遠程資訊和不受信任來源的資訊進行校正,再加上校正程式上的一點點小BUG,伺服器上的一點點安全配置問題,整個網站就被"黑"了。相信很多朋友都身受其害,不光光是論壇程式,其他一些網站內的資料處理程式,既沒有許可權驗證,也沒有對不信任地區的請求加以過濾,這就使得我不知道密碼也能改你網站頁面的情況時有發生了。要提醒一點的是,很多朋友怕自己的網站被黑,將使用的免費程式的後台登陸地址稍做修改就以為萬事大吉了,尤其是登陸頁面和資料處理頁面不在同一頁面的,而且資料處理頁面沒有對不信任地區的請求加以過濾的,即使你改過登陸口,攻擊者還是可以偽造資料進行登陸。尤其是一些非URL上的注入攻擊,比如單表上的SQL注入,僅僅做頁面單表的指令碼級過濾,而攻擊者在探索資料處理頁面上沒有對不信任地區的請求加以過濾時,一般都會在本地偽造頁面進行非法語句的提交,那是防不勝防哦。以下再次給出防止遠程注入的代碼:程式塊(8)本文轉載出處E代時.光E3i5.com

quote:

· 有關資料安全的一點說明
還是要提一下,有經濟能力使用SQL資料庫+伺服器整機的朋友注意,資料庫帳戶的開設許可權要盡量接近理想情況下,只應向資料庫中的選定預存程序授予執行許可權,且不提供直接的表格存取權限,以及對伺服器一些特殊的命令和檔案進行刪除或改名。
使用ACCESS資料庫的使用者,應該注意保護CONN.ASP檔案的安全性,最好使用異常捕捉將資料庫連接的錯誤資訊屏蔽掉。以防止敏感資訊的泄露。如:程式塊(9)

quote:

另外使用ACCESS資料庫的朋友要注意資料庫的防下載防護,步驟為:
1. 使用ASP程式向資料庫寫入OLE資料,寫入內容為<%
2. 將資料庫改名為ASA結尾的檔案,由於IIS伺服器對ASA檔案的保護要比ASP檔案更高,所以我們選擇ASA檔案作為ACCESS資料庫檔案的結尾副檔名。
3. 在改好的資料庫名中加入一個#號,目的是防止其他程式出現SQL Injection問題時,阻止"跨庫查詢"的操作。

最後更加不要忘記將網站程式的安裝檔案刪除,否則被"黑"是應該滴,因為這樣才會長記性嘛。

· 後記
看到近來網路上的不平靜,感覺這篇文章寫出來能對各位站長有所協助或是提醒。抓緊時間看看你的站上的程式,說不定哪個不起眼的頁面上就存在著以上的問題。HU~更加擔憂的是國內的一些門戶網站也存在著類似的問題,甚至一些安全公司,國家級機構的網站。形式似乎迫在眉睫,管理員們該工作了,舉手之勞。本文轉載出處E代時光E3i5.com
有什麼疑問的朋友請到www.e3i5.com詢問。謝謝!

參考文獻:
1.http://www.securiteam.com/securityreviews/5DP0N1P76E.html
2.http://msdn.microsoft.com/msdnmag/issues/04/09/SQLInjection/default.aspx
3.http://www.4guysfromrolla.com/webtech/061902-1.shtml
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.