萬盛學電腦網

 萬盛學電腦網 >> 病毒防治 >> SYN Flood攻擊的基本原理及防御

SYN Flood攻擊的基本原理及防御

http://./第一部分 SYN Flood的基本原理   SYN Flood是當前最流行的DoS(拒絕服務攻擊)與DDoS(分布式拒絕服務攻擊)的方式之一,這是一種利用TCP協議缺陷,發送大量偽造的TCP連接請求,從而使得被攻擊方資源耗盡(CPU滿負荷或內存不足)的攻擊方式。   要明白這種攻擊的基本原理,還是要從TCP連接建立的過程開始說起: 大家都知道,TCP與UDP不同,它是基於連接的,也就是說:為了在服務端和客戶端之間傳送TCP數據,必須先建立一個虛擬電路,也就是TCP連接,建立TCP連接的標准過程是這樣的: 首先,請求端(客戶端)發送一個包含SYN標志的TCP報文,SYN即同步(Synchronize),同步報文會指明客戶端使用的端口以及TCP連接的初始序號; 第二步,服務器在收到客戶端的SYN報文後,將返回一個SYN+ACK的報文,表示客戶端的請求被接受,同時TCP序號被加一,ACK即確認(Acknowledgement)。 第三步,客戶端也返回一個確認報文ACK給服務器端,同樣TCP序列號被加一,到此一個TCP連接完成。 以上的連接過程在TCP協議中被稱為三次握手(Three-way Handshake)。   問題就出在TCP連接的三次握手中,假設一個用戶向服務器發送了SYN報文後突然死機或掉線,那麼服務器在發出SYN+ACK應答報文後是無法收到客戶端的ACK報文的(第三次握手無法完成),這種情況下服務器端一般會重試(再次發送SYN+ACK給客戶端)並等待一段時間後丟棄這個未完成的連接,這段時間的長度我們稱為SYN Timeout,一般來說這個時間是分鐘的數量級(大約為30秒-2分鐘);一個用戶出現異常導致服務器的一個線程等待1分鐘並不是什麼很大的問題,但如果有一個惡意的攻擊者大量模擬這種情況,服務器端將為了維護一個非常大的半連接列表而消耗非常多的資源----數以萬計的半連接,即使是簡單的保存並遍歷也會消耗非常多的CPU時間和內存,何況還要不斷對這個列表中的IP進行SYN+ACK的重試。實際上如果服務器的TCP/IP棧不夠強大,最後的結果往往是堆棧溢出崩潰---即使服務器端的系統足夠強大,服務器端也將忙於處理攻擊者偽造的TCP連接請求而無暇理睬客戶的正常請求(畢竟客戶端的正常請求比率非常之小),此時從正常客戶的角度看來,服務器失去響應,這種情況我們稱作:服務器端受到了SYN Flood攻擊(SYN洪水攻擊)。    從防御角度來說,有幾種簡單的解決方法,第一種是縮短SYN Timeout時間,由於SYN Flood攻擊的效果取決於服務器上保持的SYN半連接數,這個值=SYN攻擊的頻度 x  SYN Timeout,所以通過縮短從接收到SYN報文到確定這個報文無效並丟棄改連接的時間,例如設置為20秒以下(過低的SYN Timeout設置可能會影響客戶的正常訪問),可以成倍的降低服務器的負荷。     第二種方法是設置SYN Cookie,就是給每一個請求連接的IP地址分配一個Cookie,如果短時間內連續受到某個IP的重復SYN報文,就認定是受到了攻擊,以後從這個IP地址來的包會被一概丟棄。     可是上述的兩種方法只能對付比較原始的SYN Flood攻擊,縮短SYN Timeout時間僅在對方攻擊頻度不高的情況下生效,SYN Cookie更依賴於對方使用真實的IP地址,如果攻擊者以數萬/秒的速度發送SYN報文,同時利用SOCK_RAW隨機改寫IP報文中的源地址,以上的方法將毫無用武之地。                 第二部份 SYN Flooder源碼解讀       下面我們來分析SYN Flooder的程序實現。 首先,我們來看一下TCP報文的格式:   0         1         2         3         4         5         6     0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4 6 8 0 2 4     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    |      IP首部      |    TCP首部      |    TCP數據段    | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               圖一 TCP報文結構   如上圖所示,一個TCP報文由三個部分構成:20字節的IP首部、20字節的TCP首部與不定長的數據段,(實際操作時可能會有可選的IP選項,這種情況下TCP首部向後順延)由於我們只是發送一個SYN信號,並不傳遞任何數據,所以TCP數據段為空。TCP首部的數據結構為:      0                   1                   2                   3     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    |             十六位源端口號    |           十六位目標端口號    |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    |                        三十二位序列號                         |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    |                        三十二位確認號                         |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    | 四位  |           |U|A|P|R|S|F|                               |    | 首部  |六位保留位 |R|C|S|S|Y|I|         十六位窗口大小        |    | 長度  |           |G|K|H|T|N|N|                               |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    |           十六位校驗和        |         十六位緊急指針        |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    |                          選項(若有)                         |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    |                          數據(若有)                         |    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                       圖二  TCP首部結構   根據TCP報文格式,我們定義一個結構TCP_HEADER用來存放TCP首部: typedef struct _tcphdr               {         USHORT th_sport;               //16位源端口     USHORT th_dport;    &
copyright © 萬盛學電腦網 all rights reserved