Author Topic: The current key.dat format is insecure.  (Read 3965 times)

I kept wavering between posting this and not posting it, and ultimately I decided that it's better to show the exploit than to allow it to have any chance of potentially flying under the radar.  The reason is simple.  While trying to help a friend recover his previously lost key, I realized that this attack existed, but decided that it was worthless as an avenue of recovery because there would never be enough keys generated by one machine for it to be useful.  Specifically, I knew that this attack existed a good two weeks before Computermix exploited it, and decided to not alert Badspot because I thought it would never be a problem.  I also have a more personal interest in solving this issue, since one of the keys leaked was my brother's.  Anyway, about the exploit itself:


If you haven't been living under some form of large rock, you're probably at least vaguely aware that 41 individual key.dat files were leaked.  They were subsequently cracked through a fundamental flaw in the key.dat format's encryption.  It only takes about ten individual keys to go from essentially unbreakable to easily breakable.

The current key.dat format is "KEYDAT_V1", followed by a newline and 17 bytes of encoded key data.  The encoding formula looks something like this (although this code is in C#, not TorqueScript).

Code: (EncryptKey) [Select]
static byte[] EncryptKey(string Key, string CPU, string MACAddress)
{
    byte[] bKey = Encoding.ASCII.GetBytes(Key.Replace("-", ""));
    byte[] bCPU = Encoding.ASCII.GetBytes(CPU);
    byte[] bHex = Encoding.ASCII.GetBytes("XXXXX" + MACAddress);
    byte[] Result = new byte[17];
    for (int I = 0; I < 17; I++)
        Result[I] = (byte)(bKey[I] ^ ((bHex[I] + bCPU[I]) % 256));
    return Result;
}

The part we're interested in is the fact that the encryption key stays the same on any given computer.  Since keys are Base32 data, there is a very limited range of valid final bytes we can get upon decryption.  If a given cypher byte doesn't give us a valid final byte for every single encrypted key, we can discard it completely.  As the sample size of keys increases, the likelyhood of having more than one valid final byte per byte position decreases. Get one key, and you (should) have 85 bits of uncertainty. Get ten, and you'll usually have about 8 bits of uncertainty. Get 41, and you'll have about 0 bits of uncertainty.


The problem is with the deterministic nature of the encryption key.  For any given computer, the encryption key is ALWAYS identical.  This is simply unacceptable.  Just directly adding a bunch of random noise to the encryption key doesn't work, however - either you save it with the encrypted data, in which case it's useless; or you don't, in which case it's undecryptable.

Luckily, there is a solution.  In fact, there are many - the one linked is just my own personal solution.

Below is what the key.dat of a wholly fictional scenario would look like - the key "ABCDE-FGHJ-KLMN-PQRS", encrypted on a computer with a Generic CPU and a MAC address of 0123456789ab.




This is what Blockland will always generate under those circumstances.  That deterministic nature is why the attack works.
However, if Badspot implemented the linked solution, Blockland would give us a file that looks more like the following:




To break it down, I have highlighted the relevant parts here.



The yellow portion is the header, and will never change.  The light blue portion is the salt, 48 bytes of CSPRNG data, and will never be dependant on the computer.  The green portion is the key, encrypted with a combination of data unique to the computer and the salt.  The result is a file which can be decrypted on the original computer, but which does not always have the same encryption key.

Compare the above image with the two below.  These are all the exact same hypothetical key, on the exact same hypothetical computer.  The only difference is the salt.






Now that I have systematically detailed both the attack and one possible solution, hopefully we'll soon see KEYDAT_V2.

wow you are a smart lil fella

Another solution is to use something like AES (Or one of the many other easy-to-implement block ciphers) encryption, which, when you change even 1 character of the input, all of the characters of the output change seemingly randomly. No salt needed, and provides the same amount of security while rendering all the attacks listed here useless.

I do hope for a keydat_v2!



damn

badspot needs to hire this man

damn

badspot needs to hire this man

I hope Badspot Will modify it, really!

nobody needs to hire anyone. don't act like badspot didn't know any of this ahead of time when he was making this. this is like, super obvious stuff that's been known by many people years before the attack.

you can argue that its sorta beneficial to upgrade it (I guess?), but badspot isn't going to do anything regardless of how fancy the essay.

holy stuff
does Xalos major in like everything

badspot isn't going to do anything regardless of how fancy the essay.


or:

let me steal more keys please
i didn't steal anyone's keys.

_______ didn't know any of this ahead of time when he was making this. this is like, super obvious stuff that's been known by many people years before the attack.
INSIDE JOB! THE GOVERNMENT PLANNED THIS!


Seriously though, how did you figure this out? Smart.
 :cookie:

You recovered my friend Wink's key he hasn't used in five years using this method. That's both cool and scary at the same time.

You recovered my friend Wink's key he hasn't used in five years using this method. That's both cool and scary at the same time.
not really scary, he needs a key.dat file to do it. he can't do it over the air.