####################################################################### Title: Explanation of the authentication method used by the Gamespy CD-Key SDK 0.1 Author: Luigi Auriemma e-mail: aluigi@autistici.org web: aluigi.org ####################################################################### 1) Introduction 2) Explanation 1: Client <--> Server 3) Example 1 4) Explanation 2: Server <--> Master server 5) Example 2 ####################################################################### --------------- 1) Introduction --------------- The Gamespy Cd-key SDK is used by some games as Halo, Battlefield 1942, Gore, Need for Speed Hot Pursuit 2 and many others to authenticate users for online multiplayer. It uses a server side authentication so the client contacts only the game server and the game server will contact the master server to know if the cd-key of the client is valid or not. I WANT TO STRESS THE FACT that the method I'm talking about can be considered secure and cd-key theft is *NOT* possible, that's why I have written and released this paper in fact I was in contact with Gamespy and I explained my cd-key theft theory so in a morning I have personally made some tests and checks and this paper is the result of my research. So I want to highlight that if you are an user of the games that use the Gamespy Cd-key SDK (I'm just the owner of some of these games) don't worry because you don't have problems with your cd-key. Although seems strange, this time I will not show something that is bugged or contains errors but something that works fine. ####################################################################### ------------------------------------ 2) Explanation 1: Client <--> Server ------------------------------------ When a client joins a server, the server sends a randomly generated challenge (that now we will call SERVER_TOKEN) to it. The length of the string changes between each game, for example it is 7 chars long in the game Gore and 8 in Need for Speed Hot Pursuit 2, however this is NOT important. FYI the client makes also a buffer-overflow check controlling that the sum of the "length of the cd-key" "multiplicated for 2" plus the "length of the SERVER_TOKEN" plus "8" is minor than 512: if(strlen(cd-key) * 2 + strlen(server_key) + 8) >= 512) { printf("CD Key or challenge too long"); break; } Then the client calculates a random 32 bit number that will be used as CLIENT_TOKEN. The next step is the creation of 3 strings containing: - MD5 hash of the client CD-KEY - CLIENT_TOKEN (in hex format!) - MD5 hash of a new generated string The third string on which will be calculated the MD5 hash is composed by the following objects: - client CD-KEY - the remainder of the division between CLIENT_TOKEN and 0xffff - SERVER_TOKEN In C language it is traduced in: sprintf( buffer, // buffer that will contain the string "%s%d%s" // format of the parameters "1111-2222-3333-4444", // client cd-key CLIENT_TOKEN % 0xffff, // remainder of the division SERVER_TOKEN // token sent by the server ); Then the 3 strings will be merged togheter (%s%s%s) and the result will be sent to the server. ####################################################################### ------------ 3) Example 1 ------------ Now a practical example is just what we need if someone has doubts: Client CD-KEY is 1111-2222-3333-4444 its MD5 hash is 9a1d71b925b56b097f6803c61ba2e217 SERVER_TOKEN is aBcDeFg CLIENT_TOKEN is 0x12345678 the remainder yield by the division with 0xffff is 0x68ac (26796 in decimal format) Now we calculate the "third" string that is: 1111-2222-3333-444426796aBcDeFg The MD5 hash of this string is 567289f3392a21a37da23b139449a2ff The last operation is the merging of the 3 strings and the result is the following string (also called response): 9a1d71b925b56b097f6803c61ba2e21712345678567289f3392a21a37da23b139449a2ff ####################################################################### ------------------------------------------- 4) Explanation 2: Server <--> Master server ------------------------------------------- When the server receives the string from the client it contacts the master server (usually master.gamespy.com to port 29910) to see if the client uses a valid CD-KEY. The contact happens with an UDP packet containing the following data: - \auth\ - \pid\ - the PID, it is an unique number for each game. For example it is 302 for Gore and 659 for Need for Speed Hot Pursuit 2 - \ch\ - SERVER_TOKEN - \resp\ - the string sent by the client - \ip\ - IP address of the client in decimal format, for example 127.0.0.1 is 16777343 (0x100007F) - \skey\ - the ID, it is a number used to track the master server reply for a specific authorization request With these values the server is able to do the same operations made by the client in the previous 2 sections and then will say if the cd-key of the client is valid or not reporting also an error (Invalid cd-key, cd-key in use, Invalid authentication, Your CD Key is disabled and others). Probably someone has some doubts about how the server can retrieve the real CD-KEY of the client from a MD5 hash. The answer is simple, the master server should use a database with all the valid cd-keys and their respective MD5 hashs as made by all the games with MD5 based authentication. ####################################################################### ------------ 5) Example 2 ------------ The following is the UDP packet that the server will send (XORing it with the string "gamespy") to the master server to know if the CD-KEY 1111-2222-3333-4444 is valid, it is based on the values of the previous example (3) and the pid is that of Gore: \auth\\pid\302\ch\aBcDeFg\resp\9a1d71b925b56b097f6803c61ba2e21712345678567289f3392a21a37da23b139449a2ff\ip\16777343\skey\1 #######################################################################