MySpaceIM Protocol Reverse Engineering

Document started on 20070329 by Jeff Connelly for a Google Summer of Code 2007 Application. Information in this document is entirely the result of original research; it is not endorsed by MySpace or NewsCorp.

Important: This document will no longer be maintained, in favor of the Pidgin Developer Wiki MySpaceIM page.

Hosts

Connect to im.myspace.akadns.net port 1863 TCP.

If port 1863 is not accessible, the client will try to connect using ports 6660,6661,6662,6665,6668,6669,0080 and 0443 in succession. If successful, the port will be stored in HKCU\Software\MySpace\IM\LastConnectedPort and used for further connections.

User

Users are identified by several means:

Message Structure

Tokens are separated by backslashes, which alternate as name, value, name, value, etc. For example, a complete message would be:

\lc\1\nc\AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==\id\1\final\\

This message has the following information:

 Name    Value
 =============
 lc      1
 nc      AAAA...
 id      1
 final   (empty)

The end of a message is marked with a key named final and an empty value.

The following data types are present:

Integers    These are just stored as ASCII
Text        Also ASCII
Binary      Base64 encoded
Boolean     Presence of the key indicates 'true', absense 'false'
Dictionary  Multiple key=value's, separated by \x1c (field usually named 'body')
List        Items separated by '|'

Login challenge

The client connects to the server (as described in the Hosts section), and the server immediately sends a "login challenge" message. The important part of this challenge message is the binary nonce field, named nc. The client computes its login response using this field.

How to derive response from nc

First note, nc is 0x40 bytes and it is split into two parts, after being base64-decoded:

SHA-1 hash the following concatenated together:

  1. 0x14 bytes - the SHA-1 hash of the password as utf16le
  2. 0x20 bytes - nonce2

Just to be clear, there are two hashes computed above.

Using the first 0x10 bytes of the hash value as an 128-bit RC4 key, encrypt the following concatenated together:

  1. nonce1
  2. username, in ASCII
  3. 00 00 00 00
  4. 1 byte = the number of IPv4 addresses this host has
  5. IPv4 addresses of host's network interfaces in network order

The network interface addresses are obtained using the Win32 GetIpAddrTable API call. They should be the actual interface IPs on the system, even if they are RFC1918 private addresses. The server most likely uses these addresses to determine if a connection can be directly initiated to the host, or if it must pass through some kind of NAT device.

After encrypting, base64 the encrypted message to obtain the value for response.

High-level summary:

    response = encrypt(key=hash(hash(pw) + nc2), data=nc1+username+IP_list)
where hash=SHA-1, encrypt(key, data)=RC4. Fairly simple, but took some time to reverse-engineer.

Implementations

The login procedure, as described above, is implemented in msimlogin (251 lines of C++), using similar Win32 CryptoAPI calls that MySpaceIM uses. msimlogin computes response for a specific test vector (username/password: testuser/testpw, as well as certain network interfaces) and verifies the result is correct. No network communication is performed.

Also implemented in Python myc.py—this program is higher-level, in that it uses the simpler PyCrypto library instead of Win32 API calls. This script accepts a username/password on the command line and connects to MySpaceIM's servers to get a login response. Base64 conversion is performed where needed. New tests to the protocol will likely be tested in this Python script first.

The login procedure will (hopefully) ultimately be implemented in a Gaim protocol plugin, using the appropriate libraries and the C programming language.

Login Message

After computing response client then the login message, as follows:

\login2\%d\username\%s\response\%s\clientver\%d\reconn\%d\status\%d\id\1\final\

Where %s and %d are placeholders. The %s in \response\%s\ will be replaced by the base64'd response as described in the previous section, for example. The following values are acceptable to cause the MySpaceIM servers to respond:

The server quickly (even before waiting for the client response, above) sends a 'persistr' message, with various information. The 'body' field contains key=value pairs, separated by the \034 characters (the "dictionary" type described earlier in this document). It contains various parameters for the client:

Login Success Message

In response to the "login response message", the server will send another message. If the login failed, a message will say so. If it succeeded, various information will be sent. (TODO: describe these).

Followed by: (TODO)

TODO: describe the 3 additional Challenge,ChallengeData messages. Web challenge.

FROM SERVER - web challenge

\persistr\\cmd\257\dsn\17\uid\3656574\lid\26\rid\20015794\body\Challenge=2437569020 \034ChallengeData=CTtWmfBzuq4rxoe5GJhk0bfNp7tGQljzsIKaTBOARc21898xR26Y4qs9MBohcn+FlnD/ 1+T9KL/1Ftuo9vd3elbw==\034Challenge=2437569023\034ChallengeData=3PZg0J

on home.myspace.com, client does:

GET /Modules/IM/Pages/UrlRedirector.aspx?challenge=8408570-3656574-267577152&response=5CiUQCLEkz1ryhNZpv/IPxdmXS1tNnZaDk/kGx4cQxM&target=searchfriends&targetid=3656574 HTTP/1.1\r\n

on collect.myspace.com, client does:

GET /index.cfm?fuseaction=im.friendslist&setonlinenow=1&setrsi=1&MyToken=6451502b-0ba5-4805-91b3-b5925d8f1747 HTTP/1.1\r\n

Errors

Error messages:

Known errors:

Pick Your Username

If you login without a username/IM name, MySpaceIM will prompt you to select one, very cautiously warning you cannot change it. To check if a username is available, client sends (similar to 'buddy search' message):

The server replies with:

User Information Messages

Both messages from server, sent upon connect for each user on buddy list. \bm\100\f\6221\msg\|s|1|ss|:-)|ls||ip|0|p|0\final\ \bm\100\f\15187323\msg\|s|0|ss|Offline\final\

User status message:

  • final \body\UserID=3656574\034ImageURL=http:/1/1myspace-513.vo.llnwd.net/100928/131/151/1928941513_m.jpg \034DisplayName=Jeff\034UserName=3656574\034BandName=\034SongName=\034TotalFriends=69

    User information message:

    Keep Alives

    These messages are simply:

    Sent periodically to keep connection alive.

    Buddy Management

    Commands related to your buddy list.

    Buddy Search

    Accessed from "Add" button on official MySpaceIM client. Before a buddy can be added, the buddy must be found. The user enters a username or email address, and the client contacts the server to obtain the numeric user ID used internally throughout the protocol. Buddy search message from client:

    Server responds with:

    Add Buddy

    The client also updates the blocklist, removing from block list (b-) and adding to accept list (a+).

    Group Manangement

    cmd=258 (group info)

    Example messages:

    \persistr\\cmd\258\dsn\2\uid\3656574\lid\16\rid\64\body\GroupName=MySpaceIM Rooms\034Position=2\034GroupFlag=196612\final\\persistr\\cmd\258\dsn\2\uid\3656574\lid\16\rid\65\body\GroupName=Recent Contacts\034Position=3\034GroupFlag=196610\f

    \persistr\\cmd\257\dsn\0\uid\3656574\lid\2\rid\86\body\ContactID=6221\034ContactID=6221\034Headline=:-)\034Position=1\034GroupName=IM Friends\034Visibility=1\034AvatarUrl=\034ShowAvatar=False\034LastLogin=128182824000000000\034IMName=\034N

    \persistr\\cmd\257\dsn\0\uid\3656574\lid\2\rid\87\body\ContactID=15187323\034ContactID=15187323\034Headline=\034Position=0\034GroupName=Recent Contacts\034Visibility=1\034AvatarUrl=\034ShowAvatar=True\034IMName=\034NickName=\034NameSelect=

    Comes predefined with groups (ways to organize contacts):

    Block List

    Sent from client to server, to tell server to not relay messages from these users:

    Delete Buddy

    The client also sends a persist message and updates the block list when deleting a buddy. Example message sequence:

    Actions and Instant Messages

    Example messages:

    Fields:

    Instant messages are sent by specifying the user's numeric ID in the 't' field, and received with the sender's numeric ID in the 'f' field.

    Message Markup Code

    Messages are sent with a 'bm' of '1'. Outgoing messages have the to ('t') field set to the numeric user ID, incoming messages have 'f' (from) se.

    Message text is formatted using "tags", not quite like HTML. Tags and attribute names are single letters to save space. Attributes are either quoted with ' or `. For unknown reasons, the client uses ' but the server translates it to `.

    Tags end as /(number)(tag), for example /1b, /1c, /1f, /1p. I suspect the number could be the nesting level or how many tags to close (not investigated).

    Example: <f f='Times' h='16'><c v='black'><b v='white'>hello</1b></1c></1f></1p>

    Zaps

    "Zaps" are actions, sent with bm=121, with msg text of !!!ZAP_SEND!!!=RTE_BTN_ZAPS_n, where n is the zero-based index in the array. 0 is just a regular "zap", up to 9 which is "raspberry" (whatever that means...)

    Status

    For bm=100, 'f' is set to the numeric user ID of the user the message is from. 'msg' is set to an array string such as |s|0|ss|Offline (user is offline).

    Set Status

    Logout

    Simply: