Difference between revisions of "Steam Friends"

From IMFreedom Wiki
(→‎Encryption: Added information about encryption)
(→‎External Links: Added some external links)
Line 111: Line 111:
 
* Wikipedia page about Steam [http://en.wikipedia.org/wiki/Steam_%28content_delivery%29]
 
* Wikipedia page about Steam [http://en.wikipedia.org/wiki/Steam_%28content_delivery%29]
 
* Ticket requesting support for the Steam protocol within libpurple [http://developer.pidgin.im/ticket/3987]
 
* Ticket requesting support for the Steam protocol within libpurple [http://developer.pidgin.im/ticket/3987]
 +
* December 2007 Pidgin mailing list thread [http://pidgin.im/pipermail/devel/2007-December/thread.html#4263]
 +
* February 2008 Pidgin mailing list thread [http://pidgin.im/pipermail/devel/2008-February/thread.html#4876]
 +
* Valve Developer Information about ICE [http://developer.valvesoftware.com/wiki/ICE]

Revision as of 21:25, 16 February 2008

TOC

Introduction

Steam Friends is an instant messaging protocol that is built into Steam, a game content delivery system developed by Valve. This page details the protocol specification for Steam Friends as was ascertained though reverse-engineering.

Connection

Steam Friends uses UDP on port 27017. Connections have been made to the following servers:

  • 68.142.64.165
  • 68.142.64.164

Layers

On top of UDP, another layer is implemented to keep track of sequencing and splitting of packets. This layers prepends every packet with the following 36-byte structure:

Steam Protocol Header Fields
Offset 0x00 0x04 0x08 0x0C
0x00: "VS01" type destination source
0x10: sequence # last rcv. # split count seq. # of 1st packet
0x20: data length

Note: These values are little-endian, which is not network order.

Steam Protocol Header Fields Description
Field Type Length (bytes) Description
"VS01" string (non-null terminated) 4 the 4 characters 'V', 'S', '0', '1' (0x56, 0x53, 0x30, 0x31)
type bit-field 4 a bit field describing the type of packet (needs further analysis)
destination integer 4 the destination ID of the packet
source integer 4 the source ID of the packet
sequence # integer 4 the packet's sequence number. server and client keep track of own numbers
last recv. # integer 4 the sequence number of the last packet received
split count integer 4 the number of packets the current message was split in to
seq. # of 1st packet integer 4 the sequence number of the first packet for current message
data length integer 4 the length of the data that follows

Login sequence

  1. Client initiates the login by sending a type '0x00020004' packet to the server with no data, and sequence # 1
00:   56 53 30 31 00 00 01 04 00 02 00 00 00 00 00 00
10:   01 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00
20:   00 00 00 00
  1. Server responds with type '0x04020004' (first one ORed with 0x04000000) with 4 bytes of data attached (although the data length field is 0), sequence: 1, last: 1, src: 0x00000200
00:   56 53 30 31 04 00 02 00 00 00 00 00 00 02 00 00
10:   01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00
20:   00 00 00 00 f9 8d 22 25
  1. Client responds with type '0x04030004' (previous ORed with 0x00010000) with 4 bytes of data attached (with 4 as data size). That 4 bytes corresponds to the 4 bytes that the server sent XORed with 0xA426DF2B. sequence: 2, last: 1, dest: 0x00000200
00:   56 53 30 31 04 00 03 04 00 02 00 00 00 00 00 00
10:   02 00 00 00 01 00 00 00 01 00 00 00 02 00 00 00
20:   04 00 00 00 d2 52 04 81
  1. Server responds with type '0x04040000' (possibly as some sort of ACK). sequence: 2, response: 2, dest: this becomes the source for all subsequent packets from client
00:   56 53 30 31 00 00 04 04 00 34 7e fe 00 02 00 00
10:   02 00 00 00 02 00 00 00 01 00 00 00 02 00 00 00
20:   00 00 00 00
  1. Server sends type '0x0406001c' with the following data stream: "17 05 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 01 00 00 00 01 00 00 00". sequence: 3, last: 2
00:   56 53 30 31 1c 00 06 04 00 34 7e fe 00 02 00 00
10:   03 00 00 00 02 00 00 00 01 00 00 00 03 00 00 00
20:   1c 00 00 00 17 05 00 00 ff ff ff ff ff ff ff ff
30:   ff ff ff ff ff ff ff ff 01 00 00 00 01 00 00 00
  1. Client responds type '0x040600a4' with the following data stream: "18 05 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 01 00 00 00 80 00 00 00 [128 byte random string (1024-bit encryption key, RSA?), xx] [CRC32 of preceding 128 bytes, cc] 00 00 00 00".
00:   56 53 30 31 a4 00 06 04 00 02 00 00 00 34 7e fe
10:   03 00 00 00 03 00 00 00 01 00 00 00 03 00 00 00
20:   a4 00 00 00 18 05 00 00 ff ff ff ff ff ff ff ff
30:   ff ff ff ff ff ff ff ff 01 00 00 00 80 00 00 00
40:   xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
50:   xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
60:   xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
70:   xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
80:   xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
90:   xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
a0:   xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
b0:   xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
c0:   cc cc cc cc 00 00 00 00
  1. Server responds with type '0x04060018' with the following data: "19 05 00 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 01 00 00 00"
00:   56 53 30 31 18 00 06 04 00 34 7e fe 00 02 00 00
10:   04 00 00 00 03 00 00 00 01 00 00 00 04 00 00 00
20:   18 00 00 00 19 05 00 00 ff ff ff ff ff ff ff ff
30:   ff ff ff ff ff ff ff ff 01 00 00 00

Encryption

The encryption method has yet to be determined. There was some discussion on the pidgin mailing list that they might use the ICE (Information Concealment Engine) for encryption. According to the Valve Developer pages, ICE is used to encrypt script files used for games, so it does not seem completely unreasonable that they could use it for their communication protocol, however, it doesn't necessarily imply that they do use it for encryption of network data.

Dissecting the steamclient.dll, there doesn't seem to be anything obvious that would identify the use of ICE. However, there are several references to the Crypto++ Library:

  • CryptoPP.
    • AlgorithmParametersBase
    • IKeyCallback
    • RSAFunction
    • CipherModeBase: GetNextIV() must be called on an encryption object
  • CCrypto::RSAEncrypt
  • CCrypto::HexDecode

In addition, there is some thought that the 128 bytes transferred from the client to the server (see above) might be a 1024-bit RSA public encryption key.

External Links

  • Valve developer wiki page for Steam Friends [1]
  • Wikipedia page about Steam [2]
  • Ticket requesting support for the Steam protocol within libpurple [3]
  • December 2007 Pidgin mailing list thread [4]
  • February 2008 Pidgin mailing list thread [5]
  • Valve Developer Information about ICE [6]