Cleaning NTFS artifacts with FSCTL_CLEAN_VOLUME_METADATA
NTFS is the main filesystem used within Windows OS to store your files and folders. As every single filesystem, NTFS not only stores your data, but also some additional data about your data, usually called metadata. It may be not the most important thing for you, but it is priceless when it comes to some forensics activities. Two most important examples include:
- analyze deleted files. As deletion is performed as marking an entry within MFT with “deleted” bit and does not touch the real data, scanning such MFT entries may tell an investigator deleted files name, size, location etc.
- analyze data history. Every single operation on the disk is optionally recorded into a journal. Reading such journal (i.e. with fsutil usn) may provide detailed information about file-related activities, sometimes years back.
You do not like to leave any traces? Of course, if you can access the disk below the filesystem level, you can scan such structures and wipe them. It may be time consuming, complex and potentially dangerous as manipulating such structures unofficial way is always related to some risk. You can also intentionally destroy all data with “format /P:0”.
And what if I tell you, that NTFS is fitted with “metadata cleanup” functionality? You have to send a special code to the disk device and it will wipe unused MFT entries, journal and couple of other structures without touching live files on the disk. Unfortunately, Microsoft does not document it, but had to admit such feature exists to avoid a gap in the feature numbering on the position #223.
In general, when any process tries to manipulate filesystem, it finally calls a DeviceIoControl() function, providing requested operation in the form of IOCTL (I/O control code) or FSCTL (file system control code). Such codes are listed in the ntifs.h distributed by Microsoft, but only part of these is documented at https://docs.microsoft.com/en-us/windows/win32/api/winioctl/
When I started to play with the code “FSCTL_CLEAN_VOLUME_METADATA”, I have realized it does not work as expected, making DeviceIoControl return 1 (“Incorrect function”). As it could be related to some “protection” of the live volume, I had to try it from WindowsPE. Surprisingly, return codes were totally different (5, 19, 21, 32, etc.) depending on the scenario, but never obtained “Incorrect function” anymore. After some manipulations (sending FSCTLs about dismount, offline, etc.) I have finally made it working and returning the expected BOOL value. I have then realized; exactly the same operation sequence should be working on the live OS as well. Nope. Error 1. Which means not I am doing something wrong (as I observed results under WinPE) but the OS tries to tell me it refuses my calls just because. I have spotted some WinPE-only features previously, and I know it is usually related to the MiniNt registry key. I have added it, but nothing changed, so I have tried with a reboot. And now it works like a charm. If you want to repeat it on your own, you should:
- Unlock the feature by adding MiniNt key
- Use GetVolumeNameForVolumeMountPoint() to obtain the GUID path to the volume (you can also display it from cmdline using mountvol command)
- Open the handle to your volume (do not use trailing backslash as you open a device and not a root folder on it)
- Call DeviceIoControl() with dwIoControlCode equal to FSCTL_CLEAN_VOLUME_METADATA. Feel free to use NULLs as other parameters.
And you have it. MFT for unused entries is gone, journal is gone and now I am really curious what else. Of course, my files and folders remain intact.
One important conclusion at the very end, if you want to try this in the production environment: do not leave your system working with MiniNt key present during the boot. It affects somewhat unpredictable areas of the OS, especially the auditing subsystem. Your OS will be totally blinded. But have fun anyway!