NTFS file streams, also known as alternate data streams (ADS), are part of every file, as well as directories (folders), in a Windows NTFS volume. NTFS files and folders are comprised of attributes one of which is $Data. The content we normally associate with a file such as the text in a .txt file or the executable code in a .exe file is stored in the ‘default’ $Data attribute or ‘stream’. The name string of this default attribute is empty (set to “”) thus it is often referred to as the “unnamed data stream”. Any additional $Data steams must be named and are typically referred to as “alternate data streams”.
An application can use the Windows API’s to create additional named data streams. This is done by appending “:” followed by the stream name to the file name or path. Since “:” is a reserved character not allowed in a filename this does not conflict with file names not making use of additional streams or references to files on volumes using FAT32 which does not support streams.
Each stream has its own allocation size (disk space reserved for it), its own actual size (bytes in use), and its own file locks. Thus streams can be thought of as files within files from a user perspective.
The History of NTFS File Streams
Older Windows file systems such as FAT16 and FAT32 have no support for multiple streams. Multiple stream support was added to NTFS as part of NT 3.5.1. This was done in large part to enable the ability of a Windows server to be a file server for Apple Macintosh computers. Macintosh files make use of two streams per file – one for data and one for resource information. By enabling NTFS to support multiple streams a Macintosh user could copy files to a Windows server and then back to a Macintosh without losing the ‘resource’ stream.
Initially, NTFS streams support was limited to the Win32 API’s used to access files. For years only a couple utilities had any ‘awareness’ of multiple streams. These were “echo” and “more”.
This made leveraging ADS by bad actors very tempting as it was hard for end users and even security professionals to detect the use of ADS given that the common ‘dir’ command and File Explorer were blind to ADS usage.
That situation has improved over time but the use of ADS is still often overlooked.
Not all ADS content is ‘bad’ these days. Some archive and backup software make use of ADS to store file revision information. A more common usage in the past few years is IE and other browsers that now add a stream named “Zone.identifier” to files downloaded from the internet or other security zones. The Zone.identifier stream will include data like “[ZoneTransfer]\nZoneId=x” where x is 0-4:
- 0 My Computer
- 1 Local Intranet Zone
- 2 Trusted sites Zone
- 3 Internet Zone
- 4 Restricted Sites Zone
Tools to Work with NTFS Streams
Over time a few ‘native’ tools have emerged to provide more visibility into ADS usage. These include:
- ‘Echo’ and ‘More’
- Sysinternals ‘Streams’ utility
- Windows Server post Server 2003 added the /R option to the Dir command.
- PowerShell 3.0 was updated with six cmdlets to directly manipulate content for ADS
Echo / More
For a time ‘echo’ and ‘more’ were the primary utilities out of the box with any ADS awareness beyond the native Win32 API’s available only to programmers. In the above example ‘echo’ is used to create a new stream named “secret” on existing file ‘test.txt’ by appending “:secret” to the file name. The specified text is added by echo to the new stream. ‘More’ is used to read the new stream content. Note the directory listing only includes the size of the string “My default stream\n” and not any content from the stream named ‘secret’.
Streams.exe is a command line tool available from sysinternals. It is used to show what files in a folder make use of streams beyond the default data stream. Note in the above example it shows that file test.txt has an alternate $Data stream named “secret” and the stream has 83 bytes of data – far more than the 19 bytes shown by “Dir” in the first example
Sometime after Server 2003 the ‘Dir’ command finally became ‘streams’ aware with the addition of the /R option. As shown above, our file ‘test.txt’ is shown twice when using the Dir /R option; Once for the default stream with its size of 19 bytes and again for the stream named ‘secret’ having 83 bytes of data.
Also note above the use of “more < streams.exe:Zone.Identifier”. We downloaded the file ‘streams.exe’ from the internet using IE. IE created the “Zone.Identifier” stream with the text shown indicating the file was transferred from zone 3 – the internet zone. This is one of a few ADS streams that File Explorer does know about. This stream results in the ‘unblock’ button that shows in the Explorer ‘general” tab when one right clicks on the file and picks ‘properties’. When you press the ‘unblock’ button Explorer deletes the ‘Zone.Identifier’ stream from the file.
PowerShell 3.0 was updated with six new built-in cmdlets for managing ADS content.
Executing Code from ADS
In the Windows XP day’s one could simply run an .exe from ADS using ‘Start’ but Microsoft plugged that security hole. However, it is still rather easy to get code to run from ADS per the above example.
We took the ‘ADExplorer.exe’ application (Sysinternals) and used the ‘type’ utility to stick it in the ad.exe named ADS of file zzz.txt . We then used WMI via the command “wmic process call create “c:\ads\zzz.txt:ad.exe”” in order to get Windows to run the program as shown by the entry in TaskManager with same PID (12908) as shown from the command line used to launch it. DLL’s are even easier – just use rundll32.exe from the command line with the ADS name of your DLL – Windows will not object.
Why Should Security Professionals care?
As we have shown, Windows File Explorer and most other tools report only information about a file’s default (unnamed) data stream. The file size is shown by Explorer and, by default, the dir command only includes the space used by the unnamed data stream. Thus a simple .txt file or word doc having, say 1k of data would be shown as that 1k in size BUT there could be megabytes of data or executable code ‘hidden’ in one or more named (alternate) data streams!
As shown in the tool examples above it is simple to place any type of content in an ADS; after all, they work no different than the default stream other than having an explicit name. Such content ‘hidden’ from plain view could be anything – like your HR database file or maybe the latest ransomware program.
For the reasons summarized above ADS has obtained a reputation for being dangerous because bad actors can and have made use of ADS to hide content ranging from sensitive data to malicious code. Therefore it is very important to ensure security-oriented tools such as AV products, sensitive data discovery tools, or data exfiltration detectors are all able to detect the existence of ADS content and scan that content – just like it would be done for the default data stream. As a closing reminder – not all ADS content is bad. There are legitimate uses such as “Zone.identifier” or archive/backup metadata so one cannot simply delete all non-default / named streams as this will break some applications.
Anthony Sarra is the VP of Research & Development focused on building and delivering real-time activity solutions for Stealthbits technologies including the StealthINTERCEPT and Activity Monitor products. He joined Stealthbits in 2010 as part of the acquisition of NetVision Software.
Anthony has 40 years of experience in software development and management roles creating enterprise software solutions ranging from factory automation to desktop management and server security. Prior to NetVision and Stealthbits Anthony held software developer and leadership roles at Intel Corp. and Intel spin out LANDesk Software.