Forensic techniques against hackers evading the hook (notes from NIC conference)

In reference to my talk at Nordic Infrastructure Conference 2017: “Explore adventures in the underland: forensic techniques against hackers evading the hook” I am sharing slides, tools and some extra step by step on how to recover files from the drive.

Slide deck from my session at Nordic Infrastructure Conference 2017: “Explore adventures in the underland: forensic techniques against hackers evading the hook”.

Tools from the session

Here you can find the most important tools I used during the session!

>> Get the tools from this session <<

Hackers…

Cybercrime is a very lucrative business not just because of the potential financial return, but because it quite easy to get away with. Sometimes hackers get caught, but most of the time they still run free. When it comes to operating system and after-attack traces, it is not that bad as all traces are gathered in one place – your infrastructure. Even though hackers use techniques to remain on the loose, it is possible by using forensic techniques to gather evidence in order to demonstrate what actually happened. During this super intense session, I demonstrated techniques used by hackers to hide traces and forensic techniques that indicate how these activities were performed.

PowerShell Forensics

Time to do some forensics! Attach a given VHD in your system as X:. You need to start PowerShell ISE as an Administrator to perform these tasks.

The story goes like this… So we have a disk from attacked machine. Of course, you never should work on a real piece of evidence! If you have the physical disk you can use for example Sysinternals Disk2VHD utility and if you have a VHD file – just work on a copy keeping the original in a safe place.

Of course, the very first thing to be done is to attach the VHD to our machine.

$VHDPath=“c:\ForeDemo.vhdx” 
$disk= Mount-VHD -Path $VHDPath  

Just to make sure everything works fine:

dir x:\  

It works but there is absolutely nothing on it. At this point, we have no idea what happened and why data is not where it should be but let’s ask the MFT.

Install-Module PowerForensics
Import-Module PowerForensics -Verbose
Get-ForensicFileRecord -VolumeName x: | Where-Object {$_.Deleted}

We have found something here! Let’s write down the RecordNumber property.

As you can see it was a mysterious p.exe file and it was deleted. Let’s try to figure out what this executable was about. As you can see the name is not really useful here. It is common practice to use very short names for tools used for attack because it keeps the scripts and commands more compact and easier to pack into some payloads.

Now instead of looking for deleted files we can ask about this particular one and store the result in $fr (like “file record”) variable:

$fr=Get-ForensicFileRecord VolumeName x: -Index 38

Inside we have one very nice property. Let’s display all of them first:

$fr | select *

And now let’s focus on “Attribute”:

$fr.Attribute

As you can see there is STANDARD_INFORMATION, FILE_NAME and DATA. Data has a property called “DataRun”. We all love DataRun and for a reason 😉

Let’s store DATA attribute in a new variable and let’s examine the DataRun property.

$fd=$fr.Attribute | Where-Object {$_.name –eq DATA’}

$fd.DataRun

Here we have an information about data kept on a disk for this file. File is not sparse (not being sparse is very normal for executable files), it starts in a cluster 8267 and it is 130 clusters long. The good news is it is kept on the disk in one piece, not split into multiple fragments. With fragmented files it is not more complicated at all but it requires more PowerShell commands which makes the process more error prone.

So we have cluster numbers. Here we need one piece of information more: the cluster size in bytes. It may be different so instead of guessing we have to read it from the Boot Record of the disk:

Get-ForensicVolumeBootRecord -VolumeName x:

The interesting value here is (what a surprise!) BytesPerCluster equals here 4096. Let’s remember it.

The magic we have to do right now is: read X bytes from the device starting at some offset. Let’s do this:

Invoke-ForensicDDInFile \\.\X: -Offset (8267*4096) BlockSize (130*4096) Count1 OutFile c:\test.exe

Now we can go to the C:\ and see the file created! It has an icon, description etc now so it looks like a success. It even works. The only thing to mention is we have read entire clusters not the real amount of bytes of the original file. This does not affect how executable file works but for some other format may be significant.

But please do not forget that in Attributes we had the actual size so if we would like to be very strict we should truncate the file.

Trimming the file

Let’s return to our variable:

$fd

As you can see the allocated size is larger than real size – only 531368 bytes. To make everything just perfect we can trim the file we have created on the disk.

$bytes = [System.IO.File]::ReadAllBytes(“c:\test.exe”)

$bytes = $bytes[0..531367]

[System.IO.File]::WriteAllBytes(‘c:\test2.exe’,$bytes)

And now we can open properties of the test2.exe file and you can see even the digital signature is valid!

My favorite Forensic trick

Now comes one of my favorite forensic tricks. It is based on how NTFS filesystem works. Let’s do a small demonstration. I will create 10 small text files containg 10x “cqure” string inside.

for ($j=0; $j -lt 10; $j++) { for ($i=0;$i -lt 10;$i++) {“cqure” | Out-File -FilePath “x:\wipeme$j.txt” -Encoding ascii -Append}}

As you can see in this file there is 10 * cqure. No rocket science.

Let’s Shift+Delete these files. (F5 if necessary)

Is the real data left on the disk? Sure it is! So let’s wipe the free space.

cipher /w:x:\

Every single unused byte on the x:\ should be written with 00, then FF then some random value.

Do we have any file on this disk? Well. It depends on what do you mean by “file”. The most exciting one is x:\$MFT – Master File Table. .

Get-ForensicFileRecord -VolumeName X: -Index 0

(OPTIONAL)

BTW it is pretty interesting because it has a parent with index 5.

Get-ForensicFileRecord -VolumeName X: -Index 5

This is a root directory indicated as a parent (which makes sense) but the root directory has an index equal to 5. So it means the file was created before the directory it stays in.

Final thoughts

The time is the UTC time if you are interested why it is not just a couple of seconds old if we just played with the volume.

Let’s copy MFT from the X: drive to c:\xmft.txt using CopyFile() method.

(Get-ForensicFileRecord -VolumeName X: -Index 0).CopyFile(“c:\xmft.txt”)

Now we have an MFT structure saved into a txt file, we can open it using any editor and scroll a couple of lines down or just search for “cqure”. And what you can see here is the content of the files we have just deleted and wiped.

Why was the data not wiped? The answer is simple and it is an effect of NTFS filesystem architecture. If we recreate the file

for ($i=0;$i –lt 10;$i++) {“cqure” | Out-File -FilePath x:\wipeme.txt -Encoding ascii -Append}

Then right click it and select properties we can observe how much place it takes on the drive. Looks reasonable..? Well, it depends on your understanding the NTFS. But at least one thing should be clear right now – if it takes zero bytes on the drive, even if you wipe the space couple of times it will not destroy the data, right?

Actually, the mystery here is pretty easy to explain: small files (up to approximately 700B) fit entirely into MFT record and sometimes referred as “resident” data. If we delete such file and then wipe unused space, the file stays in the MFT (of course marked as deleted) but the MFT occupies some space on the drive and this space is marked as used – obviously MFT remains on the disk even if we delete a couple of files. So the wipe operation does not wipe the real data of the file. Pretty nice thing to have if we are doing the forensics.

Comments