标题:IP分片重组的分析和常见碎片攻击 v0.2
作者:yawl@nsfocus.com
主页: www.nsfocus.com
时间:v0.1:2000/07; v0.2:2000/09
一前言
本文对linux的IP组装算法进行了分析,因为IP碎片经常用于DOS等攻击,在文章后面我结合
了一些攻击方法进行了更进一步的说明。内核主要参考版本是2.2.16,另外简要的介绍了
2.4.0-test3中的一些变化.
这篇文章基于我今年7月的一份笔记,但增加了许多新的内容。其实本来这月的月刊投稿准备
写一些netfilter的东西,但工作太紧,只好写自己比较熟悉的题材了:-)。成文比较仓促
,如果出现了什么问题,欢迎指正。
二目录
1-概述
2-关键数据结构
3-重要函数说明
4-2.4系列的变化
5-常见碎片攻击
1. 概述
在linux源代码中,ip分片重组的全部程序几乎都在都在/net/ipv4/ip_fragment.c
文件中。其对外提供一个函数接口ip_defrag()。其函数原型如下:
struct sk_buff *ip_defrag(struct sk_buff *skb)
众所周知,网络数据报在linux的网络堆栈中是以sk_buff的结构传送的,ip_defrag()的
功能就是接受分片的数据包(sk_buff),并试图进行组合,当完整的包组合好时,将新的
sk_buff返还,否则返回一个空指针。
此函数在其他文件中的调用如下:
ip层接收主函数为ip_rcv()(/net/ipv4/ip_input.c),任何IP包都需经过此函数处理。
如果此包是发往本机,则调用ip_local_deliver()函数(/net/ipv4/ip_input.c)进行
处理,一般的系统碎片只有在到达最终目的的时候才进行重组(尽管在传输过程中可
能被进一步分成更小的片)。在ip_local_deliver()中我们可发现如下代码:
if (sysctl_ip_always_defrag == 0 && /*编译时未设置提前组装*/
(iph->frag_off & htons(IP_MF|IP_OFFSET))) { /*判断是否是分片包*/
skb = ip_defrag(skb); /*条件满足,进行组装*/
if (!skb) /*若组装好则进行下一步处理,出错
return 0; 或仍未组装完返回*/
iph = skb->nh.iph; /*重新定位ip头的指针*/
}
iph->frag_off只有在设置MF(more fragment)或offset!=0才意味着是分片包,因此
此处的检验理所当然,但为什么判断sysctl_ip_always_defrag == 0呢?
在看ip_rcv()时我们应该已经注意到在刚进行了版本号,长度,校验和等判断后,有如下
一段代码:
if (sysctl_ip_always_defrag != 0 &&
iph->frag_off & htons(IP_MF|IP_OFFSET)) {
skb = ip_defrag(skb);
if (!skb)
return 0;
iph = skb->nh.iph;
ip_send_check(iph);
}
即如果sysctl_ip_always_defrag==1的话,ip_defrag()的调用位置将有变化,对任何
进来的IP分片都要进行重组,可以想像,如果此机器作路由器的话,将对所有的分片
组装好后,才会进行转发。此举一般是没有必要的。这个值可以通过sysctl命令动态
设置,用sysctl -a可以看到在一般的系统中,此值被设为0:
#sysctl -a
......
net.ipv4.ip_always_defrag = 0
......
2. 关键数据结构(2.2系列)
每一个分片用ipfrag结构表示:
/* Describe an IP fragment. */
struct ipfrag {
int offset; /* offset of fragment in IP datagram */
int end; /* last byte of data in datagram */
int len; /* length of this fragment */
struct sk_buff *skb; /* complete received fragment */
unsigned char *ptr; /* pointer into real fragment data */
struct ipfrag *next; /* linked list pointers */
struct ipfrag *prev;
};
这些分片形成一个双向链表(在linux内核中,若需要使用链表,除非有特殊需要,否则推荐
双向链表,见document/CodingStyle),表示一个未组装完的分片队列(属于一个ip包)。
这个链表的头指针要放在ipq结构中:
/* Describe an entry in the "incomplete datagrams" queue. */
struct ipq {
struct iphdr *iph; /* pointer to IP header */
struct ipq *next; /* linked list pointers */
struct ipfrag *fragments; /* linked list of received fragments */
int len; /* total length of original datagram */
short ihlen; /* length of the IP
IP分片重组的分析和常见碎片攻击 v0.2
最新推荐文章于 2025-09-11 00:53:13 发布
本文深入探讨Linux内核2.2和2.4系列中IP分片重组的过程,分析了关键数据结构和函数,如ip_defrag、ip_evictor和ip_glue。此外,还讨论了常见的碎片攻击,如teardrop和jolt2攻击,以及Linux如何防范这些问题。文章强调了正确处理IP分片以防止DOS攻击的重要性。

最低0.47元/天 解锁文章
4017

被折叠的 条评论
为什么被折叠?



