Difference between revisions of "Warden Packets"

From SkullSecurity
Jump to navigation Jump to search
 
(9 intermediate revisions by one other user not shown)
Line 4: Line 4:
Generating the keys used for encrypting Warden packets is a somewhat convoluted algorithm, but it is fairly simple to implement. Here are the basic steps:
Generating the keys used for encrypting Warden packets is a somewhat convoluted algorithm, but it is fairly simple to implement. Here are the basic steps:
# Create a source of shared random data based on a seed
# Create a source of shared random data based on a seed
# Generate the outgoing key from the first 0x10 bytes
# Generate the outgoing key from the first 0x10 bytes, using the generation code in [[Crypto_and_Hashing#Xor_Encryption]]
# Generate the incoming key from the next 0x10 bytes
# Generate the incoming key from the next 0x10 bytes using that code


The random source is basically a struct with 4 fields, which are initialized as such:
The random source is basically a struct with 4 fields, which are initialized as such:
Line 13: Line 13:
* Data 3 [0x14 bytes]: WardenSHA1(second half of seed)
* Data 3 [0x14 bytes]: WardenSHA1(second half of seed)


Data is read one byte at a time, and Current position is incremented. Immediately after being created, or when Current position reaches 0x14, an update is performed:
"Data 1" is read one byte at a time, and Current position is incremented. Immediately after being created, and when Current position reaches 0x14, an update is performed:
* Current position = 0
* Current position = 0
* Data 1 = SHA1(Data 2, Data 1, Data 3)
* Data 1 = SHA1(Data 2, Data 1, Data 3)
* Data 2 and Data 3 aren't changed


That's it! All that's left is to read 0x10 bytes, generate the outgoing key (using the key generation function in [[Crypto_and_Hashing#Xor_Encryption]]), read 0x10 more bytes, and generate the incoming key.  
That's it! All that's left is to read 0x10 bytes, generate the outgoing key (using the key generation function in [[Crypto_and_Hashing#Xor_Encryption]]), read 0x10 more bytes, and generate the incoming key.  
Line 23: Line 24:


===The Key===
===The Key===
On Starcraft, the first 4 bytes of the CDKey hash are used. That's the actual CDKey has that's sent over the wire as part of SID_AUTH_CHECK.  
On Starcraft, the first 4 bytes of the CDKey hash are used. That's the actual CDKey hash that's sent over the wire as part of SID_AUTH_CHECK.
 
On Diablo 2, the 4-byte GameHash value is used.
 
Other clients are currently unknown (to me).


==Packet Codes==
==Packet Codes==
Line 34: Line 39:
===0x00===
===0x00===
0x00 is a request sent from the server asking if you have the current warden module. It is in the following form:
0x00 is a request sent from the server asking if you have the current warden module. It is in the following form:
* [1 byte] code (0)
* [16 bytes] name of the current module
* [16 bytes] name of the current module
* [16 bytes] decryption key for the current module
* [16 bytes] decryption key for the current module
Line 39: Line 45:


A response of 0 will tell Battle.net to send you the current module, and you'll receive a slew of 0x01 packets. 1 will tell Battle.net you already have the module, and you'll receive a 0x02 packet.
A response of 0 will tell Battle.net to send you the current module, and you'll receive a slew of 0x01 packets. 1 will tell Battle.net you already have the module, and you'll receive a 0x02 packet.
====Example====
* Server
** 00 a2 d4 d6 4c 46 8e 56 4f 42 c6 s4 68 e4 5d 6a 46 5f 46 b4 5c 24 d5 46 e4 56 a6 4d 75 2d 21 f8 79 05 0b 00 00
* Client
** 00


===0x01===
===0x01===
Line 46: Line 58:
* [array] data
* [array] data


You will receive a number of 0x01 packets, until the total length of "data" received is equal to the length sent in packet 0x00.  
You will receive many 0x01 packets, until the total length of "data" received is equal to the length sent in packet 0x00.
 
After the packet is received, it's validated (see [[Warden Modules]]). If it was received without error, a response of 1 (encrypted) is sent. If there's an error, 0 (encrypted) is sent.


===0x02===
===0x02===
Line 52: Line 66:


I haven't reversed it yet, and don't plan to in the near future.
I haven't reversed it yet, and don't plan to in the near future.
===0x03===
This packet is used to initialize functions to read information from the MPQ files.
0x03 packets have the form:
* [1 byte] code (0x03)
* [2 bytes] length (without the 7-byte header)
* [4 bytes] checksum of the packet data (the checksum does not include the header)
* [1 byte] Unknown flag (this has to be 1 otherwise Warden will exit the initialize function)
* [1 byte] Unknown flag (usually 0)
* [1 byte] Unknown flag (usually 1)
* [nullstring] Library Name
* [4 bytes] function offset #1
* [4 bytes] function offset #2
* [4 bytes] function offset #3
* [4 bytes] function offset #4
===Packet Checksums===
Warden uses a modified version of the SHA1 algo and Xor's the result of it.
Warden_SHA1 can be found here: [[SHA1_in_C]]
<pre>
DWORD dwBuffer[5], DWORD dwHash;
warden_sha1_hash(dwBuffer, (CHAR*)bPacket, sizeof(bPacket));
for(INT i = 0; i < 5; i++)
dwHash = dwBuffer[i] ^ dwHash;
</pre>

Latest revision as of 21:39, 11 December 2008

This is about how to encrypt/decrypt the Warden packets, and what they mean.

Generating encryption keys

Generating the keys used for encrypting Warden packets is a somewhat convoluted algorithm, but it is fairly simple to implement. Here are the basic steps:

  1. Create a source of shared random data based on a seed
  2. Generate the outgoing key from the first 0x10 bytes, using the generation code in Crypto_and_Hashing#Xor_Encryption
  3. Generate the incoming key from the next 0x10 bytes using that code

The random source is basically a struct with 4 fields, which are initialized as such:

  • Current position [0x04 bytes]: 0
  • Data 1 [0x14 bytes]: 00 00 00 ....
  • Data 2 [0x14 bytes]: WardenSHA1(first half of seed)
  • Data 3 [0x14 bytes]: WardenSHA1(second half of seed)

"Data 1" is read one byte at a time, and Current position is incremented. Immediately after being created, and when Current position reaches 0x14, an update is performed:

  • Current position = 0
  • Data 1 = SHA1(Data 2, Data 1, Data 3)
  • Data 2 and Data 3 aren't changed

That's it! All that's left is to read 0x10 bytes, generate the outgoing key (using the key generation function in Crypto_and_Hashing#Xor_Encryption), read 0x10 more bytes, and generate the incoming key.

Here is the code in C and in Java.


The Key

On Starcraft, the first 4 bytes of the CDKey hash are used. That's the actual CDKey hash that's sent over the wire as part of SID_AUTH_CHECK.

On Diablo 2, the 4-byte GameHash value is used.

Other clients are currently unknown (to me).

Packet Codes

The packet structure for Warden is very simple. The received packets, once decrypted, are in the form: [1 byte] code (0, 1, or 2) [array] data

And the response is usually a single encrypted byte, either 0 (for "fail") or 1 (for "success"). The exception is the response to the 0x02 packet.

0x00

0x00 is a request sent from the server asking if you have the current warden module. It is in the following form:

  • [1 byte] code (0)
  • [16 bytes] name of the current module
  • [16 bytes] decryption key for the current module
  • [4 bytes] length of the current module

A response of 0 will tell Battle.net to send you the current module, and you'll receive a slew of 0x01 packets. 1 will tell Battle.net you already have the module, and you'll receive a 0x02 packet.

Example

  • Server
    • 00 a2 d4 d6 4c 46 8e 56 4f 42 c6 s4 68 e4 5d 6a 46 5f 46 b4 5c 24 d5 46 e4 56 a6 4d 75 2d 21 f8 79 05 0b 00 00
  • Client
    • 00

0x01

0x01 packets have the form:

  • [1 byte] code (0x01)
  • [2 bytes] length (without the 3-byte header)
  • [array] data

You will receive many 0x01 packets, until the total length of "data" received is equal to the length sent in packet 0x00.

After the packet is received, it's validated (see Warden Modules). If it was received without error, a response of 1 (encrypted) is sent. If there's an error, 0 (encrypted) is sent.

0x02

This packet is a request to validate the running game to verify it's legit.

I haven't reversed it yet, and don't plan to in the near future.

0x03

This packet is used to initialize functions to read information from the MPQ files.

0x03 packets have the form:

  • [1 byte] code (0x03)
  • [2 bytes] length (without the 7-byte header)
  • [4 bytes] checksum of the packet data (the checksum does not include the header)
  • [1 byte] Unknown flag (this has to be 1 otherwise Warden will exit the initialize function)
  • [1 byte] Unknown flag (usually 0)
  • [1 byte] Unknown flag (usually 1)
  • [nullstring] Library Name
  • [4 bytes] function offset #1
  • [4 bytes] function offset #2
  • [4 bytes] function offset #3
  • [4 bytes] function offset #4

Packet Checksums

Warden uses a modified version of the SHA1 algo and Xor's the result of it.

Warden_SHA1 can be found here: SHA1_in_C

	DWORD dwBuffer[5], DWORD dwHash;
	warden_sha1_hash(dwBuffer, (CHAR*)bPacket, sizeof(bPacket));
	for(INT i = 0; i < 5; i++)
		dwHash = dwBuffer[i] ^ dwHash;