📦 Volatility3 : Alternate Data Stream Scan

Abstract Link to heading

The Master File Table (MFT) is the core metadata structure for the New Technology File System (NTFS). This table can be seen as a database that contains every information needed to describe all the files. The MFT itself is stored on the disk, usually in a reserved area at the beginning of the partition. When accessing a file on an NTFS volume, the operating system looks up the file’s MFT entry to retrieve the necessary information. However, during normal operation, the operating system may cache MFT entries in memory for faster access. This resulted into a volatility3 plugin called “mftscan”.

NTFS is providing a feature called alternate data streams (ADS). Used by Windows, it consists of another stream of data that can be attached to a file without changing its size or content. This feature can be abused by attackers to hide information like code or malicious content. It can also be a great digital forensics artefact to identify the origin of some files.

In this blogpost, we will dive into the possibility of creating a volatility3 plugin to scan for alternate data streams.

The Master File Table Link to heading

Forensic analysts utilize the MFT extensively as it provides a wealth of information during investigations. Every file or directory in an NTFS volume holds an entry in the MFT. Each MFT entry, also known as a record. By examining the MFT, one can acquire valuable insights into a system’s file activity, including deleted files or folders, timestamps, and access permissions. This information can be used to determine which files were created, accessed, modified, or deleted, and when these actions occurred for example.

The MFT records Link to heading

MFT entries or records are typically 1,024 bytes in size and are divided into several fields. Here is a very nice representation by Jaked Atinkson of an MFT record.

alt text

  • Header: Holds information about the record itself, such as its address and links to other records.

  • File Attributes: Reveal crucial details about the file or directory, including its name, timestamp, size, and permission. File attributes may either be resident, meaning they are stored directly within the MFT record, or non-resident, indicating that they are stored elsewhere on the disk with only a reference in the MFT entry.

The $DATA attribute typically contains the actual contents of the file, the data can be resident or non-resident.

A resident $DATA attribute means that the data is stored directly within the MFT record. This is usually the case for small files, where the data can fit within the record. The data will be stored directly in the MFT entry along with the metadata. Whereas a non-resident $DATA attribute is present when the file is too large for the record and therefore will contain a pointer to the location on the disk where the data is actually stored.

Alternate Data Streams (ADS) Link to heading

NTFS is providing a feature called alternate data stream (ADS). Used by Windows, it consists of another stream of data that can be attached to a file without changing its size or content.

alt text

One example of usage of this feature by Microsoft is the Zone.Identifier ADS. It is employed by Internet Explorer and other Windows applications to identify where a file was downloaded from and from a potentially unsafe zone (like the internet). This artefact is known to be very useful for forensics investigators. But it was also seen in the wild that some threat actors are abusing the ADS to hide malicious payloads. The ADS can be detected by the fact that a given record is holding multiple $DATA attributes.

Creating a volatility3 plugin Link to heading

The MFTScan plugin Link to heading

Even if the MFT entries are stored on disk, the latter also cached in memory, which motivated the creation of the “MFTScan” volatility3 plugin. This plugin is scanning for $STANDARD_INFORMATION and $FILE_NAME attributes providing a view of the files that were present in the volatile memory of the target system.

~» ./vol.py -r pretty  -f Triage-Memory.mem  windows.mftscan.MFTScan                                                                                                                                    
Formatting...0.00               PDB scanning finished                  
Volatility 3 Framework 2.5.1
   |         Offset | Record Type | Record Number | Link Count |  MFT Type |         Permissions |       Attribute Type |                     Created | ...|  Filename
*  | 0xf88004477450 |        FILE |        146309 |          2 | Directory |                 N/A | STANDARD_INFORMATION | 2019-03-21 15:47:00.000000  | ...| N/A
** | 0xf880044774b0 |        FILE |        146309 |          2 | Directory |                 0x0 |            FILE_NAME | 2019-03-21 15:47:00.000000  | ...| AM1080~1.175
*  | 0xf88004477850 |        FILE |        146310 |          2 |      File |                 N/A | STANDARD_INFORMATION | 2019-03-21 15:47:00.000000  | ...| N/A
** | 0xf880044778b0 |        FILE |        146310 |          2 |      File |             Archive |            FILE_NAME | 2019-03-21 15:47:00.000000  | ...| cfgmgr32.dll
** | 0xf88004477928 |        FILE |        146310 |          2 |      File |             Archive |            FILE_NAME | 2019-03-21 15:47:00.000000  | ...| cfgmgr32.dll
*  | 0xf88004477c50 |        FILE |        146311 |          2 | Directory |                 N/A | STANDARD_INFORMATION | 2019-03-21 15:47:00.000000  | ...| N/A
** | 0xf88004477cb0 |        FILE |        146311 |          2 | Directory |                 0x0 |            FILE_NAME | 2019-03-21 15:47:00.000000  | ...| AMEA70~1.175

The ADS plugin Link to heading

A new addition the capabilities of the MFT analysis in memory would be to scan for ADS inside the records looking for others $DATA attributes that are resident. This plugin was therefore created to detect ADS and extract the resident data to present it to the analyst. The output shows the file associated with the ADS found as well as a Hexdump and disassembled view. The latter could potentially help an analyst to identify a malicious code.

Proof Of Concept Link to heading

The example below is showing the output of the plugin. We can see that the “putty-64bit-0.70-installer.msi” for example was downloaded from the internet (see ZoneID=3 in the hexdump column).

~» ./vol.py -r pretty  -f Triage-Memory.mem  windows.mftscan.ADS                                                                                                                                    
Formatting...0.00               PDB scanning finished                  
Volatility 3 Framework 2.5.1
  |         Offset | Record Type | Record Number | MFT Type |                      Filename |    ADS Filename |                          Hexdump |                                          Disasm
* | 0xf98001423650 |        FILE |         78477 |     DATA | putty-64bit-0.70-installer.msi | Zone.Identifier |                                  |                                                
  |                |             |               |          |                               |                 | 5b 5a 6f 6e 65 54 72 61 [ZoneTra |                             0x0:    pop     rbx
  |                |             |               |          |                               |                 | 6e 73 66 65 72 5d 0d 0a nsfer].. |                             0x1:    pop     rdx
  |                |             |               |          |                               |                 | 5a 6f 6e 65 49 64 3d 33 ZoneId=3 |             0x2:    outsd   dx, dword ptr [rsi]
  |                |             |               |          |                               |                 |                                  |              0x3:    outsb   dx, byte ptr [rsi]
  |                |             |               |          |                               |                 |                                  |                             0x4:    push    rsp
  |                |             |               |          |                               |                 |                                  |                            0x6:    jb      0x69
  |                |             |               |          |                               |                 |                                  |              0x8:    outsb   dx, byte ptr [rsi]
  |                |             |               |          |                               |                 |                                  |                            0x9:    jae     0x71
  |                |             |               |          |                               |                 |                                  |                            0xb:    jb      0x6b
  |                |             |               |          |                               |                 |                                  |                 0xe:    or      eax, 0x6e6f5a0a
* | 0xf98001432e40 |        FILE |         78539 |     DATA | PackageManagement_x64.msi     | Zone.Identifier |                                  |                                                
  |                |             |               |          |                               |                 | 5b 5a 6f 6e 65 54 72 61 [ZoneTra |                             0x0:    pop     rbx
  |                |             |               |          |                               |                 | 6e 73 66 65 72 5d 0d 0a nsfer].. |                             0x1:    pop     rdx
  |                |             |               |          |                               |                 | 5a 6f 6e 65 49 64 3d 33 ZoneId=3 |             0x2:    outsd   dx, dword ptr [rsi]
  |                |             |               |          |                               |                 |                                  |              0x3:    outsb   dx, byte ptr [rsi]
  |                |             |               |          |                               |                 |                                  |                             0x4:    push    rsp
  |                |             |               |          |                               |                 |                                  |                            0x6:    jb      0x69
  |                |             |               |          |                               |                 |                                  |              0x8:    outsb   dx, byte ptr [rsi]
  |                |             |               |          |                               |                 |                                  |                            0x9:    jae     0x71
  |                |             |               |          |                               |                 |                                  |                            0xb:    jb      0x6b
  |                |             |               |          |                               |                 |                                  |                 0xe:    or      eax, 0x6e6f5a0a

Conclusion Link to heading

The ability to scan for Alternate Data Stream is a good way to identify whether a file was downloaded from the internet or not. One can also identify malicious hidden data to help analysts upon an investigation to shed light onto the attack chain. The source code of this plugin can be found on Github: https://github.com/forensicxlab/volatility3/tree/feature/ADS, a pull request will be made to the volatility3 foundation for a potential integration to the framework.

Do not hesitate to reach me at felix.guyard@forensicxlab.com to enhance this article or to comment on the integration to the volatility framework.