McAFuse - open source McAfee FDE decryption

This post is a guest post, where Andrea Canepa (recently graduated at University of Genoa, Computer Science) will explain his Master Thesis. The topic is how to handle McAfee FDE acquisitions when doing a DFIR investigations.

Suppose that you're asked to perform a forensic investigation on a laptop where McAfee FDE is used: the company will provide you the xml file (McAfee ePO) with the decrypting key. How would you proceed?

Our usual approach has always been to perform a full disk acquisition of the encrypted disk, as is: this is most likely the best freeze of the current data you could get. Then, how would you decrypt the forensic image?

McAfee provides the DETech tool and a proper manual: point is, you'd have to use it by creating a boot-able WinPE device (CD, USB) to run it and decrypt the original disk, sector by sector.

What I've done in the past is a Powershell script which will take the DETech.zip file and it will "install" it inside a Windows system: to say the truth, inside a Windows VM. By using that VM together with the DETech app with the proper decryption key, the mcafee filter driver will decrypt the volume on the fly when you access it: a second acquisition can then be performed to get the volume decrypted. I'm not going to release that script but, if you want to adopt a similar approach, be careful to use a VM: mcafee filter driver will allow one and only one decrypting key and if your host is using McAfee FDE, you're going to fast blue screen the system. Moreover a forced new filter driver will most likely kill your current FDE or trigger any TPM. Go virtual.

I've never liked the previous solution, so I swept Internet to spot a research about this full disk encryption. No luck, only few commercial tools able to handle it, without details. This is the reason I proposed a Master Thesis at University of Genoa, to see if some skilled student was interested in it. In the end, Andrea was, and that's how the McAFuse (which is not fuse a Mac, regardless the opportunity to do that) project started.

Before leaving the blog post to Andrea, let me say thanks to Prof. Giovanni Lagorio and, obviously to Andrea, who manage quite a complexity in a professional way.  Disclaimer: we're all part of the ZenHack team (https://zenhack.it/).

Spoiler: the McAFuse project is a blue project. But the SafeDisk object - what is called Drive Encryption Pre-Boot File System (PBFS) by McAfee - is a gold mine for configurations, cracking and, maybe, xploits: decrypted offline, encrypted when online, fun trick.

Go on Andrea, and thank you!

DETech and McAfee internals

Let's start our journey by taking a quick look at one of the windows presented by DETech.exe after having it installed on our VM. In particular, in the picture below we can see the Workspace environment, where we can upload up to 40960 sectors from one of the mounted disks on our system.

Here we can play a little by encrypting and decrypting the data previously loaded. This was the starting point for the investigation! We knew in advance that the algorithm used by this technology was AES-256 in CBC mode. How do we know it? Elementary, Watson! There is another very informative frame that DETech displays to the user, like in the picture below (n.d.r. in the following some of the data showed in the pictures are redacted to preserve the privacy of those sensitive personal information):


At this point a question is legit: how are we able to see all those information if the disk is entirely encrypted? There must be some areas in memory which contain clear data, but the "only" difficulties are find and interpret them. Of course, we cannot analyze every single byte on the hard disk, so we need to develop a smart strategy that helps us finding the important stuff. So let's think simple: if the computer is able to boot, then there should be, at least, the bootstrapping code saved somewhere in clear. Usually those instruction are saved in the first(s) sector of the disk in a data structure called Master Boot Record (MBR). Indeed, that was the right direction that led us to identify 3 main internal components of the whole encryption system:

  • SafeBoot MBR: the first sector of the evidence we were working on, it contains the signature (in red) and a pointer to the SafeBootDiskInfSector


  •  SafeBootDiskInf Sector: here we can find in plaintext the same information showed in the Disk Information window. This and the following sectors in the same memory region are linked together with a double-linked list, whose pointers are tracked at the end of the sector itself, along the special signature SBfs (n.d.r. SafeBoot File System, or at least what we inferred). In this area we can look at:
    • SafebootDiskInf signature
    • Disk ID, an integer auto-incremental identifier of the disk
    • Disk Crypt List, sector pointer, where we where we can find the number of defined encrypted areas of this logical disk, the physical first and last sector of the region, and the number of sectors in the region
    • Disk GUID, a unique little-endian 16-bytes value which has to be read in the following format: XXXX-XX-XX-X-X-X-X-X-X-X-X
    • Algorithm ID, an identifier for the cryptographic primitive adopted, in this case 18 (0x12 in hexadecimal) means AES-256-CBC
    • Sector Map, an address, express in sectors, of the Sector Map area, which is the subject of the next section
    • Sector count, the number of sector in the region
    • Key check, a useful value for recovery operations in case the XML file with the key went missing

  • SectorMap Sector: here we can see what resemble an Hash-Map data structure: the "keys" are sector numbers, while the "values" are lengths. If we read n sectors starting from each of those pointers top-bottom, and we concatenate the buffers we obtain an entire FAT partition that was hidden and fragmented before.


The latter partition, as @dfirfpi already mention before, is a real goldmine for DFIR examiners and can be used for both blue team operations to retrieve useful information about the suspect, but also for the red team ones, since it contains a lot of configurations that can be tweaked to ease an entire class of exploits. For example, it contains the maximum number of attempts allowed to insert the master password that could be increased to perform a brute-force attack to recover the secret of the user.

Reverse Engineering experience

To build an application that can serve the decrypted disk, we must be able to understand how McAfee product implements its cryptography under the hood. Given that it is using the AES-256 algorithm in CBC mode (note that this is the default configuration, but there are more available), of which we own the secret key, we are still missing an important piece of information to be able to read in the clear the data: the initialization vector.
 
To describe better our experience, we divide this section in 3 parts:
  • DETech application
  • MfeEpePc driver
  • MfeCCDE driver
First of all we begun by reversing some of the features presented by the DETech applicative, starting with the decryption of the disk. After having mounted the encrypted device with the help of Arsenal Image Mounter, and ingested the program with the XML file containing the key, we investigate the flow of data after having clicked on the "Decrypt Workspace" button in the related window. And here our first discovery: all the cryptographic operations are performed at kernel level. The passage between these two "worlds" is clearly visible in the picture below.
 

After invoking the DeviceIoControl function from the Windows API core library, the control flow goes to the first of the two driver involved in this process, namely MfeEpePc. The latter is a filter driver that, given the buffer received from the user-space application, invoke different callbacks. The most important one, at some point in the middle of the instruction flow, jump (literally, with an unconditional jmp statement) to a function exposed at a very specific address in memory by the other driver, MfeCCDE, as we can see in the next picture.


Here we can find an implementation of the AES primitive along its mode (CBC in our case). At this point the whole reversing process got a lot easier! We just put a breakpoint in the WinDBG Preview debugger at that address to see the real value of the initialization vector that we were seeking from the beginning. The last two images of this sections show respectively a fragment of the implementation of the CBC mode and an AES round.



For the sake of completeness, I describe the shape of the initialization vector that we have found, since it played a very important role in our solution. It is a 16 bytes value, divided in four 32-bits integers, each of them representing the number of the sector we are trying to encrypt/decrypt. For example, if we had worked on the 1000-th sector, which is 0x3e8 in hexadecimal, its corresponding IV would have been: 00 00 03 e8 00 00 03 e8 00 00 03 e8 00 00 03 e8.

For the most curious among you, this blogpost was a big inspiration, and an influential source of knowledge. It helped a lot in understanding the most intricate parts of the reversing process, a highly suggested reading!

McAFuse

After all the research work, it was time to do some coding! We decided to implement an open-source tool that is shaped as a CLI util to help forensics examiners in the analysis of devices encrypted with this McAfee product. From a technical point of view, it was implemented in Python3 language, with the help of FUSE framework. FUSE stands for File system in USEr space. Basically it allows the programmers to write file systems, that usually are very complex piece of code, with ease by only overriding the behavior of the most common and basics operations, like write(), or read(), for example. To present the user an interesting interface we decided to implement a static, read-only file system with only two files:
  • SafeBoot.disk: the FAT partition that McAfee FDE solution install on the disk that encrypts, presented above
  • encdisk.img: the partition or the disk encrypted, depending on the parameter passed to the program
If the XML file containing the key is provided, then the user can see both files. In case the latter is missing, they can see only the first of the two files.

To emphasize the "read-onlyness" property of the exposed file system it is sufficient to say that we implemented this property at two different levels:
  • the write() operation was not implemented, instead for each request of this type our code throws an exception
  • the permissions on the files are 0444, that means read-only for owner, group and others
At the moment McAFuse is available only on GNU/Linux. For those who are interested in all the CLI parameters accepted by our program, please have a look at the README file present in the root directory of our project on GitHub (link below).



Conclusions

After 5 months of hard work this project came to a very successful end. We were able to implement a CLI tool to simplify the life of the DFIR examiners, letting them handle evidence with an easier and safer procedure than before. I could not have been able to terminate the work without the support I received from both my supervisors, @dfirfpi and Prof. Giovanni Lagorio, for this reason I am very grateful to them. 

For those who are interested in the tool, you can find it here. Feel free to play with the code, and eventually provide a PR to improve it, I will be available to further discuss modifications, and improvements. Thank you all for the attention, and happy investigations!
 
@dfirfpi here - Thank you Andrea for your great work! For those who want to keep in touch with Andrea, here are his links: linkedin, github and email.

Comments

Popular posts from this blog

A first look at Android 14 forensics

Huawei backup decryptor

WhatsApp Xtract