本文由 網易雲 發布。
TCP協議,相信對於每一個開發工程師都不陌生。由於該協議是一個面向連接,可靠的特性,廣泛應用於現在互聯網的應用中。如常見的Web、SSH、FTP等都是基於TCP協議。目前TCP協議占全網的流量達到80%,因此這也成為黑客主要攻擊的類別。
例如在2016年,造成美國大半個互聯網下線的Dyn事件,10月21日,提供動態DNS服務的Dyn DNS遭到了大規模DDoS攻擊,攻擊主要影響其位於美國東區的服務。此次攻擊導致許多使用DynDNS服務的網站遭遇訪問問題,其中包括 GitHub、Twitter、Airbnb、Reddit、Freshbooks、Heroku、SoundCloud,、Spotify 和 Shopify。攻擊導致這些網站一度癱瘓,Twitter甚至出現了近24小時0訪問的局面。事后據Dyn產品部門執行副總裁的深入剖析本輪攻擊就是利用TCP協議的數據包進行攻擊。一開始就成功打破了Dyn的防護,並對其內部系統造成了嚴重破壞。該公司並未披露本次攻擊的確切規模,外界估計它可能大大超過了針對OVH的那次DDoS攻擊。(峰值達到了1.1Tbps,這也是迄今所知最大的一次DDoS攻擊。)
那么這些針對TCP的攻擊都是如何發起的呢?下面首先我們先回顧一下TCP報文的交互過程。
下面是本機瀏覽器訪問www.163.com,使用wireshark抓包的結果:
這里我們忽略中間的數據傳輸過程,重點先關注一下頭尾處的連接建立我斷開連接的部分。
TCP連接的建立:主要的目的是為了互相通知對方自己的初始化的sequence Number,這個序號用於IP數據包在網絡上亂序到達的時,便於TCP對IP數據包的重排序。
客戶端的第一個報文如下圖:
TCP中的syn標志位置為1,序號為 612417286(記為i)。
服務端接收到報文后,對該報文進行確認,並發送自己的sequence number給客戶端,故為SYN_ACK包,如下圖:
可以看到tcp中syn,ack標志位同時被置為1,服務端確認客戶端的報文,Acknowledgement number(確認號)為612417287(i+1),並帶上自己的sequence number 為 522111292(記為j)。
客戶端收到后會對發送確認報文,對服務端報文進行確認。如圖:
TCP的ack標志位被置為1,確認號為522111293(j+1)。
這樣經過這3個報文,客戶端和服務端都獲取到了對方的初始sequence number,連接就建立了。
TCP連接斷開: TCP是一個全雙工的數量傳輸協議,所以TCP連接的斷開實際上是2個方向上的傳輸關閉過程。接下來看看報文的交互過程,本例為服務端發起的關閉:
首先服務端發送一個FIN報文。通知客戶端,服務端不在有數據發送給客戶端。
這里我們可以忽略ack和Acknowledgement number,這個為對前一次客戶端報文的確認。我們可以看到TCP中的FIN標志位置為1,sequence number 為522230043(記為k)。
客戶端收到fin報文后,回復一個ack包確認。
這樣從服務端到客戶端這個方向上的數據傳輸通道就被關閉,即服務端應用不可以在通過這條連接發送數據給客戶端。
接下來就是關閉客戶端到服務端的傳輸通道,客戶端首先發送fin包
服務端收到后發送確認報文給客戶端。
這樣一來從客戶端到服務端的傳輸通道也關閉了,那么此時兩個方向上的傳輸通道都關閉了,TCP的通信雙方就都斷開了連接。
簡略的交互示意圖如下:
從上述的連接建立和斷開方式我們會發現TCP連接的建立和斷開涉及多個報文,多個狀態之間的轉換。那么從攻擊者角度看上述過程,我們該怎么利用交互過程進行DDOS攻擊呢?
TCP攻擊可以簡單的分為以下三類:
1. FLOOD類攻擊,例如發送海量的syn,syn_ack,ack,fin等報文,占用服務器資源,使之無法提供服務。
2. 連接耗盡類攻擊,如與被攻擊方,完成三次握手后不再發送報文一直維持連接,或者立刻發送FIN或RST報文,斷開連接后再次快速發起新的連接等,消耗TCP連接資源。
還有一類則比較巧妙,是在我們上述沒有做分析的數據傳輸過程中的利用TCP本身的流控,可靠性保證等機制來達到攻擊的目的,即:
3. 利用協議特性攻擊:例如攻擊這建好連接之后,基於TCP的流控特性,立馬就把TCP窗口值設為0,然后斷開連接,則服務器就要等待Windows開放,造成資源不可用。或者發送異常報文,可能造成被攻擊目標奔潰。
那么上述三種類型的攻擊具體的實時和防御原理是怎樣的呢?
FLOOD類攻擊與防御
Flood類攻擊中最常見,危害最大的是syn_flood攻擊,也是歷史最悠久的攻擊之一。因此我們先來看看syn_flood攻擊。
syn_flood攻擊:SYN-Flood攻擊是當前網絡上最為常見的DDoS攻擊,也是最為經典的拒絕服務攻擊,它利用了TCP協議實現上的一個缺陷,通過向網絡服務所在端口發送大量的偽造源地址的攻擊報文,就可能造成目標服務器中的半開連接隊列被占滿,從而阻止其他合法用戶進行訪問。這種攻擊早在1996年就被發現,但至今仍然顯示出強大的生命力。很多操作系統,甚至防火牆、路由器都無法有效地防御這種攻擊,而且由於它可以方便地偽造源地址,追查起來非常困難。
從上文我們可以知道客戶端發起連接的報文即為syn報文。當攻擊者發送大量的偽造IP端口的syn報文時,服務端接收到syn報文后,新建一共表項插入到半連接隊列,並發送syn_ack。但由於這些syn報文都是偽造的,發出去的syn_ack報文將沒有回應。TCP是可靠協議,這時就會重傳報文,默認重試次數為5次,重試的間隔時間從1s開始每次都番倍,分別為1s + 2s + 4s + 8s +16s = 31s,第5次發出后還要等32s才知道第5次也超時了,所以一共是31 + 32 = 63s。
也就是說一共假的syn報文,會占用TCP准備隊列63s之久,而半連接隊列默認為1024,系統默認不同,可 cat /proc/sys/net/ipv4/tcp_max_syn_backlog c 查看。也就是說在沒有任何防護的情況下,每秒發送200個偽造syn包,就足夠撐爆半連接隊列,從而使真正的連接無法建立,無法響應正常請求。
而一台普通的每秒就可以輕松偽造100w個syn包。因此即使把隊列大小調大最大也無濟於事。那么應該如何區防護呢?
Syn_flood防御:通常針對syn_flood 有2種比較通用的防護機制
1. cookie源認證:
原理是syn報文首先由DDOS防護系統來響應syn_ack。帶上特定的sequence number (記為cookie)。真實的客戶端會返回一個ack 並且Acknowledgment number 為cookie+1。 而偽造的客戶端,將不會作出響應。這樣我們就可以知道那些IP對應的客戶端是真實的,將真實客戶端IP加入白名單。下次訪問直接通過,而其他偽造的syn報文就被攔截。下面為防護示意圖:
2.reset認證:
Reset認證利用的是TCP協議的可靠性,也是首先由DDOS防護系統來響應syn。防護設備收到syn后響應syn_ack,將Acknowledgement number (確認號)設為特定值(記為cookie)。當真實客戶端收到這個報文時,發現確認號不正確,將發送reset報文,並且sequence number 為cookie + 1。
而偽造的源,將不會有任何回應。這樣我們就可以將真實的客戶端IP加入白名單。
通常在實際應用中還會結合首包丟棄的方式結合源認證一起使用,首包丟棄原理為:在DDOS防護設備收到syn報文后,記錄5元組,然后丟棄。正常用戶將重傳syn報文,防護設備在收到報文命中5元組,並且在規定時間內,則轉發。當重傳syn報文到達一定閥值時,在啟用上述的源認證。這樣就能減少反射syn_ack報文的數量,緩解網絡擁堵,同時對防護不產生影響。
以上是TCP的syn_flood的攻擊和防御原理,后續將分析TCP其他類型的攻擊和防護,敬請期待。
原文地址:https://mp.weixin.qq.com/s/ApHcRCgsJKRi_SrkhqRlcg
延伸閱讀:
DDoS高防服務-DDOS攻擊防御-DDos壓力測試_網易雲
DDoS防護服務_DDoS檢測識別_DDoS攻擊防御_大流量攻擊-網易雲
了解 網易雲 :
網易雲官網:https://www.163yun.com/
新用戶大禮包:https://www.163yun.com/gift
網易雲社區:https://sq.163yun.com/