FRAME ICMP IP UDP TCP
traceroute 数据传输路径
ping 一般用ICMP协议,定制可以使用IP ICMP
ping 192.168.0.1 -n -c l -s 65527
tranceroute -n -I 10.210.121.128
tcpdump -n -s o -l eth0 icmp
ifconfig eth0|grep inet
ping -b -n -c l 192.168.0.1
[root@vm0000055 templates]# ping -c 1 -s 65535 192.168.0.1
Error: packet size 65535 is too large. Maximum is 65507
常见 IP 碎片攻击详解
常见 IP 碎片攻击详解
January 11, 2002
Sinbad Technical Publications
Website: http://sinbad.zhoubin.com
© Copyright 2002, All Rights Reserved
Sinbad Technical Publications Page 1
本文简单介绍了 IP 分片原理,并结合 Snort 抓包结果详细分析常见 IP 碎片攻
击的原理和特征,最后对阻止 IP 碎片攻击给出一些建议。希望对加深理解 IP
协议和一些 DoS攻击手段有所帮助。
1. 为什么存在 IP 碎片
链路层具有最大传输单元 MTU 这个特性,它限制了数据帧的最大长度,不同
的网络类型都有一个上限值。以太网的MTU 是 1500,你可以用 netstat -i 命
令查看这个值。如果 IP层有数据包要传,而且数据包的长度超过了 MTU,那
么 IP 层就要对数据包进行分片(fragmentation)操作,使每一片的长度都小
于或等于 MTU。
我们假设要传输一个 UDP 数据包,以太网的 MTU 为 1500字节,一般 IP首部
为 20 字节,UDP 首部为 8 字节,数据的净荷(payload)部分预留是
1500-20-8=1472字节。如果数据部分大于 1472 字节,就会出现分片现象。
IP 首部包含了分片和重组所需的信息:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |R|DF|MF| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|<-------------16------------->|<----3--->|<------------------13----------------->|
Identification:发送端发送的 IP 数据包标识字段都是一个唯一值,该值在分片
时被复制到每个片中。
R:保留未用。
DF:Don't Fragment, “不分片”位,如果将这一比特置 1 ,IP层将不对数据
报进行分片。
MF:More Fragment, “更多的片” ,除了最后一片外,其他每个组成数据报的
片都要把该比特置 1。
Fragment Offset:该片偏移原始数据包开始处的位置。偏移的字节数是该值乘
以 8。
另外,当数据报被分片后,每个片的总长度值要改为该片的长度值。
Sinbad Technical Publications Page 2
每一 IP 分片都各自路由,到达目的主机后在 IP 层重组,请放心,首部中的数
据能够正确完成分片的重组。你不禁要问,既然分片可以被重组,那么所谓的
碎片攻击是如何产生的呢?
2. IP 碎片攻击
IP 首部有两个字节表示整个 IP 数据包的长度,所以 IP 数据包最长只能为
0xFFFF,就是 65535 字节。如果有意发送总长度超过 65535 的 IP碎片,一些
老的系统内核在处理的时候就会出现问题,导致崩溃或者拒绝服务。另外,如
果分片之间偏移量经过精心构造,一些系统就无法处理,导致死机。
所以说,漏洞的起因是出在重组算法上。下面我们逐个分析一些著名的碎片攻
击程序,来了解如何人为制造 IP碎片来攻击系统。
3. ping o' death
ping o' death 是利用 ICMP 协议的一种碎片攻击。攻击者发送一个长度超过
65535 的 Echo Request数据包,目标主机在重组分片的时候会造成事先分配的
65535 字节缓冲区溢出,系统通常会崩溃或挂起。ping不就是发送 ICMP Echo
Request数据包的吗?让我们尝试攻击一下吧!不管 IP和 ICMP首部长度了,
数据长度反正是多多益善,就 65535吧,发送一个包:
# ping -c 1 -s 65535 192.168.0.1
Error: packet size 65535 is too large. Maximum is 65507
不走运,看来 Linux自带的 ping不允许我们做坏事。:(
65507 是它计算好的:65535-20-8=65507。Win2K下的 ping更抠门,数据只允
许 65500大小。所以你必须找另外的程序来发包,但是目前新版本的操作系统
已经搞定这个缺陷了,所以你还是继续往下阅读本文吧。
顺便提一下,记得 99年有“爱国主义黑客” (“红客”的前辈)发动全国网民在
某一时刻开始 ping 某美国站点,试图 ping 死远程服务器。这其实是一种 ping
flood 攻击,用大量的 Echo Request 包减慢主机的响应速度和阻塞目标网络,
Sinbad Technical Publications Page 3
原理和 ping o' death是不一样的,这点要分清楚。
4. jolt2
jolt2.c 是在一个死循环中不停的发送一个 ICMP/UDP 的 IP 碎片,可以使
Windows 系统的机器死锁。我测试了没打 SP 的 Windows 2000,CPU 利用率
会立即上升到 100%,鼠标无法移动。
我们用 Snort分别抓取采用 ICMP和 UDP 协议发送的数据包。
发送的 ICMP 包:
01/07-15:33:26.974096 192.168.0.9 -> 192.168.0.1
ICMP TTL:255 TOS:0x0 ID:1109 IpLen:20 DgmLen:29
Frag Offset: 0x1FFE Frag Size: 0x9
08 00 00 00 00 00 00 00 00 .........
发送的 UDP 包:
01/10-14:21:00.298282 192.168.0.9 -> 192.168.0.1
UDP TTL:255 TOS:0x0 ID:1109 IpLen:20 DgmLen:29
Frag Offset: 0x1FFE Frag Size: 0x9
04 D3 04 D2 00 09 00 00 61 ........a
从上面的结果可以看出:
* 分片标志位 MF=0,说明是最后一个分片。
* 偏移量为 0x1FFE, 计算重组后的长度为 (0x1FFE * 8) + 29 = 65549 > 65535,
溢出。
* IP包的 ID 为 1109,可以作为 IDS检测的一个特征。
* ICMP包:
类型为 8、代码为 0,是 Echo Request;
校验和为 0x0000, 程序没有计算校验, 所以确切的说这个 ICMP包是非法的。
* UDP 包:
目的端口由用户在命令参数中指定;
源端口是目的端口和 1235进行 OR的结果;
校验和为 0x0000,和 ICMP的一样,没有计算,非法的 UDP。
净荷部分只有一个字符'a'。
jolt2.c 应该可以伪造源 IP 地址,但是源程序中并没有把用户试图伪装的 IP 地
址赋值给 src_addr,不知道作者是不是故意的。
Sinbad Technical Publications Page 4
jolt2的影响相当大,通过不停的发送这个偏移量很大的数据包,不仅死锁未打
补丁的 Windows 系统,同时也大大增加了网络流量。曾经有人利用 jolt2 模拟
网络流量,测试 IDS 在高负载流量下的攻击检测效率,就是利用这个特性。
5. teardrop
teardrop 也比较简单,默认发送两个 UDP 数据包,就能使某些 Linux 内核崩
溃。Snort抓取的结果如下:
第一个:
01/08-11:42:21.985853 192.168.0.9 -> 192.168.0.1
UDP TTL:64 TOS:0x0 ID:242 IpLen:20 DgmLen:56 MF
Frag Offset: 0x0 Frag Size: 0x24
A0 A8 86 C7 00 24 00 00 00 00 00 00 00 00 00 00 .....$..........
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 ....
* MF=1,偏移量=0,分片 IP 包的第一个。
* 结构图:
|<-------20-------->|<-------8------->|<------------------28----------------->|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| IP | UDP | Data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
第二个:
01/08-11:42:21.985853 192.168.0.9 -> 192.168.0.1
UDP TTL:64 TOS:0x0 ID:242 IpLen:20 DgmLen:24
Frag Offset: 0x3 Frag Size: 0x4
A0 A8 86 C7 ....
* MF=0,偏移量=0x3,偏移字节数为 0x3 * 8 = 24,最后一个分片。
* 结构图:
|<-------20-------->|<--4-->|
+-+-+-+-+-+-+-+-+-+-+-+-+
| IP | Data |
+-+-+-+-+-+-+-+-+-+-+-+-+
Sinbad Technical Publications Page 5
如果修改源代码, 第二片 IP包的偏移量也可以为 0x4, 偏移字节数就是 0x4 * 8
= 32。
下面的结构图表示了接收端重组分片的过程,分别对应于偏移字节数为 24 和
32 两种情况:
|<-------20-------->|<------8------>|<---------------28---------------->|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
| IP | UDP | Data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
|
| +-+-+-+-+
|<--- ------- 24 --------->| Data |
| +-+-+-+-+
|<--4--->|
|
|
| +-+-+-+-+-
|<------------------- 32 --------------->| Data |
| +-+-+-+-+
|<----4--->|
可以看出,第二片 IP 包的偏移量小于第一片结束的位移,而且算上第二片 IP
包的 Data,也未超过第一片的尾部,这就是重叠现象(overlap) 。老的 Linux
内核(1.x - 2.0.x)在处理这种重叠分片的时候存在问题,WinNT/95在接收到
10 至 50 个 teardrop 分片时也会崩溃。你可以阅读 teardrop.c 的源代码来了解
如何构造并发送这种数据包。
6. 如何阻止 IP 碎片攻击
* Windows系统请打上最新的 Service Pack,目前的 Linux内核已经不受影响。
* 如果可能,在网络边界上禁止碎片包通过,或者用 iptables 限制每秒通过碎
片包的数目。
* 如果防火墙有重组碎片的功能,请确保自身的算法没有问题,否则被 DoS就
会影响整个网络。
* Win2K系统中,自定义 IP安全策略,设置“碎片检查” 。
Sinbad Technical Publications Page 6
7. 参考资料
[1] TCP/IP Illustracted Volume 1 : The Protocols
[2] Microsoft Security Bulletin MS00-029:
http://www.microsoft.com/technet/security/bulletin/ms00-029.asp
[3] BugTraq Mailing List, "Analysis of jolt2.c(MS00-029)":
http://www.securityfocus.com/archive/1/62011
[4] http://www.attrition.org/security/denial/w/teardrop.dos.html
[5] http://packetstormsecurity.org/0005-exploits/jolt2.c
[6] http://packetstormsecurity.org/Exploit_Code_Archive/teardrop.c
traceroute 数据传输路径
ping 一般用ICMP协议,定制可以使用IP ICMP
ping 192.168.0.1 -n -c l -s 65527
tranceroute -n -I 10.210.121.128
tcpdump -n -s o -l eth0 icmp
ifconfig eth0|grep inet
ping -b -n -c l 192.168.0.1
[root@vm0000055 templates]# ping -c 1 -s 65535 192.168.0.1
Error: packet size 65535 is too large. Maximum is 65507
常见 IP 碎片攻击详解
常见 IP 碎片攻击详解
January 11, 2002
Sinbad Technical Publications
Website: http://sinbad.zhoubin.com
© Copyright 2002, All Rights Reserved
Sinbad Technical Publications Page 1
本文简单介绍了 IP 分片原理,并结合 Snort 抓包结果详细分析常见 IP 碎片攻
击的原理和特征,最后对阻止 IP 碎片攻击给出一些建议。希望对加深理解 IP
协议和一些 DoS攻击手段有所帮助。
1. 为什么存在 IP 碎片
链路层具有最大传输单元 MTU 这个特性,它限制了数据帧的最大长度,不同
的网络类型都有一个上限值。以太网的MTU 是 1500,你可以用 netstat -i 命
令查看这个值。如果 IP层有数据包要传,而且数据包的长度超过了 MTU,那
么 IP 层就要对数据包进行分片(fragmentation)操作,使每一片的长度都小
于或等于 MTU。
我们假设要传输一个 UDP 数据包,以太网的 MTU 为 1500字节,一般 IP首部
为 20 字节,UDP 首部为 8 字节,数据的净荷(payload)部分预留是
1500-20-8=1472字节。如果数据部分大于 1472 字节,就会出现分片现象。
IP 首部包含了分片和重组所需的信息:
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |R|DF|MF| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|<-------------16------------->|<----3--->|<------------------13----------------->|
Identification:发送端发送的 IP 数据包标识字段都是一个唯一值,该值在分片
时被复制到每个片中。
R:保留未用。
DF:Don't Fragment, “不分片”位,如果将这一比特置 1 ,IP层将不对数据
报进行分片。
MF:More Fragment, “更多的片” ,除了最后一片外,其他每个组成数据报的
片都要把该比特置 1。
Fragment Offset:该片偏移原始数据包开始处的位置。偏移的字节数是该值乘
以 8。
另外,当数据报被分片后,每个片的总长度值要改为该片的长度值。
Sinbad Technical Publications Page 2
每一 IP 分片都各自路由,到达目的主机后在 IP 层重组,请放心,首部中的数
据能够正确完成分片的重组。你不禁要问,既然分片可以被重组,那么所谓的
碎片攻击是如何产生的呢?
2. IP 碎片攻击
IP 首部有两个字节表示整个 IP 数据包的长度,所以 IP 数据包最长只能为
0xFFFF,就是 65535 字节。如果有意发送总长度超过 65535 的 IP碎片,一些
老的系统内核在处理的时候就会出现问题,导致崩溃或者拒绝服务。另外,如
果分片之间偏移量经过精心构造,一些系统就无法处理,导致死机。
所以说,漏洞的起因是出在重组算法上。下面我们逐个分析一些著名的碎片攻
击程序,来了解如何人为制造 IP碎片来攻击系统。
3. ping o' death
ping o' death 是利用 ICMP 协议的一种碎片攻击。攻击者发送一个长度超过
65535 的 Echo Request数据包,目标主机在重组分片的时候会造成事先分配的
65535 字节缓冲区溢出,系统通常会崩溃或挂起。ping不就是发送 ICMP Echo
Request数据包的吗?让我们尝试攻击一下吧!不管 IP和 ICMP首部长度了,
数据长度反正是多多益善,就 65535吧,发送一个包:
# ping -c 1 -s 65535 192.168.0.1
Error: packet size 65535 is too large. Maximum is 65507
不走运,看来 Linux自带的 ping不允许我们做坏事。:(
65507 是它计算好的:65535-20-8=65507。Win2K下的 ping更抠门,数据只允
许 65500大小。所以你必须找另外的程序来发包,但是目前新版本的操作系统
已经搞定这个缺陷了,所以你还是继续往下阅读本文吧。
顺便提一下,记得 99年有“爱国主义黑客” (“红客”的前辈)发动全国网民在
某一时刻开始 ping 某美国站点,试图 ping 死远程服务器。这其实是一种 ping
flood 攻击,用大量的 Echo Request 包减慢主机的响应速度和阻塞目标网络,
Sinbad Technical Publications Page 3
原理和 ping o' death是不一样的,这点要分清楚。
4. jolt2
jolt2.c 是在一个死循环中不停的发送一个 ICMP/UDP 的 IP 碎片,可以使
Windows 系统的机器死锁。我测试了没打 SP 的 Windows 2000,CPU 利用率
会立即上升到 100%,鼠标无法移动。
我们用 Snort分别抓取采用 ICMP和 UDP 协议发送的数据包。
发送的 ICMP 包:
01/07-15:33:26.974096 192.168.0.9 -> 192.168.0.1
ICMP TTL:255 TOS:0x0 ID:1109 IpLen:20 DgmLen:29
Frag Offset: 0x1FFE Frag Size: 0x9
08 00 00 00 00 00 00 00 00 .........
发送的 UDP 包:
01/10-14:21:00.298282 192.168.0.9 -> 192.168.0.1
UDP TTL:255 TOS:0x0 ID:1109 IpLen:20 DgmLen:29
Frag Offset: 0x1FFE Frag Size: 0x9
04 D3 04 D2 00 09 00 00 61 ........a
从上面的结果可以看出:
* 分片标志位 MF=0,说明是最后一个分片。
* 偏移量为 0x1FFE, 计算重组后的长度为 (0x1FFE * 8) + 29 = 65549 > 65535,
溢出。
* IP包的 ID 为 1109,可以作为 IDS检测的一个特征。
* ICMP包:
类型为 8、代码为 0,是 Echo Request;
校验和为 0x0000, 程序没有计算校验, 所以确切的说这个 ICMP包是非法的。
* UDP 包:
目的端口由用户在命令参数中指定;
源端口是目的端口和 1235进行 OR的结果;
校验和为 0x0000,和 ICMP的一样,没有计算,非法的 UDP。
净荷部分只有一个字符'a'。
jolt2.c 应该可以伪造源 IP 地址,但是源程序中并没有把用户试图伪装的 IP 地
址赋值给 src_addr,不知道作者是不是故意的。
Sinbad Technical Publications Page 4
jolt2的影响相当大,通过不停的发送这个偏移量很大的数据包,不仅死锁未打
补丁的 Windows 系统,同时也大大增加了网络流量。曾经有人利用 jolt2 模拟
网络流量,测试 IDS 在高负载流量下的攻击检测效率,就是利用这个特性。
5. teardrop
teardrop 也比较简单,默认发送两个 UDP 数据包,就能使某些 Linux 内核崩
溃。Snort抓取的结果如下:
第一个:
01/08-11:42:21.985853 192.168.0.9 -> 192.168.0.1
UDP TTL:64 TOS:0x0 ID:242 IpLen:20 DgmLen:56 MF
Frag Offset: 0x0 Frag Size: 0x24
A0 A8 86 C7 00 24 00 00 00 00 00 00 00 00 00 00 .....$..........
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 ....
* MF=1,偏移量=0,分片 IP 包的第一个。
* 结构图:
|<-------20-------->|<-------8------->|<------------------28----------------->|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| IP | UDP | Data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
第二个:
01/08-11:42:21.985853 192.168.0.9 -> 192.168.0.1
UDP TTL:64 TOS:0x0 ID:242 IpLen:20 DgmLen:24
Frag Offset: 0x3 Frag Size: 0x4
A0 A8 86 C7 ....
* MF=0,偏移量=0x3,偏移字节数为 0x3 * 8 = 24,最后一个分片。
* 结构图:
|<-------20-------->|<--4-->|
+-+-+-+-+-+-+-+-+-+-+-+-+
| IP | Data |
+-+-+-+-+-+-+-+-+-+-+-+-+
Sinbad Technical Publications Page 5
如果修改源代码, 第二片 IP包的偏移量也可以为 0x4, 偏移字节数就是 0x4 * 8
= 32。
下面的结构图表示了接收端重组分片的过程,分别对应于偏移字节数为 24 和
32 两种情况:
|<-------20-------->|<------8------>|<---------------28---------------->|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
| IP | UDP | Data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
|
| +-+-+-+-+
|<--- ------- 24 --------->| Data |
| +-+-+-+-+
|<--4--->|
|
|
| +-+-+-+-+-
|<------------------- 32 --------------->| Data |
| +-+-+-+-+
|<----4--->|
可以看出,第二片 IP 包的偏移量小于第一片结束的位移,而且算上第二片 IP
包的 Data,也未超过第一片的尾部,这就是重叠现象(overlap) 。老的 Linux
内核(1.x - 2.0.x)在处理这种重叠分片的时候存在问题,WinNT/95在接收到
10 至 50 个 teardrop 分片时也会崩溃。你可以阅读 teardrop.c 的源代码来了解
如何构造并发送这种数据包。
6. 如何阻止 IP 碎片攻击
* Windows系统请打上最新的 Service Pack,目前的 Linux内核已经不受影响。
* 如果可能,在网络边界上禁止碎片包通过,或者用 iptables 限制每秒通过碎
片包的数目。
* 如果防火墙有重组碎片的功能,请确保自身的算法没有问题,否则被 DoS就
会影响整个网络。
* Win2K系统中,自定义 IP安全策略,设置“碎片检查” 。
Sinbad Technical Publications Page 6
7. 参考资料
[1] TCP/IP Illustracted Volume 1 : The Protocols
[2] Microsoft Security Bulletin MS00-029:
http://www.microsoft.com/technet/security/bulletin/ms00-029.asp
[3] BugTraq Mailing List, "Analysis of jolt2.c(MS00-029)":
http://www.securityfocus.com/archive/1/62011
[4] http://www.attrition.org/security/denial/w/teardrop.dos.html
[5] http://packetstormsecurity.org/0005-exploits/jolt2.c
[6] http://packetstormsecurity.org/Exploit_Code_Archive/teardrop.c
作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:https://jackxiang.com/post/1741/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!
最后编辑: jackxiang 编辑于2023-3-14 14:45
评论列表