zoukankan      html  css  js  c++  java
  • 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碎片攻击

  • 相关阅读:
    年终盘点 | 七年零故障支撑 双11 的消息中间件 RocketMQ,怎么做到的?
    刚刚,阿里云知行动手实验室正式开放公测了
    dubbogo 3.0:牵手 gRPC 走向云原生时代
    一个改变世界的“箱子”
    我看技术人的成长路径
    云原生体系下的技海浮沉与理论探索
    分布式事务框架 seata-golang 通信模型详解
    Serverless 如何落地?揭秘阿里核心业务大规模落地实现
    Github 2020 年度报告:你以为新冠击溃了开发者?不!他们创造了更多代码...
    493. Reverse Pairs
  • 原文地址:https://www.cnblogs.com/theseventhson/p/13708548.html
Copyright © 2011-2022 走看看