Here are a few packet analysis for:
1st packet from the client to the chatserver
The encoded unix time looks like that:
1st packet from the client to the game server
So, what are the next logical steps? As I said earlier the chat server is pretty much irrelevant at this early stage. So we (or to be honest I) should focus on looking into the cyphered stuff. From what I can tell lotroclient.exe uses the crypt API provided by advapi32.dll. I think that we need to intercept the calls to this API to find out what exactly is happening. I tried to get uhooker to run but failed. Now I'm thinking about Wine on Windows or running LOTRO under Linux. This would enable us to run "WINEDEBUG=+crypt lotroclient.exe" to dump the method calls to advapi32.dll. The issue is: I could not get wine to run on windows or lotro to run on linux. And then emupedia went down and I got disappointed and stoped working on that for the last weeks :-)
Relavant DLL calls are:
CryptReleaseContext
CryptDecrypt
CryptEncrypt
CryptGenKey
CryptAcquireContextA
CryptGenRandom
CryptGetKeyParam
CryptExportKey
CryptImportKey
CryptGetProvParam
CryptDestroyKey
As you can see they are using a varity of functions. What I assume is the following:
I think that the most important point is: do they generate a key? or are they using a precomputed key? If the key is precomputed we are pretty much busted. I think they'd use a secure algorihm and a public key, meaning we'd have no possibility to generate the private key. We'd have to use an advapi32.dll that disables encryption and just returns the unecrypted payload. But replacing advapi32.dll is not trivial. The worst case would be: the generate a random key pair (symetric or asymetric) and encrypt that using the public key of the server and use the generated key for the communication in game. But that's most likely the case. This way you can safely exchange a simple symetric key for blazing fast encryption over a secure inital layer. The later communication would be done using the symetric key.
Whatever it is, we'll need to find out by tracing the calls to the crypto api.
1st packet from the client to the chatserver
Code:
0x0000 -> 0x0003: spacer sequence 00 00 00 00
0x0004 -> 0x0005: length 2c01 = 1, 2e01 = 2, 3001 = 3, 3201 = 4, 3601 = 6, 3801 = 7, 3e01 = 10
0x0006 -> 0x000d: spacer sequence 00 00 01 00 00 00 00 00
0x000e -> 0x0011: seems to be a weird encoding of unix time
0x0012 -> 0x0015: spacer sequence 00 00 00 00
0x0016 -> 0x0028: 061004_chat_fe_2_2
0x0029 -> 0x002A: length 1501 = 1, 1701 = 2, 1901 = 3, 1b01 = 4, 1f01 = 6, 2101 = 7, 2701 = 10
0x002B -> 0x0034: spacer sequence 00 00 02 00 00 40 04 00 00 00
0x0035 -> 0x0037: seems to be another? a weird encoding of unix time
0x0038 -> 0x0038: I(49) = start of subscription id
0x0039 -> 0x003a: subscription id in UTF-16
0x003b -> 0x0041: spacer sequence 00 02 01 00 00 81 00
0x0042 -> 0x0141: token we got from the login meta server
Code:
2009-01-26 23:44:xx 469037df d43c
2009-01-26 23:45:xx 46903705 fa3c
2009-01-26 23:46:xx 47903746 3b3d
2009-01-26 23:47:xx 47903780 753d
2009-01-26 23:47:xx 479037a1 963d
2009-01-26 23:48:xx 479037be b33d
2009-01-26 23:52:xx 489037c4 b93e
2009-01-26 23:53:xx 48903705 fa3e
2009-01-26 23:56:xx 49903790 853f
2009-01-27 00:00:xx 4a9037a6 9b40
2009-01-27 00:02:xx 4a9037ec e140
2009-01-27 00:03:xx 4b90373f 3441
2009-01-27 00:04:xx 4b903790 8541
1st packet from the client to the game server
Code:
0x0000-0x0029: UDP/IP connection from 192.168.1.4 TO 192.168.1.1:9000
0x002A-0x00AD: Spacer 00 00 00 00
0x00AE-0x00AF: Opcode for connect, I guess
0x0030-0x0037: pretty constant 00 00 01 00 00 00 00 00 ... maybe packet number to simulate TCP packet ordering?
0x0038-0x003B: seems pretty much a random number, needs investigation
0x003C-0x003F: Spacer 00 00 00 00
0x0040-0x009F: Pretty much constant, only changing bytes: 0x0080 and 0x008C-0x008E ... looks like these crappy timestamps we also see in the connect to the chat server
0x00A0-0x011F: No idea. Changes completely on every request. Something cyphered. Or the key. High entropy anyway
0x0120-0x0123: length of the following cyphered gls ticket ... 0x08 + len for all length <= 80, 0x09 after that. looks like the heading key gets one byte longer? little endian 8 bit atomic 0x0124-0x022C: cyphered gls ticket
Relavant DLL calls are:
CryptReleaseContext
CryptDecrypt
CryptEncrypt
CryptGenKey
CryptAcquireContextA
CryptGenRandom
CryptGetKeyParam
CryptExportKey
CryptImportKey
CryptGetProvParam
CryptDestroyKey
As you can see they are using a varity of functions. What I assume is the following:
- they are calling CryptAcquireContextA (note: This is the ASCII version!) to get access to the crypto apo
- they use CryptGenKey or CryptImportKey to get hold of a key to be used for the session
- they CryptEncrypt the payload of the package
I think that the most important point is: do they generate a key? or are they using a precomputed key? If the key is precomputed we are pretty much busted. I think they'd use a secure algorihm and a public key, meaning we'd have no possibility to generate the private key. We'd have to use an advapi32.dll that disables encryption and just returns the unecrypted payload. But replacing advapi32.dll is not trivial. The worst case would be: the generate a random key pair (symetric or asymetric) and encrypt that using the public key of the server and use the generated key for the communication in game. But that's most likely the case. This way you can safely exchange a simple symetric key for blazing fast encryption over a secure inital layer. The later communication would be done using the symetric key.
Whatever it is, we'll need to find out by tracing the calls to the crypto api.
Keine Kommentare:
Kommentar veröffentlichen