• No products in the cart.

# [CQURElabs] Alternate Data Streams | By Adrian Denkiewicz

[CQURElabs] Alternate Data Streams

NTFS (New Technology File System) is a default file system for Windows operating system. Long time ago it replaced FAT family and brought several new features. One of its lesser known functions is called Alternate Data Streams (ADS for short). It has been initially implemented in Windows NT to support Services for Macintosh (to store objects called Resource Forks), but modern usage of Alternate Data Streams evolved and now they are used in several other situations. The only one other file system with support for Alternate Data Streams is ReFS, which initially didn’t have support for this feature. It is important to remember – while coping file with associated alternate streams to any other file system (such as old FAT32 or EXT2) – will destroy data stored in these streams. They are not explicitly visible from WSL (Windows Subsystem for Linux) context as well.

Since alternate streams are not displayed in Windows Explorer or in default output of dir command, users are usually not aware of their existence. There are couple known malware samples that used ADS to hide their code, and couple interesting vulnerabilities related to lack of proper handling. The commands used to interact with streams may have changed over the years – some examples that you can find on-line are likely not to work anymore. In this article we will summarize what is known to work nowadays, what possible challenges support for ADS brings, and what may happen if they remain hidden.

Alternate Data Streams allow more than one data stream to be associated with a filename. What we typically refer to as filename is just part of the story. On the streams-aware file systems at least. The full filename, along with stream name, has the following format: FileName:StreamName:StreamType. The default stream (the data that is used when file is normally opened) is anonymous – it is unnamed. The default stream type is $DATA. Having said that, the full NTFS name of file abc.txt is abc.txt::$DATA.

Streams can be also associated with directories. The directory called abc can be referred to in a number of ways:

abc::$INDEX_ALLOCATION abc:$I30:$INDEX_ALLOCATION \\?\C:\path\to\abc:$I30:$INDEX_ALLOCATION The $INDEX_ALLOCATION stream type is used to distinguish between directories and regular files. Note that default stream name is $I30 but it can be omitted. It is not possible to use any other stream name, though. Internally, NTFS defines several other stream types that are not available to system users. Full list can be find in MS-FSA document and can be useful during forensics when working on raw data. Don’t confuse those with NTFS Metafiles, however. $STANDARD_INFORMATION
$ATTRIBUTE_LIST$FILE_NAME
$OBJECT_ID$SECURITY_DESCRIPTOR
$VOLUME_NAME$VOLUME_INFORMATION
$DATA$INDEX_ROOT
$INDEX_ALLOCATION$BITMAP
$REPARSE_POINT$EA_INFORMATION
$EA$LOGGED_UTILITY_STREAM

Command line support

Over the years, command line support for ADS changed. Several Windows updates added support of Alternate Data Streams to various tools. However, support of ADS has been also removed from some tools and syntax used on older systems may not work in latest Windows 10. Below you can find commands that still work in Windows 10.0.18362.

To start, let’s compare output of two commands. First, dir command, then dir -r:

The Alternate Data Streams are shown only if -r switch is used. file.txt contains two additional streams: first likely to be another text file (hidden.txt), and second – to be executable (calc.exe). Of course these names and extensions may be intentionally misleading! To display the content, more command can be used:

New streams can also be trivially added, e.g. to copy cmd.exe file into new Alternate Data Stream of file.txt, execute the following:

Since the release of PowerShell version 3.0, following cmdlets can be used to work with Alternate Data Streams:

Add-Content Clear-Content Get-Content Get-Item Remove-Item Set-Content

The detailed usage instructions for each command can be found in the manual, but typically -Stream <name> parameter needs to be added to work with ADS, e.g.:

The following code can be used to find all Alternative Data Streams recursively (not displaying default streams):

 (gci -recurse | % { gi $_.FullName -Stream * } | ? Stream -ne ':$Data') 2>$null When typical operations on files are performed, usually they are working on default stream. Interesting side effect of it is that when software to calculate checksum is used, it likely calculates the checksum of default stream. Adding alternate streams (or modifying their content) will not affect produced checksum in any way. Malicious adversaries often use this property to attach files to otherwise innocent files. To calculate checksum of new stream, software has to be explicitly instructed. On the picture above, new stream is added but reported SHA256 is not changed. This is because only default stream is accessed. Application hidden within ADS can be executed in a number of ways. It used to be as simple as calling start <path>:<stream>, but this method doesn’t work anymore. Another method is to use Windows Management Instrumentation (WMI) which is likely to stay under the radar if proper monitors aren’t implemented. The command is: wmic process call create "<path>:<stream>". Alternate Data Streams in practice Nowadays, the most popular alternate stream one can spot is called Zone.Identifier. Such alternate stream is added to every file downloaded using popular Internet browsers, such as Microsoft Edge or Google Chrome. The idea of such alternate stream has been introduced in Windows XP SP2. If Google logo is downloaded using Edge, following data is saved in Zone.Identifierstream: [ZoneTransfer] LastWriterPackageFamilyName=Microsoft.MicrosoftEdge_8wekyb3d8bbwe ZoneId=3 When performing forensics analysis of a file, it gives a clue about the browser used to download the file and the security zone. Zone number 3 indicates “Internet Zone, for Web sites on the Internet that do not belong to another zone”. This information is used by Windows to inform you that executable downloaded from the Internet is being run. If you delete or change zone identifier, Windows will not display this prompt anymore. When Google Chrome is used to download file, it saves additional useful information – the referrer URL and exact URL from which file was downloaded: [ZoneTransfer] ZoneId=3 ReferrerUrl=https://www.google.com/ HostUrl=https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png Hints like that can be extra useful and may even leak some secrets if confidential info is present in the URL. Much more detailed analysis of various browsers and clients can be found here and here. Other common use of ADS includes storing favicons of bookmarked pages. In the past ADS were used to store so called Summary Information of the document – the properties displayed by the Explorer. This functionality is not available since Windows 7. Many other system binaries offer support for ADS in unexpected forms. The support to work on alternate streams is often introduced simply by using specific file system access API, and may not be conscious developer decision. Such lesser known use cases are often used by malicious software to hide its true purpose. The same techniques are useful during penetration testing assessments as well. For instance, print.exe binary is old Windows application. It is present in the system since MS-DOS times. At some point, after NTFS system was introduced, it gained support for ADS. It can be used to print content into Alternate Data Stream which result in new Stream creation. Such strange methods of using print.exe may remain undetected, especially that application is trusted, signed Windows binary. Such applications are often referred to as LOLBAS (Leaving Off The Land Binaries and Scripts). Many other interesting examples can be found on LOLBAS Project page. Transferring files with associated alternate streams is problematic if done over network or over file system that does not support ADS. In most situations, the alternate streams and their content are simply omitted. The notable exception of that are WIM archives. Such archives can be created using 7zip software, assuming that command used to create archive includes -sns switch (store named streams). What’s also interesting, is that information about associated streams is displayed in 7zip GUI, but is somehow easy to miss. To see the list and content of associated streams, right click on the file and select “alternate streams” option. Windows Defender is still able to scan these streams but overall detection rate seems much worse than for standalone Mimikatz. Detection results from virustotal.com Offensive usage of Alternate Data Streams As mentioned previously, malicious code is known to use ADS as well. In the past, this was a good method to hide from Anti-Virus software. For instance, rootkit Backdoor.Rustock.A hides additional stages in alternate streams on %Windir%\System32 directory, naming them using random sequences of characters. Today, Windows Defender and almost every other AV software check ADS for malicious content. Mimikatz detected in alternate stream. Incorrect interpretation of alternate streams is another story worth to tell. Unprivileged users typically cannot create files in C:\Windows directory. Some applications may assume that anything stored in that directory is created by system or otherwise privileged user. Of course, regular users can still create files inside some subdirectories – e.g. C:\Windows\Tracing. If ADS is created on that directory, then incorrect path normalization functions may assume that ADS is really located insideC:\Windows as there is no \ character after Tracing. Can ADS related issues exist in Web Applications world as well? Unfortunately, yes. Vulnerability in Microsoft IIS/6.0 allowed to access password-protected files by referring to directories using ::$INDEX_ALLOCATION syntax. For instance, by sending GET /admin::$INDEX_ALLOCATION/index.php HTTP/1.1 request, attacker was able to access admin panel without providing necessary basic-auth password. IIS wasn’t able to recognize alternate syntax to access default directory stream. Later, the issue has been partially fixed, but it was rediscovered using alternate syntax (admin:$I30:INDEX_ALLOCATION). Final patch included both types of syntax.

Sometimes, when web server is misconfigured, referring to file using default anonymous stream may result in file being interpreted as plain-text, revealing source code of application or other confidential data. This is especially common when custom methods to handle requested paths are developed.

File upload functionality may also be exploited. Creating file with unexpected ::$INDEX_ALLOCATIONAlternate Data Stream suffix may actually result in directory creation which wasn’t expected to happen. Filenames are typically restricted and cannot contain many special characters – e.g. < or >. Such filenames are forbidden. This restriction does not concern Alternate Data Streams, though. Stream name may contain spaces, HTML tags and various Unicode characters. If stream-aware application does not properly sanitize such names, they could be used to perform Cross-Site-Scripting or similar injection attacks. It is interesting idea, although requires very specific applications. Perhaps software with fronted written in Electron may one day implement this issue? Any software that operates on stream names should be checked for this attack vector. Unexpected Alternate Data Streams Attention! The following exercises may create files that cannot be removed or even break your file system! It is not recommended to replicate exercises on file system with important files. Use virtual machine or sandbox. So far, so clear. We have seen some examples of working with alternate streams, including creating them on directories. The interesting thing happens when ADS is associated with root directory (e.g. C:\). In this case, the alternate stream is not visible when content of root directory is checked. Instead, it is only visible in subdirectories! That’s one way of hiding it. Figure 13. Hiding alternate stream in root directory. When malicious file is copied to such ADS, it is still detected by Windows Defender, although no actual path is displayed: Another quirk is to use ... directory. That’s not one, not two, but three dots! It doesn’t have any special meaning other that it simply cannot be created. Or does it? If you use alternate syntax of ::$INDEX_ALLOCATION – it does work. Another way to do that, is to use "...\..."syntax.

Creation of … directory

This directory name (and any other with more dots) is sort of special. You cannot open it using explorer.exe, nor you cannot list its content. If you try to delete the directory, explorer will crash. You can see its content using dir /r command, along with all alternate streams inside, but you cannot see the alternate streams created on the directory! (Yes, Windows Defender still can.)

If you think of storing your secret documents over there, remember that raw disk analysis will still uncover names of these secret streams.

There are many more quirks related to unexpected ADS behavior. Symlinks created to... don’t behave as expected, various file operations conducted on this directory tends to loop forever, etc. I invite you to try on your own what else can be done.

Alternate Data Streams API

Besides built-in operating system support, one popular application to display ADS is included in Sysinternals Suite. Program is called Streams and can be downloaded for free, although application is not open source. It can list all associated streams and performs operations on them.

It is easy to develop similar functionality from the scratch. To do so, we can use two APIs offered by Windows system. First method is based on FindFirstStreamW/FindNextStreamWAPI – it iterates over all ADS associated with given filename. However, it cannot find alternate streams associated with directories! This is important limitation and should be taken into consideration when testing security of various restrictions. The second API is based on BackupRead/BackupSeekfunctions – this API allows you to make NTFS specific backup of the file. The backup information includes all associated streams, hence they can be extracted right from the memory.

Full source code of PoC application can be found below. The code should compile in Visual Studio 2017 or with any other modern C++ compiler. Please remember that it is not production-ready and shouldn’t be used as-is, as it lacks necessary checks.

view rawads.cpp hosted with love by GitHub

The different results reported by both methods can be observed on the images below:

Summary

Alternate Data Streams feature is not hidden from regular users, but it also has various very exotic corner cases which are not properly addressed by Microsoft. Some of discussed issues are explicitly marked as WONTFIX. Although modern AV is likely to scan any malicious content hidden inside alternate streams, partial information can still be successfully stored there and be hidden from sysops, thus ADS will remain important in workflow of any penetration tester, red teamer and probably malicious actors as well.

References: