Alternate Data Streams ? Adversary Defense Evasion and Detection [Guest Diary]

Published: 2025-05-28. Last Updated: 2025-05-29 00:02:44 UTC
by Guy Bruneau (Version: 1)
0 comment(s)

[This is a Guest Diary by Ehsaan Mavani, an ISC intern as part of the SANS.edu BACS program]

Introduction

Adversaries are leveraging alternate data streams to hide malicious data with the intent of evading detection. Numerous different malicious software has been designed to read and write to alternate data streams [1]. To better assist in detecting and responding to cyber threats, it is important that we understand what an alternate data stream is, ways to discretely write to an alternate data stream, and tools that can assist in detecting alternate data streams.

Alternate Data Stream

Every file on a Windows NTFS file system has a default unnamed data stream. This is the mainstream which stores the files data and can be easily viewed with File Explorer. Alternate Data Streams are a Microsoft Windows New Technology File System (NTFS) feature which was added to help support Apple’s Hierarchical File System (HFS) [2]. An Alternate Data Stream is different from the default unnamed mainstream. Alternate Data Streams are named and are not visible within File Explorer [3]. This gives us the capability to write data to a known good files alternate data stream. Essentially, we are able to hide malicious or secret files inside of an innocuous file which can’t be seen in File Explorer.

Directories can also have alternate data streams. Unlike files, directories do not have a default data stream. Instead, they have a default directory stream [3].

Why does this matter?

Adversaries want to complete their objectives and need to do so in a manner which evades detection. If our defensive tools and processes don’t scrutinize alternate data streams, adversaries are going to take advantage of our defensive blind spots. Sophisticated threat actors have been using alternate data streams to write and read data. Mitre ATT&CK has documented several skilled groups and malicious software that use this technique, categorized by Mitre as T1564.004 [1].

As a case study, the group known as Indrik Spider [4] has been operating the malicious software BitPaymer [4] to launch targeted ransomware campaigns. In 2017, BitPaymer was first identified being used to ransom the U.K.’s National Health Service, demanding 53 bitcoins. Once a computer has been compromised, the BitPaymer malware attempts to run from an alternate data stream. If it is not being run from an alternate data stream, it automatically creates a file and copies itself to the arbitrarily named alternate data stream ‘bin’. The BitPaymer ransomware has netted Indrik Spider $1.5M USD in the first 15 months of operations [4].

Writing & Reading an Alternate Data Stream

I created an empty directory and ran the commands below. When I wrote data to a nonexistent files alternate data stream, Windows automatically created the files default mainstream with no data. Windows also created an alternate data stream with the name ‘secret’, which I specified. Alternate data streams can be named using all Unicode characters except for backslash, forward slash, colon, and control character 0x00. A stream name can be no more than 255 characters in length [5].
1. Write data to a text file’s alternate data stream which I named ‘secret’
2. List directory contents. Windows created file.txt’s default data stream with 0 bytes of data. The alternate data stream ‘secret’ is not visible. Viewing the directory contents in File Explorer will also only show file.txt with 0 bytes of data.
3. Using dir /r to display alternate data streams of files. file.txt:secret will not be shown in File Explorer
4. Displays contents of the text file’s main data stream. Nothing is outputted onto the screen because there is no data in file.txt’s main data stream. Opening the file in Notepad.exe will also show an empty file.
5. Explicitly specify the filename and the stream name to read data


Figure 1 Writing, reading, and displaying a file alternate data stream

Executing Alternate Data Streams

Alternate data streams can be directly executed by many Windows tools [6]. Powershell, rundll32, wmic, wscript, and cscript are some of the tools that are capable of executing binaries in alternate data streams. These are all legitimate tools that are pre-installed on Windows operating systems.

I created an executable that enumerates all files on a victim machine, sending the results to an attacker-controlled web server via URL encoded GET requests. I hid the executable inside of an alternate data stream. The executable was successfully run with wmic.


Figure 2 Executing enumerateFiles.exe in GoodFile’s alternate data stream

Alternate Data Streams in Reserved Names

There are special reserved names in Microsoft Windows that cannot be used for file names [7]. CON is one of those unique reserved file names. If you try to create a file with the name CON using File Explorer, Windows will display an error, preventing the creation of the file.


Figure 3 Windows error when creating a file with a reserved name in File Explorer

Interestingly, it is possible to circumvent this error and successfully create a file with a reserved name by utilizing special prefixes [8]. “\\?\” is a prefix that can be used to tell the Windows API to disable string parsing, sending the string that follows the prefix straight to the file system [7].

Even more insidious, alternate data streams written to files with reserved names are not visible to directory listings with dir /r unless the prefix “\\?\” is added to the file path. In order to read, write, and delete the file, the prefix “\\?\” must be added to the file path.
1. Write data to the alternate data stream of a file with the reserved name CON. To create this file, the prefix “\\?\” must be included

2. List directory contents with dir /r. The file CON is visible, but the alternate data stream is not visible. If navigating to “C:\Temp\” within File Explorer, this file and the file’s alternate data stream will not be visible.

3. List directory contents with dir /r and the absolute file path of CON with “\\?\” prepended. The alternate data stream is visible. If navigating to “\\?\C:\Temp\” within File Explorer, this file will be visible, but the alternate data stream will not be visible.


Figure 4 Writing data to the alternate data stream of a reserved name

Detecting Alternate Data Streams in Files

Alternate data streams are part of the Windows NTFS file system and cannot be disabled. Understanding how adversaries create and interact with alternate data streams can help us detect and respond to suspicious streams [6]. Due to their naming convention, it is possible to create a detective control that monitors for reading, writing, or executing file names that contain a colon. Mitre has published Splunk queries that identify the execution of alternate data streams with common Windows tools [9]. To gain visibility into the different streams that exist, tools such as dir /r and Streams.exe [10], part of the Microsoft Sysinternals suite, can be used. It’s important to note that both tools mentioned can only view the streams of files with reserved names if the prefix “\\?\” is added before the absolute file path. On a Windows 64-bit operating system, Streams.exe was not able to find streams in the %systemroot%\System32 directory. Streams64.exe was successful in finding streams in the System32 directory.

As a starting point, I created a daily scheduled task to identify alternate data streams for all files in the %systemroot%\System32 directory recursively with Streams64.exe. The output is saved to a text file with the timestamp as the filename. This gives us the capability to track and analyze the addition of new streams over time.

The scheduled task starts cmd.exe with the argument /c C:\path\to\streams64.exe -s -nobanner %systemroot%\System32\ > C:\path\to\output\ADS_%date:~10,4%_%date:~4,2%_%date:~7,2%.txt


Figure 5 Using FC to compare the files automatically created with Streams64.exe and task scheduler

Unless we monitor for alternate data streams, they remain an invisible safe haven for threat actors to write and potentially execute malicious binaries. Manually finding streams within our Windows NTFS file systems is unscalable. Command line tool can be used with task scheduler to periodically enumerate streams. Automating this process helps us gain visibility into streams that may be hiding on our systems.

[1] https://attack.mitre.org/techniques/T1564/004/
[2] https://www.irongeek.com/i.php?page=security/altds
[3] https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/c54dec26-1551-4d3a-a0ea-4fa40f848eb3
[4] https://www.crowdstrike.com/en-us/blog/big-game-hunting-the-evolution-of-indrik-spider-from-dridex-wire-fraud-to-bitpaymer-targeted-ransomware/
[5] https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/5953f072-b28c-4fbf-ae50-09b0173317b9
[6] https://gist.github.com/api0cradle/cdd2d0d0ec9abb686f0e89306e277b8f
[7] https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file
[8] http://www.sourceconference.com/publications/bos10pubs/Windows%20File%20Pseudonyms.pptx
[9] https://car.mitre.org/analytics/CAR-2020-08-001/
[10] https://learn.microsoft.com/en-us/sysinternals/downloads/streams
[11] https://www.sans.edu/cyber-security-programs/bachelors-degree/

-----------
Guy Bruneau IPSS Inc.
My GitHub Page
Twitter: GuyBruneau
gbruneau at isc dot sans dot edu

0 comment(s)

[Guest Diary] Exploring a Use Case of Artificial Intelligence Assistance with Understanding an Attack

Published: 2025-05-28. Last Updated: 2025-05-28 13:48:55 UTC
by Jennifer Wilson, SANS.edu BACS Student (Version: 1)
1 comment(s)

[This is a Guest Diary by Jennifer Wilson, an ISC intern as part of the SANS.edu Bachelor's Degree in Applied Cybersecurity (BACS) program [1].]

As part of my BACS internship with SANS, I setup and maintained a DShield honeypot instance using a physical Raspberry Pi device.  As I was putting together each of my attack observations that were due, I started to wonder how helpful AI would be. One of the things I wanted to do when I started the internship was to step outside of my comfort zone. While I have read a lot about AI, I have only used it a handful of times. So, I wondered if it would lead me astray? Would it provide valid actionable data?

In this blog post, I will explore how accurate and helpful ChatGPT is with identifying one of the more unique attacks I say over the past few months.

To set the stage, I first noticed this attack after running the cowrieprocessor script [2] on my honeypot. The attack occurred on 2025-04-20 and came from IP address 63[.]212[.]157[.]187. The total attack occurred over a duration of 62.83 seconds. According to AbuseIPDB [3], the IP has been reported 300 times, and it has been marked with a 100% confidence of abuse. This IP has been busy in the world. Along with this basic data, the following commands were captured being ran on the honeypot:

# ifconfig
# uname -a
# cat /proc/cpuinfo
# ps | grep '[Mm]iner'
# ps -ef | grep '[Mm]iner'
# ls -la ~/.local/share/TelegramDesktop/tdata /home/*/.local/share/TelegramDesktop/tdata /dev/ttyGSM* /dev/ttyUSB-mod* /var/spool/sms/* /var/log/smsd.log /etc/smsd.conf* /usr/bin/qmuxd /var/qmux_connect_socket /etc/config/simman /dev/modem* /var/config/sms/*
# locate D877F783D5D3EF8Cs
# echo Hi | cat -n 

 

Let’s first break down the first 5 commands:

Command Use
ipconfig Displays network configuration in Unix-Like environments.
uname -a Displays system information.
cat /proc/cpuinfo Displays CPU information.
ps | grep ‘[Mm]iner’ Searches running processes for the string ‘Miner’ or ‘miner’.
ps -ef | grep ‘[Mm]iner’ Searches running processes for the string ‘Miner’ or ‘miner’ and provides detailed information for the matching data.

Figure 1: Break down of commands the attacker ran and its function

Ok, those are common commands that an attacker will often run to attempt to discover more information about a system on which they have landed on. Searching specifically for ‘[Mm]iner’ is interesting. The attacker is trying to discover if the system is currently being used as a crypto miner.

The next two commands caught my attention. The following command is searching to determine if the mentioned paths exist on the file system, including if they are hidden:
 

?ls -la ~/.local/share/TelegramDesktop/tdata /home/*/.local/share/TelegramDesktop/tdata /dev/ttyGSM* /dev/ttyUSB-mod* /var/spool/sms/* /var/log/smsd.log /etc/smsd.conf* /usr/bin/qmuxd /var/qmux_connect_socket /etc/config/simman /dev/modem* /var/config/sms/*?

 

The ‘locate D877F783D5D3EF8Cs’ command is attempting to locate ‘D877F783D5D3EF8Cs’ on the file system. But what is ‘D877F783D5D3EF8Cs’? This is not a string I have seen before. Normally I would run to Google and start searching around to see if I could determine what it is. I got to wonder though, could ChatGPT or another platform provide me with results as well. More importantly would it provide me with accurate results?

I started out simple, as can be seen in the below screenshot from my ChatGPT conversation [4], to see what feedback it would provide.


Figure 2: ChatGPT’s response to ‘What is D877F783D5D3EF8Cs’.

 

Given the response that ChatGPT had, I clearly need to be more specific in my request.


Figure 3: ChatGPT’s response to telling it that ‘D877F783D5D3EF8Cs’ was found on a honeypot.

 

ChatGPT still seems to be guessing a bit. I want to see if I can get it to give me a more specific answer. Let’s see what happens when I provide it with the full command that was detected on the honeypot. Here is a snippet of what ChatGPT provided back:


Figure 4: ChatGPT’s response to providing the full command that was detected on the honeypot.

 

This has gotten me closer to a definite answer. I got curious about what would happen if I gave it the context of the command that was run before it. A snippet of its response is found below:


Figure 5: ChatGPT’s response to providing it the previous ls -la command.

 

The responses are now getting more detailed. ChatGPT suggests that the attack I am reviewing is part of a credential harvesting or SMS hijacking campaign [4]. Let’s see if it knows of any connection between the ‘D877F783D5D3EF8Cs’ and Telegram:


Figure 6: ChatGPT’s response when asking about a connection between the string ‘D877F783D5D3EF8Cs’ and Telegram.

 

While I only asked ChatGPT [3] about the context of ‘D877F783D5D3EF8Cs’ in relation to Telegram, it narrowed it down to Telegram Desktop and specifically the folder tdata. Looking back at the ls -la command, one of the folders the attacker was trying to list was ~/.local/share/TelegramDesktop/tdata. Without knowing exactly what the attacker was attempting to do, in the context of the rest of the commands the attacker ran, this seems like a logical response.

Now that I have gotten a logical response from ChatGPT, I always verify that response. A quick Google search led me to several sources that confirmed what ChatGPT was providing me with as a response [5][6][7].

While it took a bit of time probing ChatGPT to get an answer, the more context I gave it the better the result I got back. This would work well for an attack where I understood part of what was happening, but needed clarification on one section, like this attack.

Let’s see what would happen if I drop the ‘s’ off the string ‘D877F783D5D3EF8Cs’ and ask about just ‘D877F783D5D3EF8C’ in relation to Telegram. ChatGPT has been dropping it off in most of its responses to me so maybe it is just a typo.


Figure 7: ChatGPT’s response when asking about a connection between the string ‘D877F783D5D3EF8C’ and Telegram.

 

Now ChatGPT seems very confident in the response it provided [4]. I then did a Google search dropping the ‘s’ off again, I got several of the same references as I did before. One difference being a Medium blog by XIT called “Lesson 10: Stealing Accounts Sessions with Malware” [8]. This could be what the attacker’s goal is. It lines up with what we learned from ChatGPT so far.

When I was testing to see if this attack would make a good example however, I got different responses. ChatGPT believed that the string ‘D877F783D5D3EF8Cs’ was part of an API call used by Telegram.

When I went to verify it with Google, I was not able to find any other resources confirming it. I asked ChatGPT to provide me with a source for their information, ChatGPT became evasive. When I specifically asked for sources that mention ‘D877F783D5D3EF8Cs’, it first provided me with a link to a paper titled Automated Symbolic Verification of Telegram’s MTProto 2.0 [9]. A quick search of the document proves that the string was not mentioned. ChatGPT then stated it could provide me with the code that mentions it, but even this I had to ask for twice as can be seen in the saved chat snippet below:


Figure 8: Screen shot of saved ChatGPT chat of a code snippet it provided.

 

Could this be what the attackers were looking for when performing the ‘locate D877F783D5D3EF8Cs’ command? Not likely. In the full context of the attack, it does not fit in. It was also hard to verify, with me relying on either ChatGPT’s reassurance that it is correct, or decompiling source code to find the answer. If I need to decompile the source code to find the answer, the attacker will need to as well, and the attacker’s actions prove that was not done. While it does appear that Telegram’s source code uses this key, according to ChatGPT, for a few different uses getting the context that it is in fact also the name of a critical file for Telegram is critically important. Without that key context a lot of time could be spent down a rabbit hole.  
There are several things that I learned from this exercise:

  • ChatGPT was useful in providing details of an attack that I was unsure of.
  • Providing as much context as I can, will help in providing useful answers.
  • If ChatGPT starts acting evasive in its answer, it’s highly likely that it is not providing good data.
  • It is important as an analyst while I may not understand the details of a particular string, to understand what the goal of the commands are, so I can recognize when ChatGPT is leading me astray.

 

[1] https://www.sans.edu/cyber-security-programs/bachelors-degree/
[2] https://github.com/jslagrew/cowrieprocessor
[3] https://www.abuseipdb.com/check/69.212.157.187
[4] https://chatgpt.com/c/682137f1-0f80-800c-92f5-58a4a9f50aef
[5] https://pkg.go.dev/github.com/atilaromero/telegram-desktop-decrypt@v0.0.0-20210418042638-a2c3042b3bfa/tdata/encrypted
[6] https://fossies.org/linux/john/run/telegram2john.py
[7] https://github.com/atilaromero/telegram-desktop-decrypt/blob/master/README.md
[8] https://x-it.medium.com/lesson-10-stealing-accounts-sessions-with-malware-f25217c3b057
[9] https://arxiv.org/pdf/2012.03141

 

 

--
Jesse La Grew
Handler

1 comment(s)
ISC Stormcast For Wednesday, May 28th, 2025 https://isc.sans.edu/podcastdetail/9468

Comments


Diary Archives