[Cmdlets referenced in this article must be run with Local Administrator or equivalent permissions]
Every Forensicator or Incident Responder has run into the dreaded ‘locked file’ at least once (probably A LOT more than once). Whether it is the Master File Table, UsnJrnl, or a Registry Hive, it seems that juicy forensic data is always contained in one of these locked files. One of my favorite PowerForensics features is the ability to find a file’s data on disk and access it directly, bypassing file system restrictions such as permissions and file locking. This feature is a key component of PowerForensics, forming the base on which all artifact parsing is built. The image below shows what happens when I try to use PowerShell’s Copy-Item cmdlet to make a copy of the SAM hive… I receive a “file in use” error.
This post looks at three methods to copy a locked file with PowerForensics. For us to properly understand what is happening under the hood for each of these methods we must start by viewing the SAM hive’s Master File Table Entry (File Record). Get-ForensicFileRecord is PowerForensics’ cmdlet for parsing the Master File Table. In the image below we are using the Path parameter to look at the single entry for the SAM hive.
Get-ForensicFileRecord returns a FileRecord object representing a Master File Table entry. NTFS files store their content in two ways, resident or nonresident. If the data is resident, it is stored within the 1024 byte Master File Table Record which typically means it is less than 600 bytes. In most cases, the data is nonresident meaning it is stored elsewhere on the hard drive. In the case of nonresident file data, the Master File Table Record’s ‘DATA’ attribute contains pointers to the actual contents. In the following image we see that the SAM file’s contents are of the nonresident type, and we are able to drill in enough to see that the Data Runs are those pointers I talked about before.
According to the Data Runs the SAM hive is a fragmented file that is made up of 2 clusters starting at cluster 9720724 and 14 clusters starting at cluster 12006058. The rest of this article explains three different methods that leverage this information to access the SAM hive’s content and copy it to a non-locked file that can be analyzed offline.
Method 1: Invoke-ForensicDD
Invoke-ForensicDD is my best effort at porting the classic unix disk duplicator (dd) utility to PowerShell. We can use this cmdlet to copy the bytes that represent the SAM hive without accessing the SAM hive (the file) directly.
Now that we have the VBR we know that this volume is formatted with 4096 bytes per cluster. Next, let’s revisit the SAM Hive’s DataRun property. Remember that in this case we are dealing with a fragmented file which is why we see two DataRun entries.
The first fragment starts at cluster 9720724 and is 2 clusters in length and the second fragment starts at cluster 12006058 and is 14 clusters in length. With this information we can use Invoke-ForensicDD to copy both fragments to a file.
Before we use Invoke-ForensicDD, let’s look check out its cmdlet help for usage instructions.
According to the help, we must provide an InFile (the file, volume, or disk to read from), an optional OutFile (the file to output the data to), an Offset (location to start reading from), BlockSize (the number of bytes to read at one time), and a Count (the number of “Blocks” to read). Since we are dealing with a fragmented file we will need to issue the command once per fragment (twice total in this example). We will be reading from the \\.\C: logical volume (InFile), and will output to C:\evidence\SAM_copy1 (OutFile). Our Offset and BlockSize parameters are derived from each DataRun. The offset will equal DataRun.StartCluster * VolumeBootRecord.BytesPerCluster or in the case of fragment 1 9720724 * 4096. The BlockSize will be DataRun.ClusterLength * VolumeBootRecord.BytesPerCluster or for fragment 1 2 * 4096. For these examples we will set Count to 1. In the image below you can see Invoke-ForensicDD is used twice, once for each fragment, to copy the SAM Hive to the evidence directory.
NOTE: In the picture below, I store a lot of information in variables. This was done to make the image easier to follow and is not 100% necessary.
Now we can open SAM_copy1 in our favorite Registry viewer.
Method 2: CopyFile Method
Without realizing it we already have another method set up. The PowerForensics.Ntfs.FileRecord object has CopyFile method built in. CopyFile understands the major concepts of how data is referenced in the Master File Table, so concepts like resident vs. nonresident data and fragmentation are made transparent to the user. The image below pipes our save FileRecord object into the Get-Member cmdlet which outputs a list of methods and properties that make up a FileRecord object (remember that $r is stored the result of Get-ForensicFileRecord from earlier).
You may have noticed that the CopyFile method was the very first method in the list and that it has multiple overloads or ways to call it. To get a better view of the method overloads, and thus what arguments the method is expecting, we can call the method without parentheses as seen in the next image.
It appears that there are two ways to call CopyFile. We will be focusing on the first overload since we are dealing with the main “data stream”. If we wanted to copy a specific “data stream”, often referred to as an Alternate Data Stream, we would use the second overload. Now all we have to do is execute the method with a destination path (C:\evidence\SAM_copy2) and we end up with a perfect copy of the SAM hive.
NOTE: PowerShell requires strings to be enclosed in quotes when passing it to a method.
There you have it, we now have SAM_copy2 in the C:\evidence directory. Looks like method 2 was successful.
Method 3: Copy-ForensicFile
The third method provides even one more layer of abstraction to the user. The Copy-ForensicFile cmdlet requires a Path and a Destination and will do all of the work for you. In the image below, I show Copy-ForensicFile being used to copy the SAM hive to C:\evidence\SAM_copy3.
Once again, it looks like our copy was successful. We have what we assume are three identical files that were copied using three different techniques. To check to make sure all three files are the same we run them through PowerShell’s Get-FileHash as seen below.
Looks like it opened successfully! As you might have guessed each of the three techniques build off each other. The beauty of having three different methods is the granularity of control that each gives you. Method 1 allows you to copy any arbitrary bytes from a hard drive, but may require a bit more “forensic” knowledge to know what bytes are important. Method 3 requires very little background knowledge but will accomplish the task that it is meant to accomplish. One of the cooler concepts behind PowerForensics is that this single tool can leverage each of these techniques to accomplish the next step in the analysis chain. If you want to parse the SAM hive that can be accomplished via Get-ForensicRegistryKey and Get-ForensicRegistryValue which uses the same code in the background as Copy-ForensicFile with the exception of creating an output file. Stay tuned for many more articles and blog posts on different PowerForensics capabilities and use cases.