回味ddos

nsfocus那弄來的
DoS 是英文Denial of Service 的縮寫,從字面上看一目瞭然?D?D無法提供服務、拒絕服務,DDoS就是分佈式(Distributed)的DoS***。DDoS與DoS的主要區別在於所謂的"分佈式",意味着***者控制了一定數量的殭屍主機(zombies)所發起的***。
隨着Internet應用以及網絡帶寬的高速增長, DoS/DDoS***發生的頻度越來越高。出於商業競爭、打擊報復和網絡敲詐等各種目的,幾乎是任何掌握一定帶寬資源的人,只要從網絡上下載***程序就可以發起DoS/DDoS***。由於實施容易、追查困難,同時由於法律規範不夠健全,DoS/DDoS***已經成爲網絡管理員以及運營維護人員的頭號大敵。
人們最常見的是利用TCP/IP協議設計缺陷發起的***,其中最爲著名的***手段例如SYN Flood***相信很多人已經耳熟能詳了。由於幾乎所有的網絡應用服務都是基於TCP協議或者UDP協議,因此***的技術手段也可以按照TCP和UDP來描述。
下面將講述目前常見的***方式,在描述***方法的時候同時分析防護及其侷限性。
常見的***方法分析
1. SYN Flood***。這是最早出現,也是最有效、最常見的***方式。
首先來看一下正常情況下一個TCP連接的建立過程:客戶端向服務器發送SYN報文à服務器迴應SYN/ACK報文à客戶端迴應ACK報文,至此連接纔算建立。這個過程就是所謂的"三次握手"。在服務器收到SYN報文並回應SYN/ACK報文之後,會啓動一個時鐘等待第3次握手的ACK報文到達,並將此連接放入一個"半開連接"列表中。如果這個時鐘超時(一般來說這個時鐘是分鐘的數量級),也就是說第3次握手的ACK報文無法到達服務器,那麼服務器會重試發送SYN/ACK報文給客戶端(重試的次數在3~5次,各種主機操作系統不同)。
惡意的***者利用***程序模擬這種情況的發生:僞造源IP地址向服務器發起相當數量的連接請求。由於是僞造源IP,服務器迴應的SYN/ACK報文可能無法達到該IP地址對應的主機。經過短暫的時間,服務器上就將出現大量的半開連接。如果***程序發包速率相對較小的話,服務器的半開連接隊列將被充滿而無法接受新的SYN請求,這時候的表現就是正常客戶端訪問服務器會被立即中斷,但此時服務器的負載並不很高。如果***程序發包速率很高的話,服務器上會迅速積累大量的SYN_RECV狀態,系統負載很高,甚至鼠標鍵盤無法響應,此時從客戶端訪問服務器會有長時間的等待。因此,當netstat ?Can發現服務器上有大量的SYN_RECV狀態的時候就可以判定遭受SYN Flood***了。
早期***工具(例如synkiller、 xdos和hgod等)通常是發送64字節的TCP SYN報文,而主機操作系統在發起TCP連接請求時發送SYN 報文是大於64字節的。因此,可以在關鍵節點上設置策略過濾64字節的TCP SYN報文(某些宣傳具有防護SYN Flood***的產品就是這麼做的)。隨着工具的改進,發出的TCP SYN報文完全模擬常見的通用操作系統,並且IP頭和TCP頭的字段完全隨機,這時就無法在設備上根據特定的規則來過濾***報文。
對於部屬在網絡前端的狀態檢測防火牆,SYN Flood***幾乎是致命的。通常***者的目標只是一個服務器,可是當防火牆上開始累積大量SYN_RECV狀態的Session直至防火牆 Session被完全充滿時,所有到達其他未被***的服務器的連接請求也無法通過,最終整個網絡癱瘓。
爲了避免SYN Flood***的影響,一個想法是驗證發起SYN請求的源IP地址是否真實。部署在服務器前端的防火牆接收到SYN報文的時候,主動迴應SYN/ACK。如果是正常的連接請求客戶端就會迴應ACK報文到達防火牆上,經過驗證之後,防火牆再模擬客戶端向服務器發起SYN請求,如圖1所示。這種做法將3次握手演變成了6次握手過程,這樣僞造源IP的連接請求就無法到達服務器上,從而服務器不會受到任何的影響。目前,很多操作系統/防火牆已經實現了類似的算法,例如著名的Linux SYN Cookie。
顯然,SYN Cookie可以在理論上解決僞造源IP的SYN Flood***。但是,這個算法在實際環境中有很多問題。假設***流量在50Mbps,如果完全做SYN Cookie的話就意味着要回應50Mbps左右的流量。這樣做首先防火牆可能不堪重負最終無法響應,其次防火牆前端的網絡設備將充斥着大量無用的垃圾流量,假設這個網絡的正常流量本身在50Mbps 左右,再加上防火牆主動迴應的50M流量,帶寬基本充滿,前端的網絡設備將開始出現隨機丟包,***者的目的也就達到了。在某些情況下,由於防火牆前端的網絡設備要轉發大量的數據包,如果配置不當甚至可能由於負載很高而無法正常工作。在實際情況中,我們發現有些交換機在大流量DoS***的時候無法響應,或者進入了共享模式(即將接收到的數據包往所有的交換機端口廣播)。
改進的算法是有選擇的進行主動迴應。在這裏引入了網絡時代的"2/8原則",即 80%的人通常只會集中訪問20%的服務器。部署在服務器前端的設備可以學習哪些客戶端IP建立連接的成功率是比較高的,在***發生的時候儘可能優先保證這些客戶端IP能和服務器正常建立連接。這樣就將***帶來的影響降到最低點。同時,還可以輔助以其他的手段來判斷是否主動迴應。例如,在服務器看來一個客戶端的IP包的TTL值是比較固定的(除非路由發生了大的改變),而***程序很難正確計算TTL值,因此在***發生的當時可以通過判斷TTL值來計算是否主動迴應。
SYN Flood***即使到今天仍然是DoS/DDoS***的主角,並且越來越多地與其他***方式混合在一起使用,使得抗拒絕服務***的任務更加複雜。
2. ACK Flood***。在TCP連接建立之後,所有的數據傳輸TCP報文都是帶有ACK標誌位的,主機在接收到一個帶有ACK標誌位的數據包的時候,需要檢查該數據包所表示的連接四元組是否存在,如果存在則檢查該數據包所表示的狀態是否合法,然後再向應用層傳遞該數據包。如果在檢查中發現該數據包不合法,例如該數據包所指向的目的端口在本機並未開放,則主機操作系統協議棧會迴應RST包告訴對方此端口不存在。通常狀態檢測防火牆所做的事情與此類似,只不過防火牆只攔截非法的數據包,而不主動迴應。
對比主機以及防火牆在接收到ACK報文和SYN報文時所做動作的複雜程度,顯然ACK報文帶來的負載要小得多。所以在實際環境中,只有當***程序每秒鐘發送ACK報文的速率達到一定的程度,才能使主機和防火牆的負載有大的變化。當發包速率很大的時候,主機操作系統將耗費大量的精力接收報文、判斷狀態,同時要主動迴應RST報文,正常的數據包就可能無法得到及時的處理。這時候客戶端(以IE爲例)的表現就是訪問頁面反應很慢,丟包率較高。但是狀態檢測的防火牆通過判斷ACK報文的狀態是否合法,藉助其強大的硬件能力可以較爲有效的過濾***報文。當然如果***流量非常大(特別是千兆線路上,我們曾經觀察到200~300Mbps左右的ACK Flood),由於需要維護很大的連接狀態表同時要檢查數量巨大的ACK報文的狀態,防火牆也會不堪重負導致全網癱瘓。
目前ACK Flood並沒有成爲***的主流,而通常是與其他***方式組合在一起使用。回顧前面描述的SYN Cookie算法,其核心思想是主動迴應SYN/ACK包,然後校驗第3次握手的ACK報文是否合法,目前大多數實現中校驗ACK報文的合法性都涉及到較爲複雜的算法。當SYN Flood與ACK Flood一起發生的時候, 主機和防火牆將耗費大量的精力來計算ACK報文是否合法以致不堪重負。
從以上的描述可以看到ACK Flood具有"單包***"的特點。但我們仍然可以從TCP/IP協議的特性以及數據傳輸特性中得到一定的統計規律。在現實世界中,正常數據傳輸的兩個方向(客戶端à服務器,服務器à客戶端)上的報文數量基本上是均衡的,同時數據報文的內容是較爲隨機的。因此,當數據傳輸兩個方向上的報文數量發生傾斜的時候,基本上可以判定發生了***。並且在大多數情況下,由於爲了追求發包的速率,***報文的內容是較爲固定的。因此,防護設備可以通過學習***報文的特徵,當某個特徵在一段時間的採樣內大量重複出現,那麼基本上可以判定符合此特徵的數據報文爲***報文。當然,統計的方法不可避免會帶來誤判,因此將統計方法與連接狀態檢測結合起來是比較合理的做法。
3. Connection Flood。稱爲連接耗盡***,顧名思義就是將服務器上可用的連接數佔滿直至無法正常響應。與前面講述的***方式不同的是,連接耗盡***使用真實的IP地址與服務器建立連接。***者操控了大量的傀儡主機或者使用代理服務器來發起大規模的連接。當連接數達到一定規模,超過了服務器的能力時,正常的連接請求將無法建立。通過不斷地與服務器建立大量的連接,最終服務器的內存資源將被耗盡。應該說,連接耗盡***比以上的***更爲複雜,手段和變化更爲豐富多彩。判斷連接耗盡***需要對netstat ?Can顯示的連接狀態進行分析,可能出現的情況有:
1) 若干個源IP與服務器建立了大量的連接;
2) 大量的連接處於TIME_WAIT, FIN_WAIT狀態;
除了建立大量的連接之外,***程序在與服務器建立連接之後可能始終不放棄連接,並間隔地向服務器發送垃圾數據包使得連接狀態始終保持,拖延服務器釋放連接的時間,這種連接也可以稱之爲"空連接"。
顯然,如果***者掌握的傀儡主機數量不夠的話,就需要每個傀儡主機與服務器建立相當數量的連接才能使***效果比較明顯。防火牆就可以通過限制每個源IP的連接數來將***的影響降到最低點。但是當傀儡主機數量足夠多的時候,幾乎是每個源IP只與服務器同時保持2到3個連接,如果限制源IP的連接數,就有可能使得正常的服務無法正常訪問。大多數的網站內容豐富多彩,打開一個頁面就可能需要向服務器發起數十個連接,限制連接就有可能使得頁面上的內容無法正常打開。
連接耗盡***對防火牆帶來的衝擊也是很明顯的,由於連接數量巨大,佔用了大量的連接表項,防火牆的負載和內存使用率將會明顯上升。如果在防火牆前面部署具有防護連接耗盡***能力的設備,在傀儡主機向服務器發起連接請求的時候,防護設備是無法簡單的根據SYN包來判斷是否是正常連接的,從而只能讓連接通過,只有當連接建立之後纔有可能判斷是否惡意的連接,但此時已經對服務器和防火牆造成了一定的影響。所以防護設備在連接建立之後,如果一斷時間內沒有有效的數據包從客戶端到達,則可以判定此連接爲"空連接",同時應當儘快地主動清除已經建立的連接,使得防火牆和服務器釋放連接表項。
4.Get Flood***,也就是 "刷Script腳本"***。以上SYN Flood、ACK Flood、Connection Flood都可以說是針對TCP層的***,而Get Flood***則是針對7層應用協議發起的***。這種***主要針對使用ASP,JSP,PHP,CGI腳本程序動態生成頁面的系統。通常動態頁面的生成涉及到後臺數據庫的操作,如果***程序與服務器建立連接之後,不斷地發送Get請求,使得腳本程序提交查詢、列表等耗費大量數據庫資源的調用,數據庫服務器的負載將急劇上升使得正常的數據庫操作也無法響應,這樣動態頁面的生成就很緩慢甚至最終操作失敗。
在使用這種***方式的時候,***者通常使用匿名的代理服務器發起請求。顯然,代理服務器數量越多的話效果越明顯,同時代理服務器的同步性越好的話***效果越顯著。由於很多網站提供代理列表,因此***者使用上千個甚至數千個代理服務器發起***並不是一件困難的事情。發送一個GET/POST請求,對客戶端的CPU耗費和帶寬的佔用微乎其微,因此當發生***的時候在防護設備和防火牆上並不能觀察到包速率和流量的明顯變化。
Get Flood***如果針對靜態頁面的話,則效果會大打折扣。因此,對付Get Flood***可以從優化頁面構造上着手,儘可能避免過多地使用動態頁面;在請求動態頁面之前要求通過認證,這樣***程序就無法直接發送頁面請求。
雖然表面上看Get Flood***所發出的頁面請求與正常的訪問頁面沒有區別,但仔細思考一下如果防護設備在收到一個頁面請求的時候主動迴應一個帶Cookie的內容,防護設備迴應的內容到達正常客戶端的時候會使得客戶端作出相應的動作,而對於使用工具發起頁面請求的客戶端將不會有任何的響應。假設工具對迴應的內容進行分析,那麼工具發送頁面請求的速率將大大降低,使得***效果不明顯。

前面講述的主要是tcp類型的***,由於TCP協議具有連接狀態,在 TCP類型的***面前或許人們可以設計一些根據連接特性的算法來較爲有效對***進行防護。但在針對UDP服務的***面前,服務器顯得更加脆弱,可以利用的協議特性更少,防護的難度更高。UDP協議是無狀態的,而基於UDP應用的協議五花八門,很多屬於商業公司開發的私有協議,人們無法知道其協議的格式,從而無法設計非常有效的通用防護算法。但可以分析一些常用的、公開的UDP應用協議,提出有針對性的防護算法。
首先仍然可以得到應用的統計特性,這在講述ACK Flood的時候曾經提到:正常數據傳輸的兩個方向(客戶端à服務器,服務器à客戶端)上的報文數量基本上是均衡的,同時數據報文的內容是較爲隨機的。當網絡上兩個方向的報文數量發生傾斜並且報文內容較爲固定的時候,一定是發生了***行爲。防護設備可以通過模式識別算法抽取出報文中的特徵,並將符合此特徵的報文認爲是***報文而丟棄。通過模式識別算法學習特徵的過程比較複雜,目前並沒有防火牆能夠做到這一點,只有少數的專業防護設備實現了這樣的算法。
但是這樣的通用防護模型在防護某些特定的應用時候可能效果並不明顯,同時如果***程序隨機生成UDP包負載,則將無法學習到特徵。或許針對一些特定的應用來定製防護算法是目前唯一可行的方法。
從人們最經常使用的DNS服務來分析可以做些什麼事情。DNS服務器對人們正常使用Internet 有着極爲重要的作用,一旦DNS服務器遭受***,人們使用網絡將受到嚴重的影響。
UDP DNS Query Flood***採用的方法是向被***的服務器發送大量的域名解析請求,通常請求解析的域名是隨機生成或者是網絡世界上根本不存在的域名,被***的DNS 服務器在接收到域名解析請求的時候首先會在服務器上查找是否有對應的緩存,如果查找不到並且該域名無法直接由服務器解析的時候,DNS 服務器會向其上層DNS服務器遞歸查詢域名信息。域名解析的過程給服務器帶來了很大的負載,每秒鐘域名解析請求超過一定的數量就會造成DNS服務器解析域名超時。
根據微軟的統計數據,一臺DNS服務器所能承受的動態域名查詢的上限是每秒鐘9000個請求。而我們知道,在一臺P3的PC機上可以輕易地構造出每秒鐘幾萬個域名解析請求,足以使一臺硬件配置極高的DNS服務器癱瘓,由此可見DNS 服務器的脆弱性。目前最常用的DNS服務器軟件是Bind。
通常***者採用的手段包括:
1) 利用發包程序向DNS服務器發送不帶任何負載的NULL數據包。由於數據包本身不符合協議規定,服務器在收到報文的時候將直接丟棄。因此這種***方式除非***流量比較大,否則不會有明顯的效果。
2) 利用程序構造DNS解析請求固定的域名,由於DNS服務器在解析請求的時候會在系統cache存放上一次解析的結果,這種***方式也需要較大的流量。
3) 向DNS服務器發起解析請求隨機的、不存在的域名;這樣DNS服務器就需要進行頻繁的字符串匹配,由於在本地無法查到對應的結果,服務器必須使用遞歸查詢向上層域名服務器提交解析請求,引起連鎖反應。
目前尚沒有防火牆能對DNS服務器的***進行防護,只有少數的專業防護設備可以做到。
防護仍然可以從統計學的角度出發。作爲安裝在DNS服務器前面的防護設備,在平時運行時可以統計哪些域名是經常被解析請求的,哪些域名是從來都沒有被解析請求過的,學習域名解析的結果,對那些經常無法解析的域名引入類似的信譽機制。在***發生的時候,防護設備利用內建的高速cache根據平時學習到的域名解析的結果主動響應解析請求,這樣減輕DNS服務器的負載。同時,根據統計的結果,過濾部分明顯非法的解析請求(例如某個從來未被解析過的域名),對突然發起大量頻度較低的域名解析請求的源IP地址進行帶寬限制。通過採取這些方法,可以將***帶來的影響降到最低點。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章