IP协议安全:泪滴攻击与碎片攻击

一、IP协议介绍

IP协议是网络中最繁忙的协议。IP协议是一种best efforts协议,不保证可靠性,数据包可能重复、丢失;无连接协议,同一个连接中的多个报文被独立对待。IP协议主要定义了数据传送的基本单位;执行路由功能;主要规定了主机和路由器应该如何处理数据包;在什么情况下产生错误信息;以及什么情况下应该丢弃数据包。
先介绍现在普遍使用的IPv4,以下是报头格式:

IP协议安全:泪滴攻击与碎片攻击_第1张图片
我们可以看到,IP数据报的报头上一个可选填充字段,长度为0-40字节,因此IP数据报的报头的长度应该是20-60字节。接下来我们浏览一下百度产生数据报,使用wireshark抓取一个TCP数据报,观看其IP报头的部分,结合头部做实际的分析:
IP协议安全:泪滴攻击与碎片攻击_第2张图片
以下单位为bit:

  • 版本(4bit):4代表IPv4
  • 首部长度(4bit):这里的5代表5*4=20,将这里的数乘以4就是首部的长度,因此我们抓取的这个数据报的IP首部长度为20。
  • 区分服务(8bit):用来获得更好的服务。这个字段在旧标准中叫做服务类型,但实际上一直没有被使用过。
  • 总长度(16bit):代表IP数据报的总长度,单位是字节,共16位,因此IP数据报最大长度为2^16-1=65535字节
  • 标识(16bit):用于标识IP数据报。由于在不同的网络环境中的MTU不同,IP数据报有时需要分片,为了正确重组IP数据报,故每个数据报有标识字段。
  • 标志(3bit):最低一位为MF(more fragment)标识后面是否还有碎片,中一位DF(don’t fragment)表示该数据报是否允许被分片。
  • 片偏移(13bit):用于标识该碎片在整个数据报中的位置。
  • 检验和(16bit):只检验分组的首部,而不检验数据部分。
  • TTL(8bit):单位是路由次数,表示最多经过多少路由。
  • 协议(8bit):携带的数据是何种协议,即该数据应该交付至哪层传输层协议,其中6表示TCP,17表示UDP。
  • 源IP(16bit)
  • 目的IP(16bit)

温习完了IP协议,来看看该协议中有哪些漏洞吧。

二、DOS攻击

首先,很容易可以想到,IP协议的分片功能可以使我们的碎片乱序到达。因此,如果我们构造两个碎片,第一个分片的偏移为0;第二个分片的偏移是64800。因为IP分片可以乱序到达,所以接收方会等待其他分片;同时会为其他分片分配内存空间。相当于一个数据包会使用64K的内存。而且这段空间会持续保留15~255秒。这样,很快会耗尽主机的内存空间,造成DoS。Windows 2000, XP, 以及Unix的各版本都有这个漏洞。

三、泪滴攻击(TearDrop)

先分析一小段代码,看看他的输出:

#include 
int main()
{
    unsigned short a=50;
    unsigned short b=30;
    unsigned short c=100;
    printf("%hu\n",a-b);
    printf("%hu\n",a-c);
    return 0;
}

可以看到,由于该段代码缺乏判断机制,且a与c都是无符号类型,a-c时会导致溢出,变成一个很大的数。
泪滴攻击便是运用了这一原理。由于网络环境复杂,我们收到的IP数据报可能存在重叠现象,为了解决这种现象,我们需要有一段代码解决问题。接下来我们看看IP组片的一段代码:

if (prev != NULL && offset < prev->end)
// if there are overlapping fragments
{
//用之前块的结束部分减去当前的偏移,得到了重叠部分
i = prev->end - offset;
//偏移加上重叠部分,得到了新的偏移
offset += i;/* ptr into datagram */
//新的指针
ptr += i;/* ptr into fragment data */
//advance to the end of the previous fragment
}

以上这一段是用来计算到底重叠了多少字节(i),然后将指向第二个分片的指针朝后移动这么多字节,也即,忽略了第二个分片的重叠部分。

接下来需要将第二个分片的剩余内容拷贝一下,以形成完整的数据报文。首先需要计算第二个分片还剩余多少字节。

fp->len = end - offset;

针对正常的碎片重叠,这种方法是完全可行的。
IP协议安全:泪滴攻击与碎片攻击_第3张图片
而对于不正常的呢?比如我们将第二段碎片完全置于第一段碎片中:
IP协议安全:泪滴攻击与碎片攻击_第4张图片
在这种方式下,我们得到的offset与prev->end是相同的,而当前的end却比较小,因此在复制操作fp->len = end - offset下,end-offset会溢出,产生一个非常大的数(如64KB),这部分可能会覆盖系统内存的重要内存,甚至导致系统的崩溃等。

三、微小碎片攻击

3.1攻击原理与介绍
某些机器为了阻止外部机器尝试与其连接,会在防火墙中设置过滤SYN包。因为机器如果未建立TCP连接的情况下收到别的包会自动RST。因此检查TCP第一个包的SYN位并过滤理论上可以阻断外部机器尝试与其进行连接(即FO==0且SYN ==1)。然而IP分片的设定却可以绕过这道防火墙设定。

STD 5,RFC 791规定:
每个互联网模块最小能够转发68个八位字节的数据报,不允许进一步分段。这是因为IP头部最多可达60个八位字节,最小片段为8个八位字节。

我们从这篇规定看到,最小的模块为68字节,而IP头部最大可达60字节,这就意味着我们的TCP报头只要包含8个字节就可以了。这也就意味着,我们可以在第一个包里不包含我们的SYN位,而在第二包里包含。这样进入机器后被重组就又可以与目标机器建立连接了。

3.2 解决方法
3.2.1 直接法
检查最小长度,保证其包含SYN位:

如果FO = 0且PROTOCOL = TCP,则TRANSPORTLEN 

3.2.2 间接方法
间接方法依赖于这样的观察:当TCP数据包被分段以便迫使零偏移片段(第一个分片)中不存在“有趣”的头部字段时,必定存在FO等于1的片段。

如果看到具有FO== 1的分组,则相反地,它可以指示在片段集中存在具有八个八位字节的传输报头长度的零偏移片段。丢弃该FO == 1偏移片段将阻止接收主机对数据报文的重组,并且与上述直接方法一样有效。

你可能感兴趣的:(网络安全)