Wednesday, 19 September 2012

Hiding The Dead Revisted

In a previous POST, I looked at automating the detecting of encrypted data.   Assuming that you find such data...then what?   You will need to know the software that opens the cyphertext, the password and possibly a key.   There is some stuff we can do to try and establish these parameters. Bearing in mind we have ALREADY done a file signature check on our system, we can use this data to help us.

First lets look at some other routines, to try and detect encrypted data.   Some programs create cyphertext with a recognisable signature, you simply need to add those signatures to your custom magic file, which you will store under the /etc directory.

Some crypto programs generate the cyphertext file with a consistent file extension.
We can search our file signature database for those with something like this, assuming our database is called listoffiles and saved in the /tmp directory:

awk -F: '{print $1}' /tmp/listoffiles | egrep -i '\.jbc$|\.dcv$|\.pgd$|\.drvspace$|\.asc$|\.bfe$|enx$|\.enp$|\.emc$|\.cryptx|\.kgb$|\.vmdf$|\.xea$|\.fca$|\.fsh$|\.encrypted$|\.axx$|\.xcb$|\.xia$|\.sa5$|\.jp!$|\.cyp$|\.gpg$|\.sdsk$' > /tmp/encryptedfiles.txt

In this example we are asking awk to look at the file path + file name field in our database and return only the files with certain file extensions associated with encryption.

We can also detect EFS encrypted files, no matter what size.   We could use the sleuthkit  command "istat" to parse each MFT in the file system and search that for the "encrypted" flag there.   However, this is going to be very time consuming, a quicker way would be to simply look at our file signature database.   If you try and run the file command on an EFS encrypted file, you will get an error message, the error message will be recorded in you signature database.   This is a result of the unusual permissions that are assigned to EFS encrypted files, you can't run any Linux commands against the file without receiving an error message.   I have not seen the error message in any non-EFS encrypted files, so the presence of this error message is a very strong indicator that the file is EFS encrypted.   We can look for the error message like this:
awk -F: '$2 ~ /ERROR/ {print $1}' /tmp/listoffiles > /tmp/efsfiles.tx
So, we have now run a number of routines to try and identify encrypted data, including entropy testing on unknown file types, signature checking, file extension analysis and testing for the error message associated with EFS encryption.

For EFS encrypted files and encrypted files with known extensions, we can figure out what package was used to create the cyphertext (we can look up the file extensions at   But what about our files that have maximum entropy values?
First, we might want to search our file database for executables associated with encryption, we could do something like this:

awk -F: '$1 ~ /\.[Ee][Xx][Ee]$/ {print $0}' $reppath/tmp/listoffiles | egrep -i 'crypt|steg|pgp|gpg|hide|kremlin' | awk -F: '{print $1}' > /tmp/enc-progs.txt

We have used awk to search the file path/name portion of our file database for executable files, sent the resulting lines to egrep to search for strings associated with encryption, then sent those results back to awk to print just the file path/name portion of the results and redirected the output to a file.    Hopefully we will now have a list of programs of executable files associated with encryption.

We can now have a look for any potential encryption keys.   We have all the information we need already, we just need to do a bit more analysis.  Encryption keys (generally!) have two characteristics that we can look for:
1)  They don't have a known file signature, therefore they will be described as simply     "data" in our file data base.
2)  They have a fixed size, which is a multiple of two, and will most likely be 256, 512, 1024, 2048 bits...I emphasise BITS.

So our algorithm will be to analyse only unknown files to establish their size and return only files that 256,512,1024 or 2048 bits.   We can use the "stat" command to establish file size, the output look like this:

fotd-VPCCA cases # stat photorec.log 
File: `photorec.log'
Size: 1705            Blocks: 8          IO Block: 4096   regular file
Device: 806h/2054d      Inode: 3933803     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2012-09-19 11:52:48.933412006 +0100
Modify: 2012-09-19 11:52:12.581410471 +0100
Change: 2012-09-19 11:52:12.581410471 +0100

The important thing to remember is that the file size in the output is in BYTES, so we actually need to look for files that are exactly 32, 64, 128 or 256 BYTES in size, as they map to being 256, 512,1024 or 2048 BITS.

So our code would look something like this:

FILESIZE=`stat $1 | awk '/Size/ {print $2}'`
if [ $FILESIZE = "64" -o $FILESIZE = "128" -o $FILESIZE = "256" -o $FILESIZE = "32"  ]
        echo $1 >> /tmp/enckeys.txt

awk -F: '$2 ~ /^\ data/ {print $1}' /tmp/listoffiles > /tmp/datafiles.txt
cat /tmp/datafiles.txt | while read i ; do KEYREC $i ; done  

The last two lines of code search the description part our list of files and signatures for unknown files (using the string \ data as the indicator) and sends just the file path/name for those results to a file.   That file is then read and every line fed into a function that runs the stat command on each file, isolates the "Size" field of the output and test whether the size matches our criteria for being consistent with encryption keys.   Now you will get some false positives (only a handful) by looking that those files in a hex viewer you will be to eliminate those files that aren't encryption keys - if they have ascii text in them, then they aren't encryption keys!

Now we have the cyphertext, the program used to decrypt the data plus the key, all we need now is the password.  We are going to again use the tool every forensicator MUST have, bulk_extractor.   One of the many features of bulk extractor is to extract all of the ascii strings from a hard drive and de-duplicate them leaving us with a list of unique ascii strings.   It may well be that the users crypto password has been cached to the disk - often in the swap file.   We will probably want to do the string extraction at the physical disk level, as opposed to the logical disk.   We will need several gigabytes of space on an external drive as the list of strings is going to be very large, the command to extract all the strings on the first physical disk and send results to an external drive mounted at /mnt/usbdisk would be:

bulk_extractor -E wordlist -o /mnt/usbdisk /dev/sda

We need to do a bit more work, we can't realistically try every ascii string that bulk_extractor generates.  The password is likely to be long, with mixture of upper/lower case characters + numbers.   You can use a regex to search for strings with those characteristics to narrow down the number of potential passwords (Google is your friend here!).

So, detecting cyphertext and encrypted compressed archives, identifying potential crypto keys and potential passwords is doable with surprisingly small amount of code.    For those on a budget, this solution costs about 10 pence (the cost of a recordable CD) if you want to use the suspect's processing power to do your analysis.


No comments:

Post a Comment