Monday, 24 October 2011

Updated Cryptoscan for the Volatility Framework

This post is about an updated version of Cryptoscan which makes it compatible with the latest versions of TrueCrypt.

Cryptoscan is a module for the Volatility framework which scans a memory image for TrueCrypt passphrases. For a passphrase to be stored in a memory by TrueCrypt, an option “Cache passwords and keyfiles in memory” needs to be selected. Consequently, the credentials are saved until a user wipes the cache or restarts the computer.

I tried Cryptoscan version 1.0, released by Jesse Kornblum in 2008, and despite my numerous attempts I failed to recover a passphrase. Then I decided to study its source code and this is what caught my eye:

    Passphrases are stored in a structure containing a magic
    value (0x7d0), a passphrase length, and then 64 bytes of
    passphrase data. The data must contain exactly length ASCII
    characters and all remaining bytes must be zeros.

After that I searched a previously created memory dump for my passphrase and the magic value. Strangely enough, I had no problem finding the passphrase but there was no value preceding it.

As I was puzzled with the lack of magic value, I thought that maybe TrueCrypt’s source code could reveal anything useful. Spot on! The Password header file from the version 7.1, the latest at the time of writing this post, shows the following data structure:

    typedef struct
          // Modifying this structure can introduce incompatibility with previous versions
          unsigned __int32 Length;
          unsigned char Text[MAX_PASSWORD + 1];
          char Pad[3]; // keep 64-bit alignment
    } Password;

This proves to me that maybe there used to be a magic value before the password’s length in some of the previous versions, but definitely there isn’t one anymore. I have looked through different versions of the code and it seems that the structure has been introduced with the version 4.0 and then 5.0 added the padding.

So the comment from Cryptoscan could now look something like this:

    Passphrases are stored in a structure containing a passphrase
    length (a value between 1 and 64 stored in the first of the four
    bytes),65 bytes of passphrase data and then 3 bytes of padding
    to keep 64-bit alignment. The data must contain exactly length
    ASCII characters, all remaining bytes must be zeros except for
    the padding which has a random value.

If we know that there’s no magic value anymore, then modifying the code to search for passphrases according to the new requirements would cause a flood of strings which aren’t necessarily related to TrueCrypt’s “black magic”. This is an example of running modified Cryptoscan on Windows XP SP3.


To reduce the number of false positives, we can extract strings along with their offsets and then link them to a process they belong to, which can be done using Volatility’s Strings module. Once we have that, we can ignore all the strings that belong to other processes than TrueCrypt (on Windows it’s a module, TrueCrypt.sys). The final result is surprisingly good and it can be easily automated.

To prove that it actually works I created a Windows batch script that uses the updated version of Cryptoscan and Win32 ports of awk, grep and sed to filter the output. To get it working, extract the archive to a folder with Volatility 1.3 and run the batch script.

An archive with the script and the necessary binaries can be downloaded from here.

Update (27 Nov 2011): I've received an email from one of the students at university (thanks Phil!) complaining that the script won't work with Windows Vista (and higher for that matter). I've had a look and he's got a point, the script only works with Volatility 1.3 beta which is limited to older versions of Windows. I've updated the batch script to accommodate to that. You can read more on that in this post.

1 comment:

  1. hmm i'm know getting the error

    (2/3) Associating strings with the processes they belong to.
    Volatile Systems Volatility Framework 2.0
    Traceback (most recent call last):
    File "", line 135, in
    File "", line 126, in main
    File "../volatility\build\pyi.win32\pyinstaller\vol.pkz/volatility.commands",
    line 101, in execute
    File "C:\volatility\volatility\plugins\", line 88, in render_text
    ValueError: need more than 1 value to unpack

    any ideas?