TUCoPS :: Windows :: aimpro~1.txt

AOL Instant Messenger (AIM) protocol information and password decoder.


[ http://www.rootshell.com/ ]

Author: james@foo.org
http://www.foo.org/aim/

A quick note: please, do not kick and scream if this is old news; I don't
 really watch these things and this is the first I've seen.

 AOL Instant Messenger doesn't seem to make too much a point of security. 
 Security really isn't very friendly though, and it sure would slow a large
 system like AOL down.

 I've successfully signed on to the AIM network illicitly using a couple
 different methods. You may say "So? This is just a chat network." That
 excuse doesn't work, look at how many people use it every day.

 First, the hash that AIM uses to "encrypt" user passwords going over the
 network is awful. I can only assume that it's not meant to provide any
 security at all, in which case .. *sigh*

 An AIM password must be between 4 and 16 characters. I got this from the
 AIM "Change your Password" screen. When the AIM client signs on to the
 authorizer, the encoded password presented is the same length as the
 decoded form. After a little number crunching, I've found that the hash
 used to encode the password looks like this:

 u_char hash[16] = { 243, 179, 108, 153, 149, 63, 172, 182,
                     197, 250, 107, 99, 105, 108, 195, 154 };

 The user password is simply XOR'ed with this. All the server has to do is
 XOR this hash with the encoded password to get the original text. In other
 words:

         for (i = 0; i < 16; i ++)
           crypt_pw = cleartext_pw[i] ^ hash[i];

 As far as I can tell, this data is static; it's used by all the clients
 I've played with anyway (AIM for Windows '95 and AIM for Java version 1.2).
 It may be different for different versions of the client, but the client
 sends it's version information over the wire too so this is a moot point.

 If you sniff a user's connection to the authorizer you have yourself the
 user's cleartext password and can do with it what you will.  Impersonate
 them, deny them access to AIM, etc.

 There are a number of alternative ways to do this simple password
 authentication, and not all of them require fancy (read: slow) encryption.

 This next method isn't as sexy as the previous, but it works nonetheless.

 Once the AIM client has authenticated once, it never has to do it again. 
 The server sends it a cookie, much like a Kerberos KDC gives a client a
 TGT. The cookie lets a user signon quickly to another service.

 But what happens if you can get that cookie? You can steal a user's cookie,
 flood the user or reset their connection so that they can't reach the
 destination server, and login with their cookie yourself. I have only tried
 this with the BOS server; it will probably work just as well with the ad
 servers, chat & chatnav servers, and the directory servers. I assume they
 all run basically the same server software, with software modules that
 plug-in to provide the various services.

 The server's appear to be doing some sort of traffic filtering at the
 transport level. If my host hasn't been given a cookie, it won't let me
 connect to any services. This traffic filtering does not seem to be tied to
 the cookie however; as long as you have a legitamate reason for connecting
 to the server it will let you on.

 Wouldn't it be fun to sneak up on an AOL staff person, sniff their traffic,
 and find out if they have access to any "hidden" commands? :-)

-----------------------------------------------------------------------------

I have put together the following set of notes based on packet captures,
debugging information obtained from AIM/Java, the AIM/Java developer pages,
and a lot of guesswork. Read at your own risk. So how does it work, anyway?


1. FLAP, the low-level communications protocol

FLAP is the low-level communication protocol used by AOL Instant Messenger.
It is encapsulated in TCP -- AOL may also encapsulate it in other
transports, but I have not seen this myself.

The FLAP header looks like this:

  struct FLAP {
    u_char   id;        /* a literal '*' */
    u_char   channel;   /* communications channel */
    u_short  sequence;  /* sequence number */
    u_short  length;    /* length of the data portition of the datagram */
  };

  "id" is a literal asterisk character ('*'), presumeably to make the
  protocol quick to identify.

  "channel" is a numeric value, which allows you to multiplex FLAP. You can
  think of these channels like TCP or UDP port numbers.

  "sequence" is just that, a sequence number. FLAP datagrams must arrive
  in sequence, if not the connection may be terminated (there is no facility
  to handshake and re-send).

  "length" is the length of the data portion of the datagram (that is, the
  datagram not including the 6-byte header).

I have identified the following FLAP channels:

  1 - Signon, Used to sign onto a server.
  2 - SNAC Data, Used to send data back and forth between the client and
      server.
  3 - Error, FLAP-related errors.
  4 - Signoff, Used to sign off a server.

The FLAP has some slick features, although I have yet to put all of them
through their paces. These include:

  * Migration -- "transparently" move a session to another server.


2. SNAC, the higher level communications object

SNACs are the communications objects passed back and forth between the
OSCAR clients and servers. SNAC's come in a variety of flavours, and they
are broken up into families; in each family there are a variety of subtypes.

  struct SNACHeader {
    u_short  family;    /* SNAC family */
    u_short  subtype;   /* SNAC famiy subtpe */
    u_char   flags[2];  /* optional flags */
    int      reqid;     /* req(uest?) ID */
  };

  "family" SNAC family id. SNAC's are grouped into families, generally
  by the type of service they provide.

  "subtype" SNAC subtype. This identifies exactly what this SNAC is and does.

  "flags" optional flags. I'm unsure what exactly this does, I haven't
  seen it used for anything.

  "reqid" req(uest?) ID. A "unique" ID associated with the SNAC. This seems
  to be randomly generated. Reqid's from a server are or'ed with the value
  -2147483648. Server ID's count up to zero rather than from.

I have documented the following SNAC families and types. C denotes a message
sent from the client, S from the server:

Family 1, Generic service controls
  1: (C,S) Error
  2: (C) Client is online, and ready to do stuff
  3: (S) Server is online, waiting for the client
  4: (C) Request a new service - the server will redirect the client to
     a new host where a specific service is available (Advertisements,
     Directory, etc.)
  5: (S) Redirect - the server sends the client a new host where a specific
     service is available
  6: (C) Request rate information - request information regarding how
     fast the client can send out SNAC's
  7: (S) Rate information - how fast a client can send out SNAC's
 14: (C) Request information on our nickname
 15: (S) Information on our nickname
 18: (S) Migration notice

Family 2, Locate Service
  1: (C,S) Error
  2: (C) Request rights information
  3: (S) Rights information
  4: (C) Set user information
  5: (C) Request user information
  6: (S) User information

Family 3, Buddylist
  1: (C,S) Error
  2: (C) Request rights information
  3: (S) Rights information
  4: (C) Add buddy to buddylist
  5: (C) Remove buddy from buddylist
 11: (S) Buddy has signed on
 12: (S) Buddy has signed off

Family 4, IM
  1: (C,S) Error
  2: (C) Add ICBM parameter
  3: (C) Remove ICBM parameter
  4: (C) Request parameter information
  5: (S) Parameter information
  6: (C) Message from the client
  7: (C) Message to the client
 11: (S) Server missed calls

Family 5, Advertisements
  1: (C,S) Error
  2: (C) Request advertisements
  3: (S) Advertisement data

Family 6, Invitation (Client<->Client)
  1: (C,S) Error

(I'm taking a break here, time for a snack)

Family 7, Administration

Family 8, Popups

Family 9, BOS-specific

Family 10, User Lookup

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