Re: Solaris libc exploit

From: Craig Johnston (cajat_private)
Date: Sun May 23 1999 - 12:00:52 PDT

  • Next message: Ryan Russell: "Re: NetBSD Security Advisory 1999-010"

    On Sat, 22 May 1999, Oystein Viggen wrote:
    
    > On Sat, 22 May 1999, UNYUN@ShadowPenguinSecurity wrote:
    >
    > > libc overflows when that handles LC_MESSAGES.
    > > So, If you set the long string to LC_MESSAGES and call
    > > /bin/sh, the core file is dumped.
    > > This is serious problem.
    >
    > Didn't work on my Solaris2.6/sparc box.
    > It just said "Illegal instruction" when using /bin/passwd and segfaulted
    > when using /bin/su.
    
    My guess is that this is architecture-dependent.  It works on my sun4m
    boxes and not the ultrasparcs.  It looks like it could be made to work
    with some tweaking if you can get a SIGILL.  I'd assume the script
    kiddies have one that works on your platform.
    
    This is a really bad one.  Here's my ugly temporary fix:
    
    Make a directory, /subin, and move all setuid root binaries into it.
    Remove the setuid bits.  Compile the following c program and put it
    in place of the old setuid root binaries, with the setuid bit set.
    
    I spent a small amount of time on this, so it itself may be exploitable.
    Use with caution.
    
    --- cut here ---
    #include <stdio.h>
    #define MAX_ENV 255
    #define HOLDING_PEN "/subin/"
    #define BSIZE 1024
    
    /*
       quick and dirty wrapper to defeat overflowing of libraries with
       environment variables
       5/99, Craig Johnston, cajat_private
       this comes with no guarantees except "it seems to work here."
    
       When is security going to become a priority at Sun?
    */
    
    int main(int argc, char **argv, char **envp)
    {
        char *p, *q, buf[BSIZE];
        int  i;
    
        while (*envp) {         /* whack off long env variables */
            for (p = *envp, i = 0; *p ; ++p, ++i)
                if (i >= MAX_ENV) {
                    *p = '\0';
                    break;
                }
            ++envp;
        }
        for (p = q = argv[0]; *p; ++p)  /* get basename */
            if (*p == '/')
                q = p + 1;
    
        snprintf(buf, BSIZE, "%s%s", HOLDING_PEN, q);
        execve(buf, argv, envp);
        printf("exec() failed, bailing!\n");
        exit(1);
    }
    
    --- cut here ---
    
    --
    Craig Johnston
    cajat_private
    



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