Incident Response with NTFS INDX Buffers – Part 3: A Step by Step Guide to Parse INDX
October 10 2012By William Ballenthin & Jeff Hamm
Our last post in the Incident Response with NTFS INDX Buffers series detailed the internal structures of the NTFS filename attribute. In this post, we'll use a tool to parse the active contents of INDX records and carve for inactive information out of the slack space. NTFS indices track the contents of a directory by using the filename attribute structure. This includes file name, MACb times, and file sizes. This is the third post in a four part series that includes:
- Part 1: Extracting an INDX Attribute
- Part 2: The Internal Structures of a File Name Attribute
- Part 3: A Step by Step Guide to Parse INDX
- Part 4: The Internal Structures of an INDX Structure
Part 3: A Step by Step Guide to Parse INDX
Once you find an INDX record of interest, you can use it as a timeline artifact. In the example we present today, we will look for executable files in a particular path. If we do a logical listing of this path, we will not see any executable files - as either allocated or deleted. Figure 1 is a file listing from FTK Imager. If there were deleted files with active $MFT records, the files would be listed using FTK Imager or other forensic tools.
Figure 1: File ListIf we look at the hexadecimal dump of an INDX attribute, we can see the Unicode string "RC255~1.EXE". This looks like a Windows 8.3 short filename. Based on the file extension, this is probably an executable file. This INDX record suggests that an executable file used to reside in the directory of interest. Continuing the cursory glance, we also note a filename that indicates a Microsoft Word document in the INDX attribute content. Figure 1 displays a partial hexadecimal dump of the INDX attribute. INDX attributes seem to contain data that may help us to reconstruct the previous contents of a directory.
Figure 2: INDX Hex DumpINDXParse.py
INDXParse.py is an open source Python script written by Willi Ballenthin that parses INDX attributes into a human readable format. You can download it from the GitHub repository (https://github.com/williballenthin/INDXParse). The script can extract file names, MACb file timestamps, and file sizes from INDX records. INDXParse.py produces output in either a CSV or Bodyfile format (http://wiki.sleuthkit.org/index.php?title=Body_file). You can use this tool to extract file information from slack space in an INDX attribute as well. This means we can partially reconstruct the old contents of a directory. We will detail the INDX attribute slack space in Part 4 when we explain the structure of an INDX buffer in detail. Figure 3 lists the INDXParse.py options and usage.
Figure 3: INDXParse.py OptionsUsing the techniques we described in the first part of this series, we used FTK Imager to extract the INDX allocation attribute for the directory we were examining. Using INDXParse.py, we can recover timeline information and indicators for the file "RC255~1.EXE". Figure 4 displays the command we used to print the output to our console. We used the "-c" option to send the output to a CSV format, and we used the "-d" option to find entries in slack space.
Figure 4: INDXParse.py CommandFigure 5: Console OutputFor
sorting, we redirected the output to a CSV file by using the command
"python INDXParse.py -c -d $I30 >
INDX.csv".
Figure 5 lists the output in a spreadsheet
table. From the output we can see that the file
"RC255~1.EXE" was created on September 28, 2012 at
12:41:48 UTC and was 139,264 bytes in size. In total, INDXParse.py
identified two active files in the directory and evidence of at
least three deleted files in the directory.
Because a directory INDX is a b-tree structure, it sorts data as records are added or removed. This can result in the INDX containing more than one entry for the same file. For example, the "WORD~1.DOC" file is listed twice in Figure 6. This is the result of reorganization of the folder by NTFS over time.
Conclusion
Using the tool INDXParse.py, we can extract information not available to us from traditional file listing methods. We were able to establish in our example the existence of the file "RC255~1.EXE" when a file listing with other forensic tools had failed. In our final post, we'll revisit the hex dump from our INDX and detail the internal structures of the NTFS INDX attribute.