This is a writeup of the PlaidCTF 500 pts challenge “Fun with Firewire”.
Given is a memory dump (128 MB) of a running Windows XP SP3 machine as well as a 32 MB file containing random data (a TrueCrypt volume image, according to the problem description). The memory dump was supposedly extracted via the Firewire port: The Firewire specification allows devices to have full DMA access. This allows forensic analysts (or a malicious hacker) to plug into any running computer that has a Firewire port and gain full access to the machine within seconds. Papers describing the attack and tools can be found at http://www.hermann-uwe.de/blog/physical-memory-attacks-via-firewire-dma-part-1-overview-and-mitigation. A different way to get a dump of the memory would be to conduct a “cold boot attack” as described in this paper.
To get an overview of the memory dump we inspect it with volatility. We see that TrueCrypt was running at the moment the dump was taken … good.
Further inspection of the memory dump reveals that the Operating System is Windows XP SP3, and the latest version of TrueCrypt (7.0a) is used. We reconstruct the setup by launching a VirtualBox installation, and we extract the memory using Mantech Memory Dumper mdd http://sourceforge.net/projects/mdd/. TrueCrypt offers the possibility to cache the passwords for mounting encrypted volumes. Comparing different memory dumps let us conclude that password caching was not enabled in the TrueCrypt software.
We briefly summarize the relevant technical details of TrueCrypt. More information can be found at http://www.truecrypt.org/docs/. In order to mount an encrypted volume, TrueCrypt uses the password and/or one or more key-files in order to decrypt the header (first 512 bytes of the volume). If the header gets correctly decrypted (a magic cookie is found), TrueCrypt reads the configuration (encryption algorithm and mode, etc.) as well as the master and secondary key into memory, and safely overwrites the memory regions where the password / key-file location was stored. The extracted master and secondary key is used for any further encryption and decryption of data. Since the data is encrypted and decrypted on the fly, these keys remain in memory. (Note that recent papers suggest storing the keys in CPU registers, more specifically in SSE registers http://portal.acm.org/citation.cfm?id=1752053 or in MSR registers http://arxiv.org/abs/1104.4843 instead of in the RAM in order to mitigate against these attacks.).
The default cipher used by TrueCrypt is AES in XTS mode which uses two 256 Bit AES-keys. We have to locate these keys in the memory dump. One option would be to analyze the data-structures and locate the memory region where TrueCrypt stores the keys.
But it is easier to use a generic approach to locate AES keys since a tool for that task was already written for the “cold boot attack” research: AESKeyFinder.
Once we have the right keys, we replace the header of the encrypted volume with the header of an identical volume which we created and where we set the password (so that TrueCrypt starts the mounting process correctly), but have TrueCrypt patched so that it uses the extracted keys from the memory dump instead of the ones from the newly generated header.
The “constraint on rows”-output tells us that the expanded keys are valid according to the AES key schedule. If we had bit errors in the respective memory regions (likely in cold boot attacks), not all constraints would have been met and AESKeyFinder would have calculated a guess for the original valid key.
So we have three keys after only a few of seconds of runtime - so far so good.
The entropy of (3) is really low, and we can definitely exclude it if we assume TrueCrypt is not totaly broken. This is good news since we have exactly two remaining 256-bit AES keys, as used by TrueCrypt in default configuration (AES in XTR mode).
Next we read the source of TrueCrypt. Remember that TrueCrypt first decrypts the header with the password, and then reads the AES-key from the decrypted header. Reading in the header is done in Volume/VolumeHeader.cpp:VolumeHeader::Deserialize(.,.,.). We patch the code there, right after the master and secondary key was read from the decrypted header, and replace it with the hard-coded key value we found in the previous step. Our quick and dirty patch looks as follows:
Mounting the Volume
In order for TrueCrypt to reach the patched code it must first correctly decrypt a valid header. So we copy the header from an identically sized TrueCrypt volume configured with the default parameters:
and open ppp.challenge.vol with the patched TrueCrypt software and find the file KEY.TXT in the correctly decrypted volume.
This was a really nice challenge letting us explore TrueCrypt internals. If you think this is too complicated - you are right. You can also solve the challenge with available tools.
People involved in solving this challenge: Clemens Hlauschek, Michael Weissbacher