Mastering the NTFS $DATA Attribute: From Resident Data to Complex Runlists and ADS in Digital Investigations



In the examination of NTFS Master File Table (MFT) records, the $DATA attribute (type 0x80) assumes paramount importance as the primary repository for file content. This attribute either encodes mapping metadata—via a runlist—to resolve the on-disk location of the file’s allocated clusters or, for sufficiently small streams (typically ≤ ~700 bytes, contingent upon MFT record utilization by other attributes), stores the data directly within the MFT record itself in resident form, thereby optimizing I/O efficiency and minimizing fragmentation.


While conventional file systems impose a singular one-to-one correspondence between a file and its primary data content, NTFS imposes no such architectural constraint. A file may possess multiple associated data streams (also known as Alternate Data Streams or ADS when named). The default (unnamed) $DATA attribute represents the primary data fork visible to most applications and the Win32 API. Additional named streams (e.g., $DATA:"Zone.Identifier", $DATA:"AFP_AfpInfo", or user-defined streams) can coexist within the same MFT record, each potentially resident or non-resident, and each independently allocated and accessible.


This multi-stream capability, while powerful for metadata embedding, application-specific storage, and certain persistence techniques, introduces significant forensic considerations, including the potential concealment of data in alternate streams that are often invisible to standard directory listings and many forensic triage tools.




The $DATA attribute is identified within an MFT record by its 4-byte type signature value of 0x80 (128 decimal). The common attribute header (beginning with the 4-byte type identifier and 4-byte length field) is followed by the attribute body, which either contains the actual file content (for resident attributes) or the metadata required to resolve the Logical Cluster Numbers (LCNs) of the on-disk allocations (for non-resident attributes).


A single-byte non-resident flag located at offset 0x08 within the attribute header designates residency status: 0x00 indicates a resident attribute whose content is stored directly within the MFT record, while 0x01 denotes a non-resident attribute whose data resides in external clusters. Virtual Cluster Numbers (VCNs) furnish a contiguous, zero-based logical addressing mechanism for the ordered clusters comprising the data stream. While the VCN range for the primary $DATA attribute typically commences at zero and extends through the highest VCN (corresponding to the total clusters consumed), rare cases—such as fragmented attributes or those described via an attribute list—may exhibit non-zero starting VCNs; additionally, the highest VCN may be set to -1 for zero-length streams.


The Allocated Size (in the non-resident header) reflects the aggregate on-disk cluster space consumed by the attribute, encompassing both file content and associated slack space. The True Size (Real Size or Data Size) specifies the precise logical length of the file content. The Initialized Size represents the extent of pre-allocated and initialized space reserved by the operating system for potential file growth; although this region is allocated on disk, it is not yet considered part of the logical file content until explicitly written.


For non-resident attributes, the data runs (runlist) provide a compact description of the file’s allocated segments. The runlist consists of a series of variable-length entries, each commencing with a 1-byte header. This header’s high nibble encodes the byte length of the signed LCN offset (delta) field, while the low nibble encodes the byte length of the run length field. The first run’s LCN offset is absolute, with subsequent offsets expressed as signed deltas relative to the prior LCN, thereby efficiently supporting contiguous, fragmented, sparse, and compressed allocations. The runlist is terminated by a null byte (0x00).



The forensic breakdown is given in the table below:


Bytes

Meaning

Value

Explanation

32

Header

0x32

High nibble (3) = 3 bytes for offset Low nibble (2) = 2 bytes for length

4A 01

Run Length (little-endian)

0x014A = 330 clusters

Number of contiguous clusters in this run

94 6B 01

LCN Offset (little-endian, signed)

0x016B94 = 93,076 (decimal)

Starting Logical Cluster Number (LCN) for this run

00 00

End of runlist

0x0000

Terminator (null bytes)


In NTFS, a file may possess multiple data streams beyond the default (unnamed) primary data fork. These secondary streams are formally designated as Alternate Data Streams (ADS). Key characteristics include:

  • ADS are tightly bound to the parent file’s MFT record but remain orthogonal to the primary data stream; consequently, they exert no impact on the file’s reported size or content as presented by standard file system APIs and directory listings.
  • Each ADS is identified by a discrete Unicode name (e.g., Zone.Identifier, AFP_AfpInfo, or arbitrary user-defined streams).
  • Every ADS maintains independent metadata, including its own $DATA attribute type, residency status, and size fields.


In the examined secondary $DATA attribute (representing an ADS), the attribute is likewise non-resident. The name length field at offset 0x09 contains 0x0E (14 Unicode characters). The name offset at 0x0A is 0x40, directing the analyst to read 14 × 2 = 28 bytes of little-endian UTF-16LE data beginning at that relative offset to recover the stream name. Also, notice that the name offset and content offset are different since the name is present in the ADS.

For resident ADS, content extraction follows the identical procedure as the primary stream: locate the value offset and read the specified length of data directly from the MFT record. Should the ADS be non-resident, its attribute header would instead contain a runlist (mapping pairs) analogous to that observed in primary non-resident $DATA attributes.

In essence, Alternate Data Streams constitute additional named instances of the $DATA attribute (type 0x80) attached to the same MFT record. This parallels the capability of multiple $FILE_NAME attributes per file. The primary (default) data stream is always unnamed, with its logical identity derived from the associated $FILE_NAME attribute. Any supplementary $DATA attributes must carry an explicit name to enable addressing. For resident ADS, this name is stored as a Unicode string immediately preceding the content; for non-resident ADS, the name precedes the data runs in the attribute body.


Alternate Data Stream (ADS) functionality was originally included in Windows NT as part of the Services for Macintosh feature. Its purpose was to allow a Windows File Server to support the concept of a Resource Fork that exists in classic Mac filesystems (HFS). Ironically, Macintosh clients never really used ADS. Instead, they create a second hidden file to store the additional data (the Resource Fork equivalent). Because the rest of the Windows operating system is designed to only work with the primary data stream, most built-in tools (dir, type, Explorer, etc.) cannot report the existence of alternate data streams, show their size, or display their contents. No additional metadata is maintained for ADS beyond the basic stream data. This lack of visibility makes ADS an attractive hiding place for illicit tools, malware, stolen data, and persistence mechanisms.


Microsoft has implemented restrictions on ADS usage over the years to mitigate abuse. However, attackers continue to develop workarounds, making it important for defenders and forensic analysts to actively hunt for unexpected or suspicious alternate data streams.


Another very useful tool from The Sleuth Kit is icat. With icat, you can provide a disk image file and an MFT entry number (also known as the “inode” number). It will locate the corresponding metadata entry and extract the file or attribute contents. Provide just the MFT entry number (inode) → icat exports the default $DATA stream. Provide both the MFT entry number and a specific attribute ID to extract other data, including alternate data streams, e.g., Zone.Identifier as attribute 128-9).



icat is not limited to extracting contents of the $DATA attribute. It can also be used to retrieve data from other NTFS attributes, such as $STANDARD_INFORMATION, $FILE_NAME, $SECURITY_DESCRIPTOR, $OBJECT_ID, and various other resident or non-resident attributes. This flexibility makes icat a powerful tool for deep forensic analysis of NTFS file system metadata. This capability is especially valuable when investigating hidden data, alternate streams, or detailed file metadata that standard tools ignore.


The Zone.Identifier ADS: Evidence of Download

The presence of the Zone.Identifier Alternate Data Stream (ADS) explains the mechanism by which Microsoft Office applications (Word, PowerPoint, Excel, etc.) identify files as having originated from the Internet, thereby triggering the protected “Enable Editing” / “Trust” prompt.

When a file is downloaded to an NTFS volume, the operating system and applications append a named $DATA attribute called Zone.Identifier. This stream serves as a persistent security tag. From a digital forensics perspective, it constitutes a high-value artifact that enables rapid identification of downloaded files and, in many cases, provides provenance indicators regarding their source.


The core functionality of Zone.Identifier ADS was introduced in Windows XP SP2 (2004) as part of enhanced attachment and download security. Most modern web browsers (Chrome, Edge, Firefox), email clients, and many chat applications automatically attach this stream when writing files to NTFS. This capability is formally known as Mark of the Web (MotW) and is implemented through the Windows API function IAttachmentExecute::SetLocalPath and related Attachment Services. The presence of a Zone.Identifier ADS is a reliable indicator that a file traversed the Internet or was received via an untrusted channel. It typically contains a simple INI-style structure such as this.


[ZoneTransfer]
ZoneId=3


(Zone 3 = Internet zone; other values include 0 = Local Machine, 1 = Local Intranet, 2 = Trusted Sites, 4 = Restricted Sites).


However, command-line tools (e.g., PowerShell, ftp.exe, curl) often do not create MotW tags. Internet Explorer historically applied selective tagging based on file type risk. Privacy-focused sessions in Firefox and Chromium-based browsers may redact or omit fields such as ReferrerUrl and HostUrl.


The screenshot at the top of the figure above, captured using FTK Imager, illustrates a Zone.Identifier Alternate Data Stream (ADS) and its decoded contents. Analysis focuses on the metadata logged within this named $DATA attribute. In the examined case, the file under scrutiny was a copy of the Velociraptor digital forensics tool, downloaded from GitHub. Testing across multiple browsers (Google Chrome, Mozilla Firefox, and the latest Microsoft Edge—Chromium-based) produced identical Zone.Identifier content. A comparative test using legacy Internet Explorer yielded only the minimal ZoneId=3 entry, omitting richer fields such as ReferrerURL and HostURL.


In super timelines derived from MFT records (e.g., via tools processing $STANDARD_INFORMATION and $FILE_NAME attributes), ADS entries appear as distinct lines. However, they do not maintain independent timestamp sets. Instead, they inherit the temporal metadata (Created, Modified, Accessed, MFT Entry Modified) of their parent file. This linkage is critical for accurate temporal reconstruction.


The presence of a populated Zone.Identifier ADS (particularly with ZoneId=3) provides strong evidentiary context that the file was downloaded from the Internet via a modern browser. Such artifacts serve as excellent pivot points. For example, discovering executables with MotW tagging in anomalous locations (e.g., C:\Windows\System32, C:\Program Files, or user profile subdirectories) should raise immediate suspicion. A substantial proportion of compromise events begin with a user downloading a malicious, vulnerable, or trojanized file. The Zone.Identifier ADS often enables rapid identification and scoping of initial access vectors.


The Zone.Identifier stream remains one of the most reliable and low-effort indicators for establishing file provenance in NTFS-based investigations. Its consistent application by modern browsers makes it a cornerstone artifact in timeline analysis and user activity reconstruction.


The minimum mandatory information recorded in a Zone.Identifier Alternate Data Stream is the ZoneId value. The currently defined ZoneID enumerations are as follows:


ZoneId

Symbolic Name

Description

-1

NoZone

No zone information assigned

0

MyComputer

Local machine / local file

1

Intranet

Local Intranet zone

2

Trusted

Trusted Sites zone

3

Internet

Internet zone (most common for browser downloads)

4

Untrusted

Restricted / Untrusted zone


Note: A ZoneId=4 (Untrusted) tag is automatically applied by Microsoft SmartScreen when it flags a file as potentially malicious or high-risk. In some cases, SmartScreen may also append additional proprietary data streams or extended attributes beyond the standard Zone.Identifier ADS.


Adversaries continuously evolve evasion techniques to circumvent detection by defenders and security tooling. Alternate Data Streams (ADS) represent a potent native NTFS feature for such purposes. Because the vast majority of Windows applications, APIs, and forensic tools default to interacting exclusively with the primary (unnamed) data stream, hidden content stored in named ADS often remains invisible to standard operations. This technique is formally documented in the MITRE ATT&CK® framework as T1564.004: Hide Artifacts: NTFS Alternate Data Streams.


Red team operators and malicious actors frequently leverage ADS for payload storage, persistence, and execution. The LOLBAS (Living Off the Land Binaries and Scripts) project — originally developed by red-team researchers — catalogs numerous native Windows binaries capable of reading from, writing to, and executing code directly from alternate data streams, thereby bypassing application allowlisting and many AV/EDR solutions. An example technique is given below.


rundll32.exe "C:\ads\file.txt:ADSDLL.DLL",DllMain

In this scenario, a malicious DLL is concealed within the ADS named ADSDLL.DLL attached to the innocuous file C:\ads\file.txt. Standard directory listings and most forensic tools will not reveal the hidden stream.


Native methods to enumerate ADS on a live system include:

  • Command Prompt: dir /r
  • PowerShell: Get-Item * -Stream * or Get-ChildItem -Recurse | Get-Item -Stream *


A high concentration of ADS is commonly observed in the Downloads folder due to widespread Mark of the Web (MotW) tagging via Zone.Identifier streams. The presence of non-standard or unusually named ADS in unexpected directories (e.g., System32, Program Files, or temporary folders) should be treated as a high-fidelity indicator of potential malicious activity.

While ADS were designed for legitimate metadata and compatibility purposes, their abuse remains a relevant and stealthy tradecraft technique that demands targeted detection and hunting in modern Windows environments.

Post a Comment

Previous Post Next Post