In this blog we will explore several ways that Alternate Data Streams (ADS) are abused by attackers to hide files and evade detection, defences based on them (and ways to bypass those defences!) but also how they can be used to help malware evade dynamic analysis.

What are Alternate Data Streams?

Files in the NTFS file system consist of multiple streams or attributes. Metadata such as the file name, timestamps as well as the associated security descriptors are all saved in separate streams. The contents of the file itself are also saved as a stream known as the default $DATA stream. However, a file can have multiple $DATA streams! This means that additional content can be embedded in separate streams of the same file. We refer to those additional $DATA streams as Alternate Data Streams or ADS.

Hiding files with ADS

Alternate Data Streams can be added to regular files and are not visible when browsing the file system via the graphical user interface. In addition, such streams are not listed when listing the contents of a directory with dir or dir /A. In the example below, a data stream called malicious.txt is added to the file text.txt.

C:\Users\ThreatSpike\ADS>echo "Malicious Content" > text.txt:malicious.txt

C:\Users\ThreatSpike\ADS>dir /A

 Directory of C:\Users\ThreatSpike\ADS

23/12/2020  13:49    <DIR>          .
23/12/2020  13:49    <DIR>          ..
23/12/2020  13:54                27 text.txt
               1 File(s)             27 bytes
               2 Dir(s)  29,827,604,480 bytes free

There is a special flag for the directory listing command dir in Windows that enables alternate data stream listing.

/R          Display alternate data streams of the file.
C:\Users\ThreatSpike\ADS>dir /R

 Directory of C:\Users\ThreatSpike\ADS

23/12/2020  13:49    <DIR>          .
23/12/2020  13:49    <DIR>          ..
23/12/2020  13:54                27 text.txt
                                 22 text.txt:malicious.txt:$DATA
               1 File(s)             27 bytes
               2 Dir(s)  29,827,604,480 bytes free

There are also other utilities that can help identify and examine data streams such as the streams utility. Powershell has several commands that can identify and create streams as well.

Data streams can also be added to directories. In that way files can be hidden on the directory itself.

C:\Users\ThreatSpike\ADS>echo "Malicious Content" > dir:malicious.txt

C:\Users\ThreatSpike\ADS>dir /A

 Directory of C:\Users\ThreatSpike\ADS

23/12/2020  13:58    <DIR>          .
23/12/2020  13:58    <DIR>          ..
23/12/2020  13:59    <DIR>          dir
               0 File(s)              0 bytes
               3 Dir(s)  29,828,136,960 bytes free

C:\Users\ThreatSpike\ADS>dir /A /R

 Directory of C:\Users\ThreatSpike\ADS

23/12/2020  13:58    <DIR>          .
23/12/2020  13:58    <DIR>          ..
23/12/2020  13:59    <DIR>          dir
                                 22 dir:malicious.txt:$DATA
               0 File(s)              0 bytes
               3 Dir(s)  29,828,136,960 bytes free

The newly added stream cannot be seen.

There are also some edge cases that can help malicious actors hide their files even further. Files with names ending in . . are not properly parsed by several stream-aware utilities if they are not fully referenced with their full path.

C:\Users\ThreatSpike\ADS>echo malicious > "file. .:malicious.txt"

C:\Users\ThreatSpike\ADS>dir /R /A

 Directory of C:\Users\ThreatSpike\ADS

08/01/2021  17:03    <DIR>          .
08/01/2021  17:03    <DIR>          ..
08/01/2021  17:03                 0 file. .
               1 File(s)              0 bytes
               2 Dir(s)  29,895,577,600 bytes free

C:\Users\ThreatSpike\ADS>..\streams.exe -s

streams v1.60 - Reveal NTFS alternate streams.
Copyright (C) 2005-2016 Mark Russinovich
Sysinternals - www.sysinternals.com

Error opening C:\Users\ThreatSpike\ADS\file. .:
The system cannot find the file specified.

No files with streams found.

C:\Users\ThreatSpike\ADS>more < "file. .:malicious.txt"
malicious

Using more to examine the data stream reveals its contents even though dir /R and streams fail to identify it. However, if we specify the full path with the "\\?\" prefix the file is visible and we can operate on it.

C:\Users\ThreatSpike\ADS>dir /R "\\?\C:\Users\ThreatSpike\ADS\file. ."

 Directory of \\?\C:\Users\ThreatSpike\ADS

08/01/2021  17:09                 0 file. .
                                 12 file. .:malicious.txt:$DATA
               1 File(s)              0 bytes
               0 Dir(s)  29,895,057,408 bytes free

Executing files straight from data streams

It is also worth mentioning that executables residing in an alternate data stream cannot be started in the normal way. You cannot double click on them or call them by name on the command prompt. However, there are multiple indirect ways of starting a process straight from the hidden executable. Both of the below commands can be used to start a process from a data stream called calc.exe that is embedded in a normal text.txt file.

wmic process call create "C:\Users\ThreatSpike\text.txt:calc.exe"

forfiles /p c:\windows\system32 /m notepad.exe /c "C:\Users\ThreatSpike\text.txt:calc.exe"

A more exhaustive list of ways to run different types of executable files straight from an alternate data stream can be found here but the main idea is that there are options for almost all executable file types.

Detecting malware in hidden data streams

Being able to hide files in ADS, combined with the ability to initiate processes from them, makes them a very convenient hiding spot for malware and MITRE has a page dedicated to this hiding technique. Proof of concept code that uses alternate data streams to persist on a compromised host has also been published.

Windows Defender and most major Antivirus solutions are well aware of this hiding method as well. Windows Defender is particularly good at detecting malware in alternate data streams and it surgically removes only the stream that contains the malicious content without deleting the main file. However not all security vendors appear to be aware of the presence of ADS. We tested AV solutions by uploading a variety of samples to VirusTotal. By uploading a file through the browser, only the default data stream is preserved so in order to test the behavior of Antivirus products the file must be first compressed in a “container” that supports alternate data streams. In this test we used WINRar as it offers the option to save file streams when compressing the file.

First, in order to establish a baseline detection rate, a plain Meterpreter executable payload was uploaded. This generated 43/69 detections.

Then, the same payload was compressed in an RAR archive. This generated 34/60 detections.

Finally the same original Meterpreter payload was embedded in an ADS of a legitimate txt file and was then compressed into a RAR archive. This dropped the detection rate even further to 20/60 detections.

Judging from these results, there are indications that some Antivirus Vendors (including some major ones) do not scan the contents of alternate data streams. The below screenshot shows AV products that failed to identify the Meterpreter executable hidden in an ADS at the time that this research took place according to VirusTotal. At this point it should be also noted that results on VirusTotal sometimes differ from the actual detection performance of AV engines in real deployments.

*All previously mentioned detection rates refer to the results observed when this research took place and may differ in the future.

ADS based defences and malware bypasses

Alternate Data Streams are not only useful for malicious purposes. They are also used to protect users from externally acquired executables as part of a defence system integrated in Windows.

Windows Smart Screen protection for executables from external sources

Whenever a new file is downloaded, a new data stream with the name Zone.Identifier is added to the file by the program that performed the download. For example, if you download a file with Chrome, then the browser itself is responsible for this addition. The Zone.Identifier stream is then used by Windows to evaluate the origins of a file and introduce protection if needed. It specifies a Security Zone that can be used to warn and protect the user from executables downloaded from outside sources. It is also very important to propagate the Zone.Identifier field to files derived from the original one. For example, extracting a zip file that originated from an outside source should propagate the Zone.Identifier to its contents. This is indeed handled correctly for most file types but there are some exceptions. .

The Zone.Identifier data stream does not propagate to the contents when opening ISO or VHD files in Windows. The dangers of not propagating the Zone.Identifier ADS are known to the community. Malware using Virtual Hard Drive(VHD) Images and ISO files to achieve code execution bypassing the Windows SmartScreen protection have already been spotted in the wild. Both of those types of files are natively supported in Windows 10 and can be opened by a user with just a double click and as a consequence, this behavior opens up a new attack surface for phishing attacks.

In addition to that, antivirus engines do not seem to scan the contents of these types of files in some cases. For example, a VHD file that contains malware (and more specifically a meterpreter payload) can be safely saved on disk of a fully updated Windows 10 system with Microsoft Defender active. Uploading a virtual hard drive file that contains a blatantly malicious meterpreter payload to VirusTotal generates only 1/60 detection rate. A significantly different behavior was observed with an ISO file containing the same payload with 27/60 detections.

Another point that is also worth mentioning is that Alternate Data Streams are a feature of NTFS and because of that such streams are not preserved when copying files to other file systems. This means that files downloaded directly or moved to other file systems that do not support ADS, such as a Fat32 formatted external USB drive, will not enjoy the same protection from Windows.

Checking ADS to evade analysis.

While some malware strains delete the Zone.Identifier stream from their executable files themselves, in an attempt to delete forensic evidence indicating the origins of those files, others check for this stream as a means to evade behavioral analysis. The absence of the Zone.Identifier alternate data stream can be used as an indication that the file has been transferred to a new environment and it was not directly downloaded from the internet. A program can check the presence of this ADS in the executable that it was launched from and detect its origin. This method can be used by malware to implement a dynamic analysis evasion technique that forces the executable to terminate itself if no Zone.Identifier field is present. The pafishmacro project is inspired by “malicious documents found in the public” and presents an example of this technique in a VBA script that could potentially be part of a malware dropper.

Defence Takeaway Points

Alternate Data Streams are and will be a convenient hiding spot for malware as many people are not aware of their presence. However, on the defensive side there are some behaviors that can be used to alert us on potential malware activity. For example, executable code residing in Alternate Data Streams could be a sign of malicious software attempting to hide. A process deleting or accessing the Zone.Identifier attached to its own executable could indicate attempts to remove forensic data or evade dynamic analysis respectively. Finally, as far as code execution from ISO and Virtual HD Images is concerned, simple actions like disabling Windows Explorer file associations for those file types on all endpoints can help mitigate the risk as suggested here.