Jump to content

Warden


Guest Neo2003
 Share

Recommended Posts

Hello all,

As the title states, it's my turn to expose Warden and share what I did and found around it.

I will make several posts in order to split explanations in parts and to not bother TOM reading all :P

Note that I won't post on how to make the warden blind, and the goal of these posts is not to provide a hacking how-to.

This first part is focuses only on describing what is called "Warden"

1) What the warden is

The warden is a peace of code inside the client which discuss more or less directly with this official server with its own encryption. The discussion between the warden on the client and server is done exclusively in opcode 742 (client to server) and 743 (server to client).

Even if the session is encrypted, these warden packets are encrypted more.

The warden on client is a hoster for some libraries sent by the server. These libraries are win32 compiled part of code which are around 30kb in size and that we call modules. Each module embed his own encryption algorithm to encrypt the warden outgoing packets.

From what I did read, there is an unknown number of different modules, and each module is written / compiled in several form so that a reverse engeneering is very difficult.

It's this module sent by the server which is used to do the check tasks on the client, to provide the decryption keys for the client to decrypt incoming warden packets, and the module encrypt outgoing packets itself.

The overall goal of this warden functionality is for blizz to ensure:

  • * Wow does not run in a debugger
    * There is no hook between the client MPQ reading function and the MPQ themselves
    * Wow read-only memory remain unaltered
    * No LUA banned addon is installed
    * No hacking drivers are installed
    * No known cheating process is running (I did not see this in use)

Practically, all these checks are done by the module itself and the server requests a new set of checks every 1 minute.

[To be refined, corrected or expended]

Link to comment
Share on other sites

2) Warden trafic encryption and modules

Tag: MD5, RC4, SHA1, ZLIB, RSA

Opcodes 742 (S->C) and 743 (C->S) are encrypted with RC4. There is 2 keys for this, one for 742 and one for 743. Before entering into the encryption of the packets and how to get the keys, I have to expose a bit what the warden traffic is.

a) decrypted traffic

The packets always follow the same order

- SMSG_WARDEN_DATA (742) type 00 (module info) with a module MD5 and the module RC4 key to decrypt it and module length. (*1)

Optionaly [

- CMSG_WARDEN_DATA (743) type 00 (load failed) if the client does not have the module yet

- several SMSG_WARDEN_DATA (742) type 01 (module chunk) until the module is transfered. (*2)

]

- CMSG_WARDEN_DATA (743) type 01 (loaded) (**)

- SMSG_WARDEN_DATA (742) type 05 (seed) (*3)

- CMSG_WARDEN_DATA (743) type 04 (seed transformed) (*4)

- SMSG_WARDEN_DATA (742) type 03 (setup data)

Ex: http://paste2.org/p/816264 ==> http://paste2.org/p/816274

And then begin the alternation of

- SMSG_WARDEN_DATA (742) type 02 (cheat-checks)

- CMSG_WARDEN_DATA (743) type 02 (cheat-check results)

every 1 minute until you disconnect.

b) 2 sets of 2 keys: first set

I wrote in first part that the warden module uses his own set of keys to encrypt the traffic. You see in the packet sequence wrote above that the module is ready to work only at step (**). This means there is an initial set of keys. This initial set of keys is based on the session key as follow:

The session key is 40 bytes long. The pair of RC4 keys (one S->C and one C->S) are generated based on the 2 half of the session key.

I will not post the code here. it's SHA1 manipulations, around the session key parts in order to generate 2 keys 16 bytes long each and used as base with RC4_init() to create 2 full 258 bytes keys.

I suggest you take a look at warden_set_initial_keys function I wrote in warden.c in the source I will link in last post. You end-up with 2 RC4 keys 258 bytes long.

c) 2 sets of 2 keys: second set

After point (**) the module is loaded by the client, then it will be used to encrypt the traffic and will expose his keys to the client to decrypt incoming packets.

The module export directly the 2 RC4 keys 258 bytes long (256 data + uint8 x + uint8 y). To decrypt the traffic, the C->S new key has to be used after point (*3) and the S->C key has to be used after point (*4).

Note: the packet order is very important since using a RC4 key to decrypt a packet alter this RC4 key and make it ready for next packet.

As a middle conclusion, you see that you can't decrypt the traffic after step (*4) until you are able to run the module and ask it for the new keys set.

d) the module

- Raw module (.bin)

The first warden packet coming from the server contains a module MD5 (16 bytes long) this MD5 is the way to identify the module. it also contains the RC4 key to be used to decrypt the module.

There is 2 ways to get the raw encrypted module:

  • * You extract clientcache.wdb (it's what client does when he does reply immediately 743 type 01 (loaded).
    * You assemble the module chunks sent by the server together until you reach the module length

Since we use the MD5 of the module as name, you end-up with something like C128B52AD08980F905A2FCD5FF7424D1.bin around 17-19Kb in size

- decrypted module

Use the 16 bytes key given in first packet and build a RC4 key with RC4_init, then use this RC4 key to decrypt the module.

- striped module

The result of this is still a 17-19kb long piece of data. The last 260 bytes contains "SIGN" + 256 bytes with a RSA footprint of the first part. If we get the "SIGN" char[4] at end-260, we consider the data valid and we just drop the last 260 bytes.

This signature is what prevents anyone from making the client able run a custom module, I think client only has the public key to verify the footprint and only blizz has the private key used to create it. TOM do you confirm?

- deflated module (.mod)

Just use zlib to expand (inflate) the module, you read the first uint32 which contains the size, allocate it and expand the rest in this allocated space.

You end-up with a piece of win32 compiled library around 26-34Kb

Let's keep it as something like C128B52AD08980F905A2FCD5FF7424D1.mod

I know I explain this a bit out of order, but this is the way I understood it. The next part will explain how to play with this win32 code and finally run part of this code to go post steps (*3) and (*4) in traffic decryption they further.

[To be corrected or expended]

Link to comment
Share on other sites

3) Loading and playing a module

Tag: win32, libraries, import, export, object data

[To be written]

Since I won't have time to write more before Monday, this is some files to play with:

Link to comment
Share on other sites

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use