Intro

AES (Advanced Encryption Standard) is an industrial standard encryption method used for various encryption/decryption purpose. It is a symmetric algorithm that transforms plain text into cihper text. To perform an ecryption, a key is supplied to an algorithm and a bunch of mathematical operations are performed using the key on the plaintext. The output is called the ciphertext, which is the encrypted version of the original information.

                       key
                        |
                        v
   plain text -----> algorithm -------> cipher text

Vice versa, the decryption process is just the reverse: cipher text -> algorithm (key) -> plain text.

AES comes with various standards (based on the key length), there are: AES-128, AES-192 and AES-256, where AES-256 is the recommended minimum standard for most industries.

Note: Mordern encryption algorithms are merely a combination of substitution and permutation.

Where to find an AES key

AES keys are often found in the following places:

  • In memory: when a program exercises encryption/decryption, the key needs to be loaded into the memory
  • In binary/file: the key may be hard coded into the binary/file for deployment purpose

How to identify the AES key

Bruteforce

As the keys are stored in either memory or the binary/file, it is possible (in theory) to iterate every (for example) 256-bits starting from the beginning of the byte space, and eventually you’ll be able to find the AES key. Obviously, this is the dumbest approach as it’s very time consuming.

Of course, you may apply a little bit of filtering here to take out any memory spaces that contains a lot of \x00 and corresponding blocks that don’t provide enough bits (e.g 256 bits after removing the \x00s).

Entropy check

Based on the above, there is a bit more intelligence that can be introduced here, that’s the concept of entropy. Entropy is a physics concept that measures the orderlessness of a closed system. So, an ordered string like 0123456789 would have a lower entropy level than that of an unordered string like 23904370823.

Because an AES key is most-likely randomly generated instead of human picked, it’s bond to imply a higher entropy level. Therefore, when searching through the memory spaces, we can also filter by the block’s entropy level to tell if it’s likely to be an AES key.

Round key and key schedule

AES algorithm has a concept called key-expansion. Remember we mentioned before that modern day encryption is merely a combination of substitution and permutation? AES adopts the key-expansion concept to create a set of expanded keys (called round-keys, usually 15 of them in a set) and form a table (called a key-schedule) where it can refer to for substitution purpose. And the AES key itself is split into two round keys used at the start of the key-schedule. A typical memory layout of the AES key and it’s key-schedule looks like this:

0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               AES-256-Key (RoundKeys 00 and 01)               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           RoundKey02          |           RoundKey03          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           RoundKey04          |           RoundKey05          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           RoundKey06          |           RoundKey07          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           RoundKey08          |           RoundKey09          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           RoundKey10          |           RoundKey11          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           RoundKey12          |           RoundKey13          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           RoundKey14          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

# https://github.com/luismartingarcia/protocol

So, conceptually, when going through the memory spaces, we may examine a 256 bit long string, split into two round keys and calculate the rest of the round keys (algorithm is public knowledge) and compare with the following memory spaces. If there is a match, then we likely found an AES key.

Any tools can be used?

aeskeyfind (https://www.kali.org/tools/aeskeyfind/) and bulk_extractor (https://github.com/simsong/bulk_extractor) are very good tools designed based on the above concept and are very effective in key extraction that you can include in your next pentest engagement.