PDA

View Full Version : Teach me to Fish



Raistlin
11-06-2002, 04:10 PM
"Give a man a fish and he can eat for a day, Teach a man to fish and he can eat for a lifetime."

Ok, i'm going to go ahead and take off the flame retardant suit and step up on the podium with a big red target painted on my chest. Go ahead and fire. Feel free to use this as the encryption stupid faq thread that you guys need...

Please correct me when (not if) and where i'm wrong here, i'm trying to get a handle on how the encryption scheme in EQ works now a days so that I know WHAT the problem is. I find it easier to discuss the merits / detriments of ideas when I understand what the problem that needs fixed is first.

The way I understand the EQ encryption to now work is as follows:

1) Client Generates a Public/Private Key sequence. (client now holds CPriv - Client Private Key, and CPub - Client Public Key).

2) Client sends Server CPub (Client Public Key) - Client now holds CPriv and CPub, server now holds CPub. (Question: Wouldn't cpub have to go across the wire unencrypted? Not that this does us that much good.)

3) Server Generates Public/Private key sequence for server.
Client contains CPub, CPriv. Server contains CPub, SPub, SPriv.

4) Server encrypts SPub with CPub and sends Spub to client - Client contains CPub, CPriv, Encrypted SPub. Server Contains CPub, SPub, SPriv.

5) Client decrypts SPub using CPriv to obtain SPub. Client now contains CPub, CPriv, SPub. Server Contains CPub, SPub, SPriv.

6) Client/Server communication continues with packets being encrypted on Client using CPriv and decripted on server using CPub. And Server packets encrypted using SPriv, and decrypted using SPub.

Here's where I have questions. Is it CPriv or SPub that is used by the client to encrypt it's data? Or conversely is it CPub that the server uses to decrypt client data or SPriv?

Anyway, by my estimation the only key that ever crossed the wire that we can get ahold of is the key we could use to get data FROM the client to the server, not visa versa. The key we need to decrypt the information sent from the server never crossed the wire, meaning that the only way for SEQ to decrypt the data is to tell SEQ what either CPriv or SPub is (depending on the question above). Since it never goes across the wire in a format we could break, there's no way that SEQ can be maintained passive.

The next thing is that CPriv/CPub and SPriv/SPub are re-generated each time you zone. Therefor it's not a one time crack / load of the game...it's a crack each time you zone...

Ok, I know i'm missing alot here, so teach me to fish guys. Where am I wrong above? I know "session key" is mentioned alot, and I'm pretty sure this is another key that is used in some way to encrypt step 2 so that NO key goes across the wire unencrypted.

Go ahead, shoot your arrows, sling your stones...but teach me what i'm doing wrong. I could go out to the net and look at a 1500 page whitepaper on PKI/Encryption and burn out my retinas and bore myself to tears with theoretical discussions of mathimatical algorithms that I have no hope of understanding...or I can ask for the cliff notes version of those papers...that's what this is.

-Raistlin

bel
11-06-2002, 10:45 PM
Well, here's my understanding, but I'm no expert so I could be totally off base as well.

1) Client requests server's public key.
2) Upon zoning client generates a random one-time use session key for that zone.
3) Client encrypts the session key with the server's public key and sends it to the server.

Now, I haven't been using SEQ very long so I don't know how this differs from the way the session key was exchanged in the past; whether they've just lengthened the keys involved or if they didn't even bother with a PKI-type exchange before, or what.

Putting the whole PKI subject aside, I think the fundamental problem arises from them starting to compress the data in the packets, which prevents the old intelligent key attack from working. Then from there, we're prevented from sniffing the session key by the use of the server's public key.

Hope that helps some and isn't totally wrong ;)

casey
11-07-2002, 03:17 AM
The server holds the keypair. The server sends public to the client. The client makes up a 64 bit value, encrypts with public and sends back to server.

The client knows 1) the server public key, and 2) the symmetrical session key

We know from the wire 1) the server public key, and 2) the encrypted symmetrical session key

pki is only used to exchange the session key in a secure manner. The actual encryption on the packets is a symmetrical cipher, and both sides use the same key (the 64 bit session key that was sent to the server using pki).

Raistlin
11-07-2002, 09:32 AM
Ok, so the server holds the SPub and encrypted session (can decrypt via SPub *Edit* This should be SPriv, not SPub). The client holds SPub and Session.

For the client to get SPub it has to be sent to us over the wire. How is SPub encrypted by an algorithm that we can't break that the client can without talking to the server?

I don't get this, I know there's something, but i'm not "there" yet. I'm wrong in this but by the sound of what's written now we should be capturing SPub from the server upon being sent and using that to decrypt the returned Session key, just like the server does...how is SPub encrypted when the client and server havn't talked to each other yet?

I think I might have just clued in...having SPub doesn't do us any good since that's only a sending key, not a receiving key. Our problem is that Client generates a Session key and encrypts with SPub, only the Server has SPriv to decrypt that session key, which is the common link between Server and Client. Everything else is encrypted with Session Key which we can't decrypt given that we don't have SPriv, so we need to read it from somewhere where it's NOT encrypted...client memory.

Have I just learned to fish?

--Raistlin

Tyro
11-08-2002, 09:09 AM
Lemme try :)

1. The client has the server’s public key.

2. The server has it's own private key.

3. The client generates a symmetrical key (each time the client zones) to be used by both the client and the server for NewSpawn, ZoneSpawns, and CharProfile. A symmetrical key is faster than asymmetrical/PKI

4. The client encrypts the symmetric key with the servers Public key (which can only be decrypted with the server's private key) and sends it (the sym key) to the server.

5. Server decrypts symmetric key and uses it for communicating with the client (NewSpawn, Zonespawn, and CharProfile)

6. The reason we can no longer brute force the symmetric key is that Sony is now compressing the packets as well, so we have no known structure atm for comparison. In addition, it is now 64 bit not 32 bit.



For the client to get SPub it has to be sent to us over the wire. How is SPub encrypted by an algorithm that we can't break that the client can without talking to the server?
SPub is not encrypted, we know it. However, whatever is encrypted by SPub, can only be decrypted by SPriv, which we will never have.

Things I would like confirmed ...
1. The client generates the sym key, not the server
2. There is no PKI communication from server to client, therefore any need for client pub/private key.
3. Are there any encrypted packets from client to server? Besides login

Thanks

casey
11-08-2002, 11:16 AM
Things I would like confirmed ...
1. The client generates the sym key, not the server
2. There is no PKI communication from server to client, therefore any need for client pub/private key.
3. Are there any encrypted packets from client to server? Besides login

1) client generates the sym key
2) the only PKI in use at all is to echange the sym key, and the server holds the secrets.
3) unless its changed since i last looked, the login packets themselves are not encrypted.

Protector
11-08-2002, 03:05 PM
Just a thought...

I presume someone is looking into finding enough static information in the packet to be able to formulate the required decode key. I realize that the only data to work with now is compressed so there is no simple pattern to work the reverse encode on, however I suspect that there might be enough diffuse constant data gathered from sucessive packets to provide a foothold on the key.

For instance, the users know a large chunk of the beginning part of char info (i.e. the name) that could be run through a compressor to obtain the initial part of the compressed data packet. Yes the checksum there in charinfo is an unknown which would be another problem that needs to be solved. Alternately, we know that the first byte of every zlib is 0x78 (at least in the compression scheme currently used). Given a number of packets with incomplete known values, it seems theoretically possible to combine the resultant possible solutions into a key that works. i.e. if we can determine a single valid byte of the key with each packet, then eight of them might have enough information to derive the entire key.

Not being privy to eqlib.a's prior method of key generation, I can only suppose that it was reverse encoding of known data points in the uncompressed spawn packet. So I won't go any further into how to perform that process.

I probably won't be working more on this myself since I have been sniffing the key since it went to 32 bits for my windows based implementation. Unless of course all the new people jumping on the sniffing bandwagon cause VI to actively defend against it (and affect me which is really the entire point of me bringing this up :)

Tyro
11-08-2002, 03:13 PM
Thanks Casey.

Was thinking the about the pw, but then realized the entire packet didn't need to be encrypted for that. :)

high_jeeves
11-08-2002, 04:47 PM
Alternately, we know that the first byte of every zlib is 0x78 (at least in the compression scheme currently used).

These bytes (all relevant signature info) is moved to the middle of the packet before it is encoded. Cant use zlib info to plain-text it.

--Jeeves

Protector
11-11-2002, 07:59 AM
Yes of course...

But since the coding is symetric you should be able to run the algorythm with any base key value, get a result, determine how the byte(s) in the final resultant are different from what they should be and hence what the initial key value must be to make that byte(s) be what is expected. If you only have one known byte out of 8, then limit the key solution space to 7 unknown bytes instead of 8. If you can do that with enough silmutaneous solutions then possibly the entire key can be obtained, or at least enough of it to brute force the rest.

In truth we are only dealing with binary arithmatic so even though the number of shifts, subtracts, etc. add complexity, they don't make it any less soluble.