loopy.org:

navigation:

home

cisco security

hybrid security

yahoo hacking

c unleashed

mp3

links

ccie

me


email loopy@loopy.org
yahoo hacking:

Preface -  This document is several years old.  I know it is not 100% accurate.  I no longer do anything with the Yahoo chat protocol, this document is left up here simply for others to use.  I hope you find this useful, however; it is unsupported.   

 

Authentication
The first packet needed contains the login/cookie values. To get everything you need for logging in, you will have to "pretend to be a browser". You will need to view:

http://204.71.201.164/config/ncclogin?.src=bl&login=name&passwd=pass&n=1

Of course, you will need to fill in the name and pass values yourself.
Simply open a TCP connection to login.yahoo.com (the 204.71.201.164) on port 80.
Send up a

"GET /config/ncclogin?.src=bl&login=name&passwd=pass&n=1
HTTP/1.0..Host: 204.71.201.179..Accept: */*"

This will open a connection to 204.71.201.164 and grab the HTML and the cookie. This returns the following packet back, as an example. The cookie is FAKE here; don't even bother... (kids)

The exact return packet varies from Yahoo over time. They add "Pragma : No cache" messages, they removed an older cookie style, etc. Basically, you always want the cookie that contains the values for v=n=l=p=r=g=. You can also get other details here for buddylist members, ignored members, identities (aliases), Yahoo e-mail status, and the current default_login id.
We get back from this:


HTTP/1.0 200 OK  Standard header
 Date: Fri, 19 Feb 1999 22:23:04 GMT
 Content-type: text/html
 Expires: Thu, 05 Jan 1995 22:00:00 GMT
 Set-Cookie: Y=v=1&n=etc..=us; path=/; domain=.yahoo.com  
 OK  
 BEGIN BUDDYLIST  
 Group1:127001
 END BUDDYLIST
 BEGIN IGNORELIST
 END IGNORELIST
 BEGIN IDENTITIES
 hangman_bot,spaceguy_21
 END IDENTITIES
 Mail=0
 Login=hangman_bot
Save what you want from that data, but you will have to save the cookie information. Just for clarity, the cookie begins at "v=" and continues to "us". The exact string you would want from my example string would be:

"v=1&n=8l5hdnt84jd0r&l=70ub34d_1ej/o&p=gdhrn2659jn00&r=12&lg=us"


Logging in & chatting

We have to send a packet to a cs server to initiate the connection. There are a few to choose from. In my example, I am using cs4.chat.yahoo.com:8001. It has its own special format to make it work, which, of course, I am going to cover.

The TCP parameters are pretty safe to let the stack handle. (i.e., flags, ack/syn, etc.) Although, I have found setting your window size to 1500 makes things run a little smoother.

The entire Yahoo scheme is based on two main ideas. One is the client/server app; the second uses information passed via HTML pages. The client/server is the heart of the beast, while HTML is used for data collection, such as room and user lists.

So lets look at the client/server model they are implementing.

This is the packet definition:

The first 4 bytes will always be 59 43 48 54 - or "YCHT" in ASCII.
The next 4 bytes are 00 00 01 00, perhaps a Yahoo version number.
The next 4 bytes will be the packet type. I will cover this in detail in a second.
The next 2 bytes will be a flag message. This is generally only needed for errors.
The next 2 bytes will be data length: TCP payload minus 16-byte YCHT header.
The rest of the packet will contain data which is dependent on packet type.


On to the packet types...

xx xx xx xx = always 4 bytes, in hex of course
00 00 00 01 = login
00 00 00 02 = logout
00 00 00 11 = room enter event
00 00 00 12 = room leave event
00 00 00 17 = invitations
00 00 00 21 = user is away/back
00 00 00 41 = speech
00 00 00 42 = think message
00 00 00 43 = emote / action
00 00 00 44 = advertisements
00 00 00 45 = private message
00 00 00 62 = ping messages
00 00 00 68 = buddylist messages
00 00 00 69 = Yahoo mail
00 00 00 70 = Yahoo message
00 00 00 80 = Grafiti (Whiteboard) Message


Login Packet - For logging in.
To log in:

A login packet: [Note: I have removed all the stack details from the 
dump; this is only the payload of the packet.]

                   59 43 : 48 54 00 00 01 00 00 00          YCHT......
 00 01 00 00 00 4A 41 73 : 6B 46 6F 72 42 6F 6F 7A    .....JAskForBooz
 65 01 76 3D 31 26 6E 3D : 38 6C 35 67 33 33 39 70    e.v=1&n=8l5g339p
 37 6A 30 66 66 26 6C 3D : 37 30 64 36 63 30 64 5F    7j0ff&l=70d6c0d_
 31 65 6A 2F 6F 26 70 3D : 6D 32 63 32 62 38 36 35    1ej/o&p=m2c2b865
 31 30 30 30 32 26 72 3D : 34 67 26 6C 67 3D 75 73    10002&r=4g&lg=us
  
The first 16 bytes are header.  Of that, the first 4 are "YCHT", then the 
next 4 will be 00 00 01 00, then the next 4 will be the packet type from 
the index above.  Sure enough, a login is 00 00 00 01.  The next 2 will be 00 00,
and the next two will be the size of the payload.  This is the entire packet's data
minus the 16-byte Yahoo header.  0x4A is 74, and there is 74 bytes of data.  

The rest of the format for the login packet is (username, 0x01, cookie).
That is all there is to it. 

Example - if we have read in our variables correctly, we can send them very easily.


To login:

ycht + ver + type + size + name + del1 + cookie

where 
ycht     = YCHT
ver      = 0010
login    = 0001
size     = len(name) + len(cookie) + len(del1)
name     = username
cookie   = cookie
del1     = 0x01


Yahoo will reply to that packet with an acknowledgement.  It looks like this:



                    59 43 : 48 54 00 00 01 00 00 00          YCHT......
  00 01 00 00 01 7F 41 73 : 6B 46 6F 72 42 6F 6F 7A    ......AskForBooz
  65 C0 80 61 68 6F 6C 65 : 2C 61 68 6F 6C 65 73 2C    e..ahole,aholes,
  61 73 73 68 6F 6C 65 2C : 61 73 73 68 6F 6C 65 73    asshole,assholes
  2C 61 73 73 77 69 70 65 : 2C 62 69 61 74 63 68 2C    ,asswipe,biatch,
  62 69 74 63 68 2C 62 69 : 74 63 68 65 73 2C 62 6C    bitch,bitches,bl
  6F 5F 6A 6F 62 2C 62 6C : 6F 77 5F 6A 6F 62 2C 62    o_job,blow_job,b
  6C 6F 77 6A 6F 62 2C 63 : 6F 63 6B 73 75 63 6B 65    lowjob,cocksucke
  72 2C 63 75 6E 74 2C 63 : 75 6E 74 73 2C 64 69 63    r,cunt,cunts,dic
  6B 68 65 61 64 2C 66 75 : 63 6B 2C 66 75 63 6B 65    khead,fuck,fucke
  64 2C 66 75 63 6B 69 6E : 67 2C 66 75 63 6B 6F 66    d,fucking,fuckof
  66 2C 66 75 63 6B 73 2C : 68 61 6E 64 6A 6F 62 2C    f,fucks,handjob,
  68 61 6E 64 6A 6F 62 73 : 2C 6D 6F 74 68 65 72 66    handjobs,motherf
  75 63 6B 65 72 2C 6D 6F : 74 68 65 72 2D 66 75 63    ucker,mother-fuc
  6B 65 72 2C 6D 6F 74 68 : 65 72 66 75 63 6B 65 72    ker,motherfucker
  73 2C 6D 75 74 68 61 66 : 75 63 6B 65 72 2C 6D 75    s,muthafucker,mu
  74 68 61 66 75 63 6B 65 : 72 73 2C 6E 69 67 67 61    thafuckers,nigga
  2C 6E 69 67 67 61 73 2C : 6E 69 67 67 65 72 2C 6E    ,niggas,nigger,n
  69 67 67 65 72 73 2C 70 : 65 64 6F 66 69 6C 65 2C    iggers,pedofile,
  70 65 64 6F 70 68 69 6C : 65 2C 70 68 61 67 2C 70    pedophile,phag,p
  68 75 63 2C 70 68 75 63 : 6B 2C 70 68 75 63 6B 65    huc,phuck,phucke
  64 2C 70 68 75 63 6B 65 : 72 2C 73 68 61 74 2C 73    d,phucker,shat,s
  68 69 74 2C 73 68 69 74 : 73 2C 73 68 69 74 68 65    hit,shits,shithe
  61 64 2C 73 68 69 74 74 : 65 72 2C 73 68 69 74 74    ad,shitter,shitt
  69 6E 67 C0 80 54 61 6E : 67 6F 62 68 C0 80 20 C0    ing..Tangobh.. .
  80 30 C0 80 31          :                            .0..1

Charming language, yes I know...  

What we are looking at is this: the first 16 bytes are the header. 
We can tell the type, being a 0x01, or login.  And we know the length of the 
packet 17F, or 383 bytes.  Next we see the username we logged in with.
Then comes a common field delimiter with Yahoo, the 0xC0 0x80.  What follows 
this is a comma-delimited list of bad words.  This means they tell the Java
client what to filter.  Weird, I would have figured hard coding it in would 
be better than sending across the wire every time.  But what do I know?
After the bad words, we have another delimiter of 0xC0 0x80, then we go into
the ignored users, which is followed by 0xC0 0x80 0x20 0xC0 0x80 0x30 0xC0 0x80 0x31
being del2 space del2 0 del2 1 -- where del2 is a 0xC0 0x80


and we are logged in...
 


Room Enter Event

This is the packet you will send up to join a room.  There is no such thing 
as leaving a room in Yahoo, only joining.  To leave a room, you simply have to 
join another.  I will cover how to handle what Yahoo returns in a minute.


                    59 43 : 48 54 00 00 01 00 00 00          YCHT......
  00 11 00 00 00 13 43 6F : 6D 70 3A 20 50 72 6F 67    ......Comp: Prog
  72 61 6D 6D 69 6E 67 3A : 32                         ramming:2


This is a very simple packet.  Basically, you set the header with the type of 0x11.
Then you set the size of the payload.  The only piece of data you need to send is the 
exact room name you wish to enter.  Eazy Peazy, huh?

Now, when you send that up, Yahoo will reply with a packet type 11h response.  
It is very important to note that you will see packets type 11h on every 
room enter event.  That means both when you enter a room, and when other users enter 
the room.  Here are two examples of common packets 11h received from Yahoo:


Example 1:  What happens when you enter a room


                    59 43 : 48 54 00 00 01 00 00 00          YCHT......
  00 11 00 00 01 62 43 6F : 6D 70 3A 20 50 72 6F 67    .....bComp: Prog
  72 61 6D 6D 69 6E 67 3A : 32 C0 80 50 69 63 6B 20    ramming:2..Pick 
  79 6F 75 72 20 6C 61 6E : 67 75 61 67 65 3A 20 43    your language: C
  2B 2B 2C 20 4A 61 76 61 : 2C 20 56 69 73 75 61 6C    ++, Java, Visual
  20 42 61 73 69 63 C0 80 : 68 74 74 70 3A 2F 2F 63     Basic..http://c
  68 61 74 2E 79 61 68 6F : 6F 2E 63 6F 6D 2F 63 2F    hat.yahoo.com/c/
  61 64 2E 68 74 6D 6C C0 : 80 30 C0 80 69 73 64 6E    ad.html..0..isdn
  67 69 72 6C 2C 61 6C 74 : 58 66 58 32 58 6F 58 2C    girl,altXfX2XoX,
  53 63 6F 6F 62 69 5F 46 : 72 65 65 42 53 44 2C 73    Scoobi_FreeBSD,s
  6F 72 63 65 72 65 72 31 : 31 32 2C 62 69 6E 61 72    orcerer112,binar
  79 62 72 79 61 6E 2C 61 : 6E 6E 69 65 33 30 32 2C    ybryan,annie302,
  44 61 53 69 72 5F 52 2C : 68 61 6E 67 6D 61 6E 5F    DaSir_R,hangman_
  62 6F 74 2C 52 6F 35 38 : 35 38 2C 48 41 4C 5F 50    bot,Ro5858,HAL_P
  4C 55 53 2C 49 74 74 79 : 5F 42 69 74 74 79 5F 54    LUS,Itty_Bitty_T
  65 65 6E 79 5F 57 65 65 : 6E 79 2C 50 43 53 53 6F    eeny_Weeny,PCSSo
  6C 6C 75 74 69 6F 6E 73 : 2C 4D 41 53 45 52 41 54    llutions,MASERAT
  49 5F 47 53 2C 72 6F 67 : 65 72 5F 77 61 74 65 72    I_GS,roger_water
  73 5F 69 6E 5F 74 68 65 : 5F 66 6C 65 73 68 2C 68    s_in_the_flesh,h
  61 64 65 73 5F 34 36 5F : 39 38 2C 4A 65 6E 6A 65    ades_46_98,Jenje
  6E 5F 32 30 30 31 2C 68 : 68 6B 5F 70 72 6F 67 31    n_2001,hhk_prog1
  2C 73 72 6E 30 32 31 30 : 37 37 2C 4A 75 6C 74 69    ,srn021077,Julti
  6D 65 2C 6F 6F 67 75 79 : 2C 63 75 64 64 6C 65 73    me,ooguy,cuddles
  73 77 65 65 74 C0 80 20 :                            sweet.. 



The format is simple.  16-byte message header, then room name, followed by the 
field delimiter of 0xC0 0x80.  The next piece is the room description, again followed
by 0xC0 0x80.   The next item is the URL for an advertisement.  This is what is 
displayed in the Java window.  The next is another delimiter, this time 0xC0 0x80
0x30 (the zero digit character, '0'), then 0xC0 0x80 again.  After that we have a 
comma-delimited list of all the users in the room.  After the entire list, we 
terminate with a 0xC0 0x80 0x20 (space bar).

Example 2:  What it looks like when another user enters the room

                    59 43 : 48 54 00 00 01 00 00 00          YCHT......
  00 11 00 00 00 52 43 6F : 6D 70 3A 20 50 72 6F 67    .....RComp: Prog
  72 61 6D 6D 69 6E 67 3A : 32 C0 80 50 69 63 6B 20    ramming:2..Pick 
  79 6F 75 72 20 6C 61 6E : 67 75 61 67 65 3A 20 43    your language: C
  2B 2B 2C 20 4A 61 76 61 : 2C 20 56 69 73 75 61 6C    ++, Java, Visual
  20 42 61 73 69 63 C0 80 : 20 C0 80 30 C0 80 62 6F     Basic.. ..0..bo
  67 69 65 6D 61 6E 37 37 :                            gieman77


It is identical to the above list, except that there is no comma-delimited list 
of users.  Basically, this is how you will see each individual user that enters
the room.


Room Leave Event

As I said, we never leave a room in Yahoo, so there is no such thing 
as a packet we send up to leave.  However, when a user in the room leaves, 
we do get notified.  That notification looks like this:


                    59 43 : 48 54 00 00 01 00 00 00          YCHT......
  00 12 00 00 00 30 43 6F : 6D 70 3A 20 4C 69 6E 75    .....0Comp: Linu
  78 2C 20 46 72 65 65 42 : 53 44 2C 20 53 6F 6C 61    x, FreeBSD, Sola
  72 69 73 3A 31 C0 80 73 : 77 65 65 74 5F 74 77 65    ris:1..sweet_twe
  65 74 79 35 35 35       :                            ety555


The breakdown of this packet is quite simple.  16-byte header field with packet 
type 0x12, and a payload of room name, followed by the delimiter 0xC0, 0x80.
Then comes the name of the leaving user.




Speech packet


The following packet is how we send and receive the normal text part of chat.
To assemble a message and send it up, follow this format:


                    59 43 : 48 54 00 00 01 00 00 00          YCHT......
  00 41 00 00 00 1C 43 6F : 6D 70 3A 20 50 72 6F 67    .A....Comp: Prog
  72 61 6D 6D 69 6E 67 3A : 32 01 68 65 79 20 61 6C    ramming:2.hey al
  6C 20                   :                            l 


This is another simple packet.  Simply set the header details using packet type
0x41 and use the payload of room name, delimiter of 0x01, followed by the text you
wish to send.  In this example, I have said "hey all" to the room Comp: Programming:2.



You get acknowledgement by having your message returned back to you in the same way 
all messages from other users are passed to you.  You will need to parse the 
following packet to read what others say in the room. 


                    59 43 : 48 54 00 00 01 00 00 00          YCHT......
  00 41 00 00 00 25 43 6F : 6D 70 3A 20 50 72 6F 67    .A...%Comp: Prog
  72 61 6D 6D 69 6E 67 3A : 32 C0 80 31 32 37 30 30    ramming:2..12700
  31 C0 80 68 65 79 20 61 : 6C 6C 20                   1..hey all 



Looks pretty straightforward?   It is.  There is the 16-byte header followed by 
the room name.  After that is the delimiter 0xC0 0x80, then the username of who 
said the text, then the delimiter again of 0xC0 0x80, followed by the text.




Private Message Packet


The following packet is how we send and recieve PM/IM parts of chat.
To assemble a message and send it up, follow this format:



                    59 43 : 48 54 00 00 01 00 00 00          YCHT......
  00 45 00 00 00 15 31 32 : 37 30 30 31 01 45 6C 61    .E....127001.Ela
  69 6E 65 55 4B 01 68 65 : 6C 6C 6F                   ineUK.hello



This is another simple packet.  Simply set the header details using packet type
0x45 and use the payload of your username, delimiter of 0x01, followed by the 
username of the person you wish to send to.  Again, this is followed by the delimiter 
of 0x01.  Then comes the text you want to send them.  In this example, I have said 
"hello" to ElaineUK.

If the other person responds back, or if any other person PM's you, this will be 
how you parse the data.  It will come in this format:


                    59 43 : 48 54 00 00 01 00 00 00          YCHT......
  00 45 00 00 00 9E 63 61 : 70 74 75 72 65 64 5F 31    .E....captured_1
  C0 80 31 32 37 30 30 31 : C0 80 1B 5B 23 30 30 30    ..127001...[#000
  30 46 46 6D 1B 5B 23 30 : 30 30 30 46 46 6D 69 20    0FFm.[#0000FFmi 
  63 61 6E 74 20 67 65 74 : 20 61 20 70 6D 20 62 61    cant get a pm ba
  63 6B 20 74 68 6F 75 67 : 68 2E 2E 69 66 20 79 6F    ck though..if yo
  75 20 77 61 6E 74 20 74 : 6F 20 70 6D 20 6D 65 2E    u want to pm me.
  2E 69 20 68 61 76 65 20 : 74 6F 20 63 68 61 6E 67    .i have to chang
  65 20 63 6C 69 65 6E 74 : 73 2E 2E 2E 3F 20 69 73    e clients...? is
  20 6E 6F 20 70 72 6F 62 : 20 74 6F 20 64 6F 20 74     no prob to do t
  68 61 74 C0 80 31 35 31 : 31 32 38 39 36 35 31 3A    hat..1511289651:
  31 34 37 30             :                            1470


This is a PM from "captured_1" to me.  There is the 16-byte header followed by 
the person who is sending the PM.  After that is the delimiter 0xC0 0x80, then my
username.  Again we have a delimiter of 0xC0 0x80, then the text.  Then the 
delimiter again of 0xC0 0x80, followed by some weird-looking numbers.  In this case, 
the 1511289651:1470.  We can safely ignore this number.  It is a session identifier.  


 

Note-
This is not a complete list, but it should be plenty to get someone started 
on making a client.  Once you have all of this in place, it should be almost 
trivial to capture the other packets and decode them based on the information 
I have laid out here.  Good luck...

 
 

Proverbial Example Code

Just 2 simple functions to show *one way* to build a message.
Specifically, this shows the login(0x01) and ping(0x62) messages.


/*   A function to connect to the chat server. 
 * 
 *
 *  int sockfd = the socket file descriptor on unix systems, 
 *               win32 boxes would use SOCKET sockfd as the 
 *               prototype.  This should be already connected to 
 *               a csX.chat.yahoo.com box on either 8001 or 8002.
 *  char *user = pointer to char of the username
 *  char *cooky = a pointer to char of the cooky to be used
 *
 * Function will return 0 if success, -1 if error
 */

int YahooChatConnect(int sockfd, char *user, char *cooky)
{
  char packetData[512]={0};
  unsigned long pktLen, *ptr;

  strcpy( packetData, "YCHT" );
  ptr = (unsigned long *) &packetData[4];
  *ptr = htonl( 0x00000100 );
  ptr = (unsigned long *) &packetData[8];
  *ptr = htonl( 0x00000001 );
  pktLen = strlen(user) + 1 + strlen(cooky);
  ptr = (unsigned long *) &packetData[12];
  *ptr = htonl( pktLen );
  strcpy( &packetData[16], user );
  packetData[16 + strlen(user)] = 0x01;
  strcpy( &packetData[17 + strlen(user)], cooky );
  if(send(sockfd, packetData, pktLen + 16, 0) != (int)pktLen + 16)
   return -1;

    return 0;
}






/*   A function that keeps the Yahoo session open.  Without sending this
packet 
 *   at LEAST every 30 minutes, yahoo will disconnect you.  The java
client sends it 
 *   every 15 minutes, I send it every 10.  
 *
 *
 *
 *  int sockfd =   the socket file descriptor on unix systems, 
 *                 win32 boxes would use SOCKET sockfd as the 
 *                 prototype.  This should be already connected to 
 *                 a csX.chat.yahoo.com box on either 8001 or 8002.
 *
 * Function will return 0 if success, -1 if error
 */

int YahooPing(int sockfd)
{
  char PacketData[16]={0};
  unsigned long *ptr;

  strcpy( PacketData, "YCHT" );
  ptr = (unsigned long *) &PacketData[4];
  *ptr = htonl( 0x00000100 );
  ptr = (unsigned long *) &PacketData[8];
  *ptr = htonl( 0x00000062 );
  ptr = (unsigned long *) &PacketData[12];
  *ptr = htonl( 0x00000000 );
  if(send(sockfd, packetData, 16, 0) != (int)16)
   return -1;

return 0;
}