白帽子講Web安全-服務器端應用安全

1.注入攻擊

    注入攻擊的本質,是把用戶輸入的數據當做代碼執行。兩個關鍵條件:一是用戶能夠控制輸入,二是原本程序要執行的代碼,拼接了用戶輸入的數據。

1.1SQL注入

    SQL注入,是構造SQL執行語句拼接在輸入參數中,從而執行SQL。若Web服務器開啓了錯誤回顯,則會披露敏感信息,爲攻擊者提供更大便利。

    SQL盲注,是在服務器沒有錯誤回顯時完成的注入攻擊。常見驗證方法是構造簡單的條件語句,根據返回頁面是否發生變化,來判斷SQl語句是否得到執行。

    Timing Attack,利用BENCHMARK()測試函數性能函數,讓同一個函數執行若干次,使得結果的返回結果比一般長,通過時間長短的變化,判斷注入語句是否執行成功。

1.2數據庫攻擊技巧

    1)常見攻擊技巧

    sqlmap:SQL注入可以猜測出數據庫的對應版本,驗證表名是否存在,進而驗證用戶名密碼等更多信息。這可通過sqlmap.py自動化注入工具幫助完成整個過程。鏈接:https://github.com/sqlmapproject/sqlmap

    讀寫文件:在MySQL中通過load_file()讀取系統文件,通過INTO DUMPFILE寫入本地文件,再通過LOAD DATA INFILE將文件導入創建的表中,最後通過一般的注入技巧直接操作表數據。其中INTO DUMPFILE適用於二進制文件,它會將目標文件寫入同一行內,也可使用INTO OUTFILE寫入文本文件。寫入文件的技巧常用於導出一個Webshell,爲攻擊者進一步攻擊做鋪墊。

    因此在設計數據庫安全方案時,可以禁止普通數據庫用戶具備操作文件的權限。

    2)命令執行

    利用用戶自定義函數UDF(User-Defined Functions)來執行命令。

    通過lib_mysqludf_sys提供的函數執行系統命令,主要是sys_eval()和sys_exec()。在攻擊過程中將lib_mysqludf_sys.so上傳到數據庫能訪問到的路徑下,在創建UDF後,使用sys_eval()等函數執行系統命令。

    因此在建立數據庫賬戶時應該遵循”最小權限原則“,儘量避免給Web應用使用數據庫的管理員權限。

    3)攻擊存儲過程

    xp_cmdshell:執行系統命令, xp_cmdshell在SQL Server 2000中默認是開啓的,但在2005及之後的版本默認被禁止了。若當前數據庫用戶擁有sysadmin權限,則可以使用sp_configure重新開啓。

    xp_regread:操作註冊表

    xp_servicecontrol:允許用戶啓動,停止服務

    xp_dirtree:允許獲得一個目錄樹

    xp_enumdsn:列舉服務器上的ODBC數據源

    xp_loginconfig:獲取服務器安全信息

    4)編碼問題

    注入攻擊中常用單引號,雙引號等特殊字符,基於字符集攻擊。如當MySQL使用GBK編碼時,0xbf27和0xbf5c會被認爲是一個字符(雙字節字符),而在進入數據庫之前。在Web語言中則沒有考慮到雙字節字符的問題,雙字節字符會被認爲是兩個字節。若攻擊者輸入“0xbf27 or 1=1”,經過轉義後會變成“0xbf5c27”(\的ASCII碼爲0x5c),原本存在的轉義符號在數據庫中會被吃掉。

    因此在設計時需要統一數據庫,操作系統,Web應用所使用的字符集,以避免各層對字符的理解存在差異。建議設置爲UTF-8是一個很好的方法。根據系統所使用的不同字符集來限制用戶輸入數據的字符允許範圍,以實現安全過濾。

    5)SQL Column Truncation

    在MySQL中有一個sql_mode選項,當MySQL的sql-mode設置爲default即沒有開啓STRICT_ALL_TABLES選項時,MySQL對於用戶插入的超長值只會提示warning,而不是error。這可能造成越權訪問。

1.3正確地防禦SQL注入

    防禦的關鍵:一是找到所有的SQL注入漏洞,二是修補這些漏洞。

    1)使用預編譯語句,綁定變量,SQL語句的語義不會發生改變,攻擊者無法改變SQL的結構。

    2)使用存儲過程,使用安全的存儲過程對抗SQL注入,儘量避免在存儲谷城內使用動態的SQl語句,若無法避免,則使用嚴格的輸入過濾或編碼函數來處理用戶的輸入數據。

    3)檢查輸入數據的數據類型,或者其他的數據格式及類型檢查。

    4)使用安全函數,參考數據庫廠商和OWASP ESAPI的實現。從數據庫自身角度來說,應使用最小權限原則,避免使用root,dbowner等高權限賬戶直接連接數據庫。

1.4其他注入攻擊

注入攻擊都有相同的特點,就是應用違背了“數據與代碼分離”的原則。

1)XML注入:與HTML注入類似,XML文件中用戶控制數據的輸入,程序拼湊了用戶輸入的數據。

2)代碼注入:代碼注入與命令注入都是由一些不安全的函數或方法引起,典型代表就是eval()和system()。

3)CRLF注入:CR是Carriage Return(ASCII 13, \r),LF是Line Feed(ASCII 10, \n)。\r\n表示換行,其十六進制編碼分別爲0x0d,0x0a。CRLF常被用作不用語義之間的分隔符,因此通過注入CRLF字符就可能改變原有的語義。

對抗注入攻擊,要牢記“數據與代碼分離原則”,在拼湊發生的地方進行安全檢查。

 

2.文件上傳漏洞

2.1文件上傳漏洞定義

    文件上傳漏洞是指用戶上傳了一個可執行的腳本文件,並通過此腳本文件獲得了執行服務器端命令的能力。文件上傳本身沒有問題,問題在於文件上傳後,服務器怎麼處理,解釋文件。

    文件上傳後導致的常見安全問題一般有:

    >上傳文件是Web腳本語言,服務器的Web容器解釋並執行了用戶上傳的腳本,導致代碼執行;

    >上傳文件是Flash的策略文件crossdomain.xml,黑客用以控制Flash在該域下的行爲;

    >上傳文件是病毒,木馬文件,黑客用以誘騙用戶或者管理員下載執行;

    >上傳文件是釣魚圖片或爲包含了腳本的圖片,在某些版本的瀏覽器中會被作爲腳本執行,被用於釣魚和欺詐。

 

    大多數情況下,文件上傳漏洞一般是指“上傳Web腳本能夠被服務器解析”的問題,即常說的Webshell問題。要完成這個攻擊滿足的條件如下:

    1)上傳的文件能夠被Web容器解釋執行,因此上傳後所在的目錄要是Web容器所覆蓋到的路徑;

    2)用戶能夠從Web上訪問這個文件;

    3)用戶上傳的文件若被安全檢查,格式化,圖片壓縮等功能改變了內容,也可能導致攻擊失敗。

2.2設計安全的文件上傳功能

    1)文件上傳的目錄設置爲不可執行。只要Web容器無法解析該目錄下的文件,即使攻擊者上傳了腳本文件,服務器本身也不會受到影響。

    2)判斷文件類型。判斷文件類型時,結合使用MIME Type,後綴檢查等方式,且強烈推薦白名單方式。對於圖片的處理,可以使用壓縮函數或者resize函數,在處理圖片的同時破壞圖片中可能包含的HTML代碼。

    3)使用隨機數改寫文件名和文件路徑。文件上傳若要執行代碼,則需要用戶能夠訪問到這個文件,如果使用隨機數改寫文件名和路徑則極大地增加攻擊的成本。

    4)單獨設置文件服務器的域名。由於瀏覽器同源策略的關係,一系列客戶端攻擊將失效。

 

3.認證與會話管理

    認證(Authentication),認證的目的爲了認出用戶是誰。

    授權(Authorization),授權的目的是爲了決定用戶能夠做什麼。

3.1密碼是最常見的認證手段

    密碼的優點是使用成本低,認證過程實現簡單,缺點是安全性不高,可能被猜解。

密碼策略:

    密碼長度方面:普通應用要求長度爲6位以上;重要應用要求長度爲8位以上。

    密碼複雜度方面:密碼區分大小寫字母;密碼爲大寫字母,小寫字母,數字,特殊符號中兩種以上的組合;不要有連續性的字符;儘量避免出現重複的字符。

密碼保存:

    密碼必須以不可逆的加密算法,或者單向散列函數算法,加密後存儲在數據庫中。

3.2多因素認證

    除了密碼外,手機動態口令,數字證書,寶令,支付盾,第三方證書等都可用於用戶認證。多因素認證提供了攻擊的門檻,提高了攻擊成本。

3.3Session與認證

    密碼與證書等認證手段,一般僅僅用於登錄的過程,認證成功後,需要替換一個對用戶透明的憑證,即SessionID。當用戶登錄完成後,在服務器端會創建一個新的會話,會話中會保存用戶的狀態和相關信息。

    Session劫持:通過竊取用戶SessionID後,使用該SessionID登錄進目標賬戶的攻擊方法,此時攻擊者實際上使用了目標賬戶的有效Session。

    Cookie劫持:若SessionId是保存在Cookie中,攻擊者竊取Cookie中的SessionId,這種攻擊稱爲Cookie劫持。

3.4Session Fixation攻擊

    攻擊過程:用戶X(攻擊者)獲取打一個未經認證的SessionID,然後將這個SessionID交給用戶Y去認證,Y完成認證後,服務器並未更新此SessionID的值,所以X可以直接憑藉此SessionID登錄進Y的賬戶。

    解決方案:在登錄完成後,重寫SessionID。若使用sid則需要重置sid的值,若使用Cookie則需要增加或改變用於認證的Cookie值。

3.5Session保持攻擊

    一般來說,Session是有生命週期的,當用戶長時間未活動後,或用戶點擊退出後,服務器會銷燬Session。若攻擊者一直持有一個有效的Session,如間歇性地刷新頁面,以告訴服務器這個用戶仍然在活動,攻擊者就能通過此有效Session一直使用用戶的賬戶。

    解決方案:

    1)在一定時間後,強制銷燬Session。這個時間可以是從用戶登錄的時間算起,設定一個閾值,如3天后強制Session過期。

    2)當用戶客戶端如用戶的IP,UserAgent等信息發生變化時,要求用戶重新登錄。

    3)若同一用戶可以同時擁有幾個有效Session,則當用戶再次登錄時,攻擊者所保持的Session將被踢出。

3.6單點登錄(SSO)

    單點登錄(Single Sign On):用戶只需要登錄一次,就可以訪問所有的系統。從用戶體驗看,SSO讓用戶的使用更加方便,但從安全角度看,SSO把風險集中在單點上,有利有弊。優點在於風險集中化,缺點在於單點一旦被攻破,影響範圍大。

 

4.訪問控制

    權限控制/訪問控制:某個主體(subject)對某個客體(object)需要實施某種操作(operation),而系統對這種操作的限制就是權限控制。

    常見訪問控制分爲:基於URL的訪問控制,基於方法(method)的訪問控制,基於數據的訪問控制。

4.1垂直權限管理

    垂直權限管理:訪問控制實際上是建立用戶與權限之間的對應關係。基於角色的訪問控制(Role-Based Access Control)簡稱RBAC,即垂直權限管理。用戶<=>角色<=>權限。

    在配置權限時,應當使用“最小權限原則”,並使用“默認拒絕”的策略,只對有需要的主體單獨配置“允許”策略,這在很大程度上能夠避免發生越權訪問。

4.2水平權限管理

    水平權限管理問題:在RBAC這種基於角色的訪問控制模型下,系統只會驗證用戶A是否屬於角色RoleX,而不會判斷用戶A是否能訪問只屬於用戶B 的數據。導致越權訪問。水平權限問題出在同一個角色上,沒有對角色內的用戶做細分,也沒有對數據的子集做細分,缺乏一個用戶到數據之間的對應關係。因此又稱基於數據的訪問控制。

    解決方案:

    1)引入用戶組,一個用戶組的數據只屬於該組內的成員,只有同一個用戶則的成員才能實現對這些數據的操作。

    2)實現規則引擎,將訪問控制的規則寫在配置文件中,通過規則引擎對數據的訪問進行控制。

4.3OAuth

    OAuth是一個在不提供用戶名和密碼的情況下,授權第三方應用訪問Web資源的安全協議。

 

5.加密算法與隨機數

5.1常見的加密算法:

    1)分組加密算法:基於分組(block)進行操作,根據算法的不同,每個分組的長度可能不同。分組加密算法的代表有DES,3-DES,Blowfish,IDEA,AES。

    2)流密碼加密算法:每次只處理一個字節,密鑰獨立於消息之外,兩者通過異或實現加密與解密。流密碼加密算法的代表與RC4,ORYX,SEAL。流密碼加密算法存在“Reused Key Attack”和“Bit-flipping Attack”等攻擊方式。

    Reused Key Attack:使用同一個密鑰進行多次加/解密。在這種攻擊下,攻擊者不需要知道密鑰,就可以還原出明文。

    Bit-flipping Attack:攻擊者在不知道明文的情況下,通過改變密文,使得明文按其需要的方式發生改變的攻擊方式。解決方案是驗證密文的完整性,最常見的方法是增加帶有KEY的MAC。

5.2ECB模式的缺陷

    分組加密算法常見的加密模式有:ECB, CBC, CFB, OFB, CTR。

    對於ECB模式(電碼簿)來說,改變分組密文的順序,將改變解密糊的明文順序;替換某個分組密文,解密後該對於分組的明文也會被替換,而其他分組不受影響。當需要加密的明文多於一個分組的長度時,應該避免使用ECB模式。

5.3Padding Oracle Attack

    該漏洞針對CBC模式,通過對padding bytes的嘗試,還原明文,或者構造出任意明文的密文。

    CBC加密過程中,若最後一個分組的消息長度沒有達到block的大小,則需要填充一些字節,被稱爲padding。在解密完成後,若最後的padding值不正確,解密程序會拋出異常(padding error),利用應用的錯誤回顯,攻擊者往往可以判斷出padding是否正確。

    Padding Oracle Attack的關鍵在於攻擊者能夠獲知解密的結果是否符合padding。在實現和使用CBC模式的分組加密算法時注意即可。

5.4密鑰管理

    密碼學的基本原則:密碼系統的安全性應該依賴於密鑰的複雜性,而不應該依賴於算法的保密性。

    密碼管理中最常見的錯誤,就是將密鑰硬編碼在代碼裏。

    對Web應用來說,常見做法是將密鑰包括密碼保存在配置文件或者數據庫中,在使用時由程序讀出密鑰並加載進內存。密鑰所在的配置文件或數據庫需要嚴格的控制訪問權限,同時也要確保運維或DBA中具有訪問權限的人越少越好。

5.5隨機數

    避免使用弱僞隨機數算法,不要把時間函數當成隨機數使用。

    在重要或敏感的系統中,一定要使用足夠強壯的隨機數生成算法:

        Java:使用java.security.SecureRandom;

        Linux:使用/dev/random或/dev/urandom;

        PHP5.30及其之後版本:若支持openSSL擴展,可以直接使用函數來生成隨機數。

 

6.Web框架安全

1)MVC框架安全:從數據的流入來看,用戶提交的數據先後流經了View層,Control,Model層,數據的流出則反過來。在MVC框架中,通過切片,過濾器方式,往往能對數據進行全局處理,這爲設計安全方案提供了極大的便利。在正確的地方,做正確的事情。

2)模板引擎與XSS防禦: 在View層可以解決XSS問題。使用“輸出編碼”的防禦方法更加合理,針對不同上下文的xss攻擊場景,使用不同的編碼方式。

3)Web框架與CSRF防禦:CSRF攻擊的目標,一般都會產生寫數據操作的URL,而讀數據並不是CSRF攻擊的目標。僅使用HTTP POST不足以對抗CSRF,但POST的使用有利於保護token,而security token的私密性是防禦CSRF攻擊的基礎。

    完整的CSRF防禦方案,對於Web框架需要有以下幾處改動:

    >在Session中綁定token。若不能保存到服務器端Session中,則可以替代爲保存到Cookie中;

    >在form表單中自動填入token字段;

    >在Ajax請求中自動添加token,這可能需要已有的Ajax封裝實現的支持;

    >在服務器端對比POST提交參數的token與Session中綁定的token是否一致,以驗證CSRF攻擊。

4)HTTP Headers管理:在Web框架中,可以對HTTP頭進行全局化的處理。

    對抗針對HTTP返回頭的CRLF注入的方案只需要在HTTP頭value中編碼所有的\r\n即可。

    針對30X返回碼的HTTP Response,瀏覽器會跳轉到Location指定的URL,這容易實施釣魚或詐騙。管理跳轉目的地址:

    >若Web框架提供統一的跳轉函數,則可以在跳轉函數內部實現一個白名單,指定跳轉地址只能在白名單中;

    >控制HTPP的Location字段,限制Location的值只能是哪些地址,也能起到同樣的效果,其本質還是白名單。

    對抗ClickJacking,在Web框架中配置X-Frame-Options,或者在頁面的HTTP Response中添加。

    CookieJacking:在框架中提供的一個統一的設置cookie函數中設置,或者在頁面返回頭中配置實現。

 

7.應用層拒絕服務攻擊

    7.1DDOS

    DDOS(Distributed Denial of Service)又稱分佈式拒絕服務,本是利用合理的請求造成資源過載,導致服務不可用。常見的DDOS攻擊有SYN flood,UDP flood,ICMP flood等。

    正常情況下,TCP三次握手過程如下:

    1)客戶端向服務端發送一個SYN包,包含客戶端使用的端口號和初始序列號x;

    2)服務器端收到客戶端發送來的SYN包後,向客戶端發送一個SYN和ACK都置位的TCP報文,包含確認號x+1和服務器端的初始序列號y;

    3)客戶端收到服務器端返回的SYN+ACK報文後,向服務器端返回一個確認號爲y+1,序號爲x+1的ACK報文,一個標準的TCP連接完成。

 

    SYN flood攻擊:首先僞造大量的源IP地址,分別向服務器端發送大量的SYN包,此時服務器端會返回SYN/ACK包,而僞造IP不會應答,服務器端沒有收到僞造IP的迴應,會重試3-5次並等待一個SYN Time(一般爲30s-2分鐘),若超時則丟棄這個連接。攻擊者大量發送這個僞造IP地址的SYN請求,服務器端會小號大量資源(CPU和內存)來處理這種半連接,同時還要不斷對這些IP進行SYN/ACK重試,最後的結果就是服務器無暇理睬正常的連接請求,導致拒絕服務。

    解決方案:SYN Cookie/SYN Proxy,safereset算法。SYN Cookie主要是爲每一個IP地址分配一個Cookie,並統計每個IP地址的訪問頻率,若短時間內收到大量的來自同一個IP地址的數據包,則認爲受到攻擊,之後來自這個IP地址的包都會被丟棄。

    7.2應用層DDOS

    CC攻擊:對一些消耗資源較大的應用頁面不斷髮起正常的請求,以達到消耗服務端資源的目的。在Web應用中,查詢數據庫,讀寫硬盤文件等操作,相對都會消耗較多的資源。

    資源耗盡攻擊:SlowIoris以極低的速度向服務器發送HTTP請求,由於Web Server對於併發的連接數都有一定的上限,若是惡意佔用住這些連接不釋放,WebServer無法接收新的請求,導致拒絕服務。此類拒絕服務攻擊的本質,實際上是對有限資源的無限制濫用。

    HTTP POST DOS:在發送HTTP POST包時,指定一個非常大的Content-Length值,然後以很低的速度發包,保持住這個連接不斷開,這樣當客戶端連接數達到上限後,佔用住了WebServer的所有可用連接,從而導致DOS。

    Server Limit DOS:WebServer對HTTP包頭都有長度限制,攻擊者通過XSS攻擊,惡意往客戶端寫入一個超長的Cookie,則該客戶端在清空Cookie前將無法再訪問該Cookie所在域的任何頁面,導致DOS。

    ReDOS:正則表達式是基於NFA(Nondeterministic Finite Automaton)的,它是一個狀態機,每個狀態和輸入符號都可能有許多不同的下一個狀態,正則解析引擎將遍歷所有可能的路徑直到最後。當用戶惡意構造輸入時,這些有缺陷的正則表達式就會消耗大量的系統資源,從而導致整臺服務器的性能下降,表現的結果是系統速度很慢,有的進程或服務失去響應,導致DOS。

 

8.Web Server安全

8.1Apache安全

    1)檢查Apache的Module安裝情況,根據“最小權限原則”,儘可能減少不必要的Module,對於要使用的Module則檢查其對應版本是否存在已知的安全漏洞。

    2)指定Apache進程以單獨的用戶身份運行,這需要爲Apache單獨建立一個user/group。避免以高權限身份運行Apache。

    3)保護好Apache Log。一般來說攻擊者入侵成功後,第一件事情就是清除入侵痕跡,修改,刪除日誌文件,因此access log應當妥善保管,如實時地發送到遠程的syslog服務器上。

8.2Nginx安全

    Nginx需要注意軟件本身的安全,及時升級軟件版本。

8.3jBoss遠程命令執行

    JBoss是J2EE環境中一個流行的Web容器,但其在默認安裝時提供的部分功能配置不當,可能直接造成遠程命令執行。

    JBoss在默認安裝時有一個JMX-Console管理後臺,它提供給管理員配置MBeans等強大功能,且沒有任何認證,攻擊者通過8080端口訪問/jmx-console能夠進入該管理界面。

8.4Tomcat遠程命令執行

    Apache Tomcat默認運行在8080端口,管理員也可以再Tomcat Manager中部署war包,但這需要有manager權限。雖然Tomcat後臺有密碼認證,但建議刪除這一後臺,從安全角度來看,這增加了系統的攻擊面。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章