Bugtraq mailing list archives
xterm segfaults from environment variables - too obvious
From: luyer () ucs uwa edu au (David Luyer)
Date: Tue, 11 Mar 1997 15:00:16 +0800
Firstly, the bug. What a joke. A segfault from xterm this easily. Putting a large string into in LC_CTYPE or LANG will cause xterm from Debian-1.2.8 (the latest and supposedly stable and secure) Linux to segfault. Secondly, the script I used to test things to find it. Finding these was quite easy - here's a little script (this will run and compile things under Linux and probably other unicies as long as you have "sh" and "gcc"; the TestProgram currently uses the "rc" shell but it's easy enough for someone to change) which basically lets you overflow an arbitrary getenv call based on an environment variable. The test script ran it overflowing each getenv call under xterm to find the two mentoined above. What this creates: TestProgram - the getenv insecurity checker, usage eg: ./TestProgram 60 /usr/X11R6/bin/xterm -exec /bin/false -geometry \ 1x1+1+1 > log.xterm 2>&1 TestXterm - the above line in a script :) getenv.so - LD_PRELOAD to this to list all getenv calls getenv2.so - LD_PRELOAD to this and ENV_TEST_VAR to a variable number to attempt an overflow on that variable number log.testprog - the output from the sample test (a program compiled to segfault easily to make sure these scripts work on your system) Here's the proper contents of log.testprog if it all works on your system (ie, if you have the rc shell installed and handling signals properly - sh doesn't log signals to stdout or stderr on my system, but rc does. I'm not sure if the Debian default rc manages it tho) --- z# cat log.testprog Testing 0 -
MALLOC_CHECK_ << - countdown -1. AWAY << - countdown -1. HOME << - countdown -2.
Testing 1 -
MALLOC_CHECK_ << - the lucky variable! AWAY << - the lucky variable! HOME << - countdown -1.
Testing 2 -
MALLOC_CHECK_ << - countdown 1. AWAY << - countdown 1. HOME << - the lucky variable!
segmentation violation z# --- If that's all fine, chances are you can run "./TestXterm" and then "grep -3 segmentation log.xterm" to find: --- z# grep -3 segmentation log.xterm
RESOURCE_NAME << - countdown 1. LC_CTYPE << - the lucky variable! XLOCALEDIR << - countdown -1.
segmentation violation Testing 27 -
MALLOC_CHECK_ << - countdown 26. XLOCALEDIR << - countdown 25.
--
LC_CTYPE << - countdown 1. LANG << - the lucky variable! XLOCALEDIR << - countdown -1.
segmentation violation Testing 28 -
MALLOC_CHECK_ << - countdown 27. XLOCALEDIR << - countdown 26.
z# --- Well anyway, here's the script... David. -------------------------- begin script --------------------------------- #!/bin/sh cat >getenv2.c <<EOF extern char **__environ; void *stdout; char *getenv(register const char *name) { register const int len = strlen(name); register char **ep; static int i; static char *big_string_buf = 0; if(!big_string_buf) { if(!(big_string_buf = (char *)malloc(70000))) { big_string_buf = "mallocfailed"; printf("Failed to malloc test string buffer.\n"); } else { for(i=0;i<70000/4;i++) memcpy(big_string_buf+i*4, "f00l", 4); big_string_buf[70000] = '\0'; } for (ep = __environ; *ep != 0; ++ep) if (!strncmp(*ep, "ENV_TEST_VAR=", 13)) i = atoi(&(*ep)[13]); } printf(">> %s << ", name); if(--i) printf("- countdown %d.\n", i); else printf("- the lucky variable!\n"); fflush(stdout); if(i) { for (ep = __environ; *ep != 0; ++ep) if (!strncmp(*ep, name, len) && (*ep)[len] == '=') return &(*ep)[len + 1]; return 0; } else return big_string_buf; } EOF cat >getenv.c <<EOF2 extern char **__environ; char *getenv(register const char *name) { register const int len = strlen(name); register char **ep; printf(">> %s <<\n", name); for (ep = __environ; *ep != 0; ++ep) if (!strncmp(*ep, name, len) && (*ep)[len] == '=') return &(*ep)[len + 1]; return 0; } EOF2 cat >Makefile <<EOF3 all: getenv.so getenv2.so getenv.so: getenv.o @gcc -shared -Wl,-soname,getenv.so getenv.o -o getenv.so getenv2.so: getenv2.o @gcc -shared -Wl,-soname,getenv2.so getenv2.o -o getenv2.so getenv.o: getenv.c @gcc -c -fPIC getenv.c -o getenv.o getenv2.o: getenv2.c @gcc -c -fPIC getenv2.c -o getenv2.o neat: @rm -f getenv.c getenv2.c getenv.o getenv2.o Makefile EOF3 make all make neat cat >TestProgram <<EOF4 #!/usr/bin/rc # Using rc because my copy of it 'segmentation violation' to stdout # and my /bin/sh doesn't. Stock debian rc may perform differently. MAX=\$1 shift LD_PRELOAD=() for (ENV_TEST_VAR in \`{awk 'BEGIN{for(i=0;i<'\$MAX';i++){print i};exit}'}) { echo Testing \$ENV_TEST_VAR - LD_PRELOAD=./getenv2.so \$* } ##!/bin/sh #MAX=\$1 #shift #for ENV_TEST_VAR in \`awk 'BEGIN{for(i=0;i<'\$MAX';i++){print i};exit}'\` #do # export LD_PRELOAD=./getenv2.so # export ENV_TEST_VAR # \$* #done EOF4 cat >TestXterm <<EOF5 #!/bin/sh ./TestProgram 60 /usr/X11R6/bin/xterm -exec /bin/false -geometry 1x1+1+1 > log.xterm 2>&1 EOF5 cat >testprog.c <<EOF6 main() { getenv("AWAY"); if(strlen((char *)getenv("HOME")) > 50000) { raise(11); } } EOF6 gcc testprog.c -o testprog ./TestProgram 3 ./testprog > log.testprog 2>&1 rm testprog testprog.c echo Executing \"grep -3 segmentation log.testprog\" echo ++++++++++ grep -3 segmentation log.testprog echo ++++++++++ echo Make sure you have X authentification and \$DISPLAY set up and echo then run \"TestXterm\" to check for environment variable buffer echo overflows in xterm \(they\'ll show up in log.xterm if the above echo test worked\).
Current thread:
- Re: Bug in connect() ? Frank Hofmann (Mar 07)
- Re: Bug in connect() ? Frank Hofmann (Mar 10)
- Lynx/MSIE denial-of-service Doctor Who (Mar 10)
- Re: Lynx/MSIE denial-of-service Christopher Blizzard (Mar 10)
- SGI Security Advisory 19970301-01-P - IRIX 5.x and 6.x fsdump Aleph One (Mar 10)
- xterm segfaults from environment variables - too obvious David Luyer (Mar 10)
- Secuirty Hole In Older Perl Installs... Ken Robson (Mar 11)
- Re: xterm segfaults from environment variables - too obvious Alex Belits (Mar 11)
- Division of Privilege (DoP) - Potential Security Vulnerability Aleph One (Mar 11)
- runpipe v1.2 with security hole fix Aleph One (Mar 11)