Bugtraq mailing list archives
Re: L0pht Advisory: Solaris libc - getopt(3)
From: adam () MATH TAU AC IL (Adam Morrison)
Date: Tue, 28 Jan 1997 19:17:32 +0200
Super Ugly kludge fix: If you don't have the source code available (like most of us), one solution is to use adb to change the name for getopt with something like getopz, yank a publicly available getopt.c, and put it in place of getopt. If anyone can tell me how to yank the object files out of dynamically linked libraries it would be appreciated as you suffer performance hits among larger problems by doing this from the static library Sun provides as, of course, it is not PIC code.
If you want to rebuild libc, a PIC version exists in /usr/lib/pics. $ ar x /usr/lib/pics/libc_pic.a $ rm getopt.o $ cc -K pic -c getopt.c $ cc -o libc.so.1 -h libc.so.1 -G \ -Wl,-f,'/usr/platform/$PLATFORM/lib/libc_psr.so.1' \ `lorder *.o | tsort 2>/dev/null` -ldl $ su Password: # /usr/sbin/static/mv /usr/lib/libc.so.1 /usr/lib/libinsecure-c.so.1 # /usr/sbin/static/cp libc.so.1 /usr/lib Alternatively, here's a trick I've been using on other library holes where source replacements weren't so easy to come by. The usual disclaimers of how this might render your system unbootable apply. Also note the example below uses the Sun cc compiler, not gcc. Thanks to the zany Sun linker, it's possible to interpose on insecure library functions. You can easily see how this example applies to similar holes, ie the gethostbyname() resolver hole. (I should also note that as with all oh-so-technically advanced buffer overflows, the exploit for, say, passwd(1) is a short diff to the exploit Jeremy Elson posted here recently.) PS: I would love to hear of a less fidgety way of doing this. First, create a stub libc. # whoami root # >stub.c # ls -l stub.c -rw-r--r-- 1 root wheel 0 Jan 28 15:04 stub.c # mkdir /usr/lib/insecure # cc -o stub -K pic -G -h /usr/lib/insecure/libc.so.1 stub.c "c.c", line 1: warning: empty translation unit # dump -Lv stub | grep SONAME [3] SONAME /usr/lib/insecure/libc.so.1 # cp stub /usr/lib/insecure/libc.so.1 Plug the hole. # cat getopt.c #include <stdlib.h> #include <dlfcn.h> int getopt(int argc, char *const *argv, const char *args) { int (*real_getopt)(int, char *const *, const char *) = dlsym(RTLD_NEXT, "getopt"); int av0len; if (argv && argv[0]) { av0len = strlen(argv[0]); if (av0len > 256) argv[0][255] = '\0'; } if (real_getopt) return ((*real_getopt)(argc, argv, args)); else return (-1); } Replace the insecure libc; if you mess this up you may need to reboot from CDROM or the network and restore the damage. # cc -K pic -G -h libc.so.1 getopt.c /usr/lib/insecure/libc.so.1 "getopt.c", line 10: warning: assignment type mismatch: pointer to function(int, pointer to const pointer to char, pointer to const char) returning int "=" pointer to void # ls -l a.out -rwxr-xr-x 1 root wheel 4928 Jan 28 15:06 a.out # dump -Lv a.out | grep NEEDED [1] NEEDED /usr/lib/insecure/libc.so.1 # /usr/sbin/static/mv /usr/lib/libc.so.1 /usr/lib/insecure # /usr/sbin/static/cp a.out /usr/lib/libc.so.1 # rm /usr/lib/libc.so # ln -s /usr/lib/insecure/libc.so.1 /usr/lib/libc.so If you ever want to back this out, use the static mv to move /usr/lib/insecure/libc.so.1 to /usr/lib and make the symlink /usr/lib/libc.so point to it. Verify that dynamically linked executables work and that the dependencies are in order. # pwd /tmp/foo # ldd /usr/lib/libc.so.1 /usr/lib/insecure/libc.so.1 libdl.so.1 => /usr/lib/libdl.so.1 # ldd /bin/ls libw.so.1 => /usr/lib/libw.so.1 libintl.so.1 => /usr/lib/libintl.so.1 libc.so.1 => /usr/lib/libc.so.1 libdl.so.1 => /usr/lib/libdl.so.1 /usr/lib/insecure/libc.so.1 Et voila. % cat getopt-test.c #include <stdio.h> main(int argc, char **argv) { char buf[4096]; memset(buf, 'A', 4096); buf[4095] = '\0'; argv[0] = buf; (void) getopt(argc, argv, "a"); } % cc getopt-test.c % ./a.out -x AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: illegal option -- x % ./a.out -x |& sed 's/:.*$//' | wc -c 256 adam?
Current thread:
- L0pht Advisory: Solaris libc - getopt(3) Jonathan Wilkins (Jan 26)
- Re: L0pht Advisory: Solaris libc - getopt(3) Adam Morrison (Jan 28)
- Vulnerability with Large UID's and GID's in HP-UX 10.20 Aleph One (Jan 28)
- Pilot Private Data Not So Private Aleph One (Jan 28)