SYN flood攻擊
也稱SYN洪水攻擊,拒絕服務攻擊的一種。其他還有ack-flood攻擊,udp-flood攻擊,icmp-flood攻擊。今天,就以syn-flood攻擊為例說明。
原理:
利用TCP建立連接時3次握手的“漏洞”,通過原始套接字發送源地址虛假的SYN報文,使目標主機永遠無法完成3次握手,占滿了系統的協議棧隊列,資源得不到釋放,進而拒絕服務,是互聯網中最主要的DDOS攻擊形式之一。
正常的三次握手
-
客戶端透過發送
SYN
同步(synchronize)信息到服務器要求創建連線。 -
服務器透過響應客戶端
SYN-ACK
以抄收(acknowledge)請求。 -
客戶端答應
ACK
,連線隨之創建。
非正常的兩次握手
Client發出的第一個里按揭請求報文段,因為網絡延遲,在連接釋放以后的某個時間才能到達server 是一個早已失效的連接請求,但server收到此請求后,誤認為是client再次發送的新的請求,server就向client發出確認報文,同意建立連接。於是,syn-flood攻擊方法變由此而出。通過不斷地發送syn數據包,導致服務器疲於應對而出現無法正常運行業務。
安裝第三方scapy庫:
源碼:
from scapy.all import *
def sendpacket3(tar):
p = IP(dst=tar, id=1111, ttl=99) / TCP(sport=RandShort(), dport=8090, seq=12345, ack=1000, window=1000,
flags="S") / "HaX0r SVP"
ans, unans = srloop(p, inter=0.1, retry=2, timeout=1)
ans.summary()
unans.summary()
sendpacket3('169.254.88.56')
攻擊效果:
防御
-
調整內核參數的方法,可以減少等待及重試,加速資源釋放,在小流量syn-flood的情況下可以緩解,但流量稍大時完全不抵用。
-
syn proxy
在服務器前端的防火牆上使用
當防火牆收到syn包,自己就回復一個syn-ack的包給發起方,在自己內部建立連接
等發起方將ack包返回后,再重新構造syn包發給服務器,建立真正的tcp連接。(這個過程中防火牆要給發起方發送SYNACK一個包,給服務器發送SYN和ACK兩個包,通信的后續包防火牆都應該注意修改序列號或確認號,因為防火牆回復發起方的SYNACK包的序列號基本不可能等於服務器發送的SYNACK包的序列號,所以要進行調整。)
作用:
當客戶端SYN包到達BGW時,BGW並不轉發SYN包,而是以服務器的名義主動回復SYN/ACK包給客戶,如果收到客戶的ACK包,表明這是正常的訪問,此時向服務器發送ACK包並完成三次握手。BGW事實上代替了RS去處理SYN攻擊。BGW后面的服務器設備不會受到攻擊,因為實際的攻擊壓力都由BGW承擔,但同時也帶來新的問題BGW承擔的防攻擊壓力過大,BGW與BFE的結合可以有效緩解DDOS的壓力。
-
syn cookies
syn cookies 主要是應對syn-flood攻擊的單機技術(主要是內核做的服務器防護策略)。實現方案是利用SYN ACK的ISN(init seq number)攜帶信息加上檢測的手段拒絕非法的建立連接請求。
一旦開啟syn cookie,將在ack階段直接創建tcp sock,而不緩存syn隊列。
構造ISN的方法是:
-
令 t 為一個緩慢遞增的時間戳(通常為
time() >> 6
,提供 64 秒的分辨率,就是分鍾數); -
令 m 為服務器會在 SYN 隊列條目中存儲的最大分段大小(maximum segment size,簡稱為 MSS,存儲的是索引,一般這幾種值):
static __u16 const msstab[] = { 536, 1300, 1440, /* 1440, 1452: PPPoE */ 1460, };
-
令 s 為一個加密函數對服務器和客戶端各自的 IP 地址和端口號以及 t 進行運算的結果。返回得到的數值 s 必須是一個24位值。
當來了一個SYN報文后,我們先根據配置填充pre-cookie的值。最后的cookie值是這樣計算的:
hash(4-tupel,0, 0) + syn.seq + (超時時間 << 24) + (hash(4-tuple, 超時時間, 1) + mstab_index)& 0x00FFFFFF
解釋一下hash函數,對如下幾個參數做crc。src_ip, src_port, dst_ip, dst_port,num1,num2。num1目前看是超時時間(分鍾),num2,目前只有0和1兩種選擇,用來生成cookie的密鑰(固定的)。
-
hash(4-tuple,0,0)
-
client發來是syn包的seq值
-
超時的分鍾數放到最高8bit
-
hash(4-tuple, 超時時間,1)
怎么檢查呢?
-
主要看頭部8bit的時間(分鍾),不能超過2分鍾;
-
判斷從ack的ack num算出來的msstab是不是合法;
-
-
首包(第一次請求的syn包)丟棄等。