TCP協議和DOS攻擊原理


一、TCP三次握手、四次分手原理
在kali下運行:tcpdump -nn -i eth0 port 80
然后另起一個窗口運行:curl www.baidu.com,抓取的整個過程如下(中文部分都是自己加的理解和注釋):
 
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
-----------------------------------------三次握手----------------------------------------------------------------------
20:01:12.656037 IP 192.168.40.130.51840 > 14.215.177.39.80: Flags [S], seq 649061102, win 64240, options [mss 1460,sackOK,TS val 3289670858 ecr 0,nop,wscale 7], length 0  -->客戶端主動給服務器打招呼,希望建立連接;同時帶上seq,便於識別本次會話的順序,避免錯續和亂序;length=0,這個包沒數據,只有頭;
20:01:12.696893 IP 14.215.177.39.80 > 192.168.40.130.51840: Flags [S.], seq 1494708435, ack 649061103, win 64240, options [mss 1460], length 0  -->ack=649061103,是客戶端上個包的seq+1,讓客戶端知道自己收到他的請求;
20:01:12.696960 IP 192.168.40.130.51840 > 14.215.177.39.80: Flags [.], ack 1, win 64240, length 0 -->建立連接完畢
-----------------------------------------開始傳輸數據--------------------------------------------------------------------
20:01:12.697280 IP 192.168.40.130.51840 > 14.215.177.39.80: Flags [P.], seq 1:78, ack 1, win 64240, length 77: HTTP: GET / HTTP/1.1 --> P是push,立即發送,不要等;77是http頭; 這里發送http請求;
20:01:12.697509 IP 14.215.177.39.80 > 192.168.40.130.51840: Flags [.], ack 78, win 64240, length 0 --> 這個包沒有任何數據,ack=78=上個包的seq+1,就是服務器讓客戶端知道自己已經收到數據請求了,即將發送數據,請准備好接受;
20:01:12.740915 IP 14.215.177.39.80 > 192.168.40.130.51840: Flags [P.], seq 1:2782, ack 78, win 64240, length 2781: HTTP: HTTP/1.1 200 OK -->seq:服務器從這里開始傳輸http內容,seq和length共同說明了數據長度
20:01:12.740936 IP 192.168.40.130.51840 > 14.215.177.39.80: Flags [.], ack 2782, win 62780, length 0 -->客戶端回應收到服務端2782字節的內容,讓服務器知道傳輸內容是完整的
----------------------------------------四次分手,雙方釋放資源------------------------------------------------------------------------
20:01:12.741227 IP 192.168.40.130.51840 > 14.215.177.39.80: Flags [F.], seq 78, ack 2782, win 62780, length 0 -->我要分手:seq=78,就是客戶端上次發的http數據請求報頭+1,表明這個是基於這次http數據的請求基礎上的;ack:2782,表明服務器上個包已經收到;
20:01:12.741499 IP 14.215.177.39.80 > 192.168.40.130.51840: Flags [.], ack 79, win 64239, length 0 -->ack-79,收到了客戶端上個包
20:01:12.781491 IP 14.215.177.39.80 > 192.168.40.130.51840: Flags [FP.], seq 2782, ack 79, win 64239, length 0 -->真的要分手?再確認一下:seq=2782,我上次發的http內容都收到了么?
20:01:12.781534 IP 192.168.40.130.51840 > 14.215.177.39.80: Flags [.], ack 2783, win 62780, length 0 -->是的,要分手,都把資源釋放了唄;
 
整個過程很精妙,總結如下:
1、seq標明自己包的順序,首次發包都是隨機生成0~2^32內的數據;
2、如果后續自己每次發包都和自己上次的包有關系(也就是接着發, 或者說我方的數據流就從這里開始),那么這次包的seq都在上次發包的基礎上+1,用於避免因為網絡或其他原因導致的錯序和亂序;
      如果后續自己每次發包都和自己上次的包沒關系,則不帶上seq字段,僅通過ack響應對方上個包;
3、ack=對方上個包的sep+1,標明回復的是對方的哪個包;
4、所謂的可靠,就是依托序列號及確認號機制讓TCP的傳輸過程中即使出現丟包也會重傳
5、所謂的連接,本質上就是通信雙方投入自己的資源,為接下來的收發數據做准備
 
 二、基於TCP協議的反射DOS攻擊
   很多網絡協議都有一個“致命”弱點:只發包通信,不會(可能也沒法)驗證對方身份,這就導致了網絡中可能存在大量“虛假欺騙”的流量,比如最典型的當屬ARP協議:對方的MAC對方說了算,自己完全沒法驗證;還有就是TCP協議,設計的初衷是為了保證數據輸出可靠,說白了就是我發的數據對方100%能收到,也沒有考慮數據包的“真偽”,就給DOS攻擊留下了可乘之機;
  1、基於TCP的反射型DOS攻擊
       

   如上圖所示:

       (1)小壞蛋本身的地址是10.1.0.2,但是偽造了一個TCP的SYN包,把源地址改成受害人的10.1.0.4:80,發給“幫凶”10.1.0.3;

       (2)“幫凶” 拆開包一看,發現源地址是10.1.0.3,還真以為是受害人發的,於是按照TCP三次握手的約定,馬上給10.1.0.3發送包,具體的包類型有以下幾種情況:

  •      “幫凶” 本次收到包的seq以前已經出現過了,會認為是SYN重傳,於是再次發出同樣的SYN+ACK包給受害人,這就是反彈SYN+ACK場景;實際中如下圖所示:標紅的SYN包是小壞蛋偽造的,里面的destination就是“幫凶”,source就是受害者;后面那個seq=1000000的包被標記[TCP Retransmission],說明是重傳;  最后6、7兩個包都是“幫凶” 發個受害者的,也都標明了[TCP Retransmission],從ACK來看,就是針對這個seq=1000000的包的回復;從2-7這6個包的ACK來看,受害者短時間內收到了4個一模一樣的SYN+ACK包......
  •  “幫凶”本次收到包的seq比以前包的seq還小,說明傳輸出錯了,按照TCP協議的要求,回復一個ACK包,告訴對方序列號出錯,如下:

    

  •  “幫凶”本次收到包的seq比首個SYN的seq+自己的win還大,比如第一個SYN的seq=1000000,通過SYN+ACK告訴受害者自己的win=29200;受害者從5個包接着發送seq=1000000+win+1的包,但從一開始,所有包的len都等於0,沒有任何應用層的數據傳輸,seq怎么能用1029201開始了? 於是“幫凶”不服,在第6個包給受害則回復:從ACK來看,只“承認收到”首個SYN包

     anyway,不管怎樣,“幫凶”在收到包后,都會根據不同的情況給受害人發包SYN+ACK或單獨的ACK包;不同的seq會對應不同的回復包,總結如下:

             

  真實場景下的攻擊流量如下:destination是受害者,在不到13ms的時間內,收到了15個攻擊包;

    

    (3) 受害人10.1.0.4收到 “幫凶” 發來的SYN+ACK或SYN包,一臉懵逼:“兄dei,我沒給你發SYN包呀,你為啥發我SYN+ACK了?”  

   如果“幫凶”數量不多,受害人收到的SYN+ACK包不多,現有的硬件資源尚可應對這些無意義的包;可一旦小壞蛋找了大量的“幫凶”,然后偽造SYN包(把src ip改成受害人)發給各個“幫凶”,這些“幫凶”同時響應,給受害人發送SYN+ACK包,造成受害人短時間疲於接受和分析這些無意義的包,無法回應正常的流量,小壞蛋的目的就達到了;

   2、還有一種稍微簡單一點的SYN Flood攻擊,不要找“幫凶”,自己就能完成,如下:3次握手中小壞蛋第一次發送SYN包,有些服務器會專門開辟一個隊列記錄這種“半連接”的狀態;小壞蛋短時間內偽造大量src是假ip的SYN包發給受害者,讓其隊列排滿,無法繼續記錄正常合理的SYN流量,達到攻擊的目的;

  
三、總結如下:
          

 四、DDOS實戰

  1、對於普通人來說,要DOS攻擊服務器,肯定不可能用常規的flood,原因很簡單:自己的帶寬肯定拼不過服務器,自損八百后可能還無法殺敵一千,得不償失;“投機取巧”有這么幾種方式:

  •    找到大量有TCP反射的服務器,利用它們放大流量,典型如memcache攻擊,流量可放大5~6萬倍
  •    或則用木馬釣大量肉雞,利用這些肉雞DDOS攻擊

  以上兩種方式都要利用大量的第三方的“幫凶”幫忙,短時間內塞滿對方地帶寬,相當於“使蠻力”;如果短時間內找不到第三方“幫凶”該怎么辦了?

  •   tear drop:源端發送序列號錯亂的畸形tcp包,服務器收到包后重組老是出錯,就不停地消耗算力重組,直至算力耗盡;或則數據包對於end和offset故意亂標識,導致服務器計算包長度時變成負數(溢出),覆蓋內核的重要代碼或數據,導致崩潰宕機;(這里多說一句:近期著名的CVE-2020-0796漏洞,雖說是應用層的漏洞,但基本原理也是服務器接受數據后沒檢查,導致內存溢出,小壞蛋可利用該漏洞提權或讓服務器藍屏)
  •   sockStress:tcp建立連接不是要3次握手么?小壞蛋將第三次握手地ACK包中的windwo大小修改為0,然后不停地向服務器發這種包。在服務器看來就是客戶端暫時沒有空間來接受數據流量,所以服務器一直處於等待狀態,且不會釋放資源;但是小壞蛋只需要發完window=0的這種包就行,不需要維持這么一個連接,所以對於自身不會消耗巨量的CPU內存資源,達到以小博大地目的;

  2、偶然間發現一個Discuz的小黃站,ip在海外;

  

  廢話少說,直接用kali上sockStress:

   

   大約1分鍾后,網站已經打不開了,瀏覽器一片空白:

         

參考:
1、 https://security.tencent.com/index.php/blog/msg/134  TCP反射DDoS攻擊手法深入分析2.0
2、 https://zhuanlan.zhihu.com/p/53374516   “三次握手,四次揮手”你真的懂嗎?
4、 https://blog.csdn.net/Jack0610/article/details/88648304  Sockstress腳本DoS攻擊原理及實戰演示
5、 https://programtip.com/zh/art-114091 DoS攻擊、tearDrop攻擊和微小IP碎片攻擊


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM