Loading Alternate Data Stream (ADS) DLL/CPL Binaries to Bypass AppLocker

(Image Source: blogs.technet.microsoft.com)


A few weeks ago, I wrote about Executing Commands and Bypassing AppLocker with PowerShell Diagnostic Scripts.  Overall, it was a viable technique that allowed for the loading of .NET/C# assemblies.  However, PowerShell Constraint Language Mode proved to be a viable mechanism for defeating this technique if strictly enforced by UMCI/system policies (and of course, without the availability of an attacker reverting to PowerShell v2).  Regardless, I was eager to hunt for other bypass opportunities.

Last week, I read a great blog post by @Oddvarmoe that described the use of Alternate Data Streams (ADS) to bypass AppLocker Default Policies.  Aside from the fact that this was excellent work, a few very interesting tidbits stood out:

  • ADS is still relevant – and may still be a feature according to Microsoft 🙂
  • A variety of invocation methods could execute the streams (“exe/dll files”) such as wmic, start, rundll32, mavinject, forfiles, w/cscript, mshta, etc.
  • Several “low privileged” security groups can write to interesting files and directories

This compelled me to look into this a little further…

Directory Permissions Within SystemRoot (“C:\Windows”)

Using the Sysinternals tool, accesschk, I enumerated the sub-folders beneath ‘c:\windows’ to locate writable directories for three low-privileged groups:

  • Everyone
  • Users
  • Authenticated Users

I was quite surprised to see the results….


It is quite interesting to note that the opportunity for abuse is very prevalent.  Actors could potentially write to these locations for satisfying any number of malicious requirements.  For this post, we’ll focus on potential ADS abuse within the confines of a WINDOWS sub-directory to bypass AppLocker default policies using control.exe and DLL/CPL loading.

ADS ‘Reflective’ DLL Execution via Control.exe

Firstly, let’s create a an arbitrary text file (‘zzz’) within one of our writable directories. C:\windows\Tasks seems like a prime candidate based on our previous enumeration exercise:


Secondly, we inject our payload (a reflective DLL that launches notepad.exe) into the ADS of the ‘zzz’ file:

type notepad_reflective_x64.dll > c:\windows\tasks\zzz:notepad_reflective_x64.dll

Thirdly, we attempt to invoke our reflect DLL in two ways:

control.exe c:\test\reflective_dlls\notepad_reflective_x64.dll
control.exe c:\windows\tasks\zzz:notepad_reflective_x64.dll

The results are depicted in the following screenshot:


AppLocker prevented direct invocation of the reflective DLL via control.exe but allowed the ADS injected version to run.  Result: Successful Bypass!

ADS ‘Control Panel’ CPL Execution via Control.exe

@ConsciousHacker posed a great question while collaborating with me about the DLL method. He asked “Looks like it might also be capable of loading unsigned PE, did you try that as well?”  At the time, the answer was simply no, but he did inspire the next round of research.

Moving forward, I halfheartedly knew that CPL (control panel) files were ‘pretty much’ DLL files.  With this elementary logic, I simply renamed notepad_reflective_x64.dll to notepad_reflective_x64.cpl and loaded this into the ADS of another file for the same style execution.  Of course that didn’t work, but fortunately @Hexacorn chimed in and saved me from added research time!  Big shout out to him for this assist:


More info about the CPIApplet export can be found on Microsoft’s MSDN website.  Additionally, output of  the SysInternals strings utility shows the usage of rundll32/shell32.dll within control.exe:


To test the CPL method, I discovered a proof-of-concept Control Panel applet project on Github called MyCPLApplet (authored by gtrubach).  After installing the required components, I launched Visual Studio, edited the code to add a proper payload (notepad.exe, of course), and compiled the CPL binary as shown below:

*Note: As always, review the code that you compile/run or launch in a sandbox/segmented/virtual environment.


Next, I renamed the cpl file to notepad_x64.cpl, created a text file within the C:\Windows\Tasks directory called ‘yyy’, and injected the CPL payload into the ADS stream as depicted in the following screenshot:


So far so good – let’s attempt to execute our CPL file directly with control.exe…


As expected, this failed to launch due to the default AppLocker policy settings.  Let’s attempt to launch via the ADS method…


Result: Success! We executed our notepad.exe payload embedded within MyCPLApplet.

Other Notes & Research

@ReneFreingruber pointed out a very interesting bypass technique with regard to building the ADS on the actual Task Folder, which I believe is actually more compelling than creating files within such writable directories.  His fantastic research and post can be accessed here.  Thank you for sharing this!

@matthomjxiex02x blogged about an interesting technique for bypassing AppLocker policies via the exec command found in netsh.  His research can be found here.

Blue Team Recommendations

Here are a few pointers that may help…

  • Consider locking down the file permissions on folders and directories within \Windows, \Windows\System32, \Program Files…\, etc.  For clarity, the ability to write to *interesting* directories is crucial.  In retrospect, we can run an arbitrary DLL/CPL within c:\windows\tasks to defeat the Default AppLocker Rules but we can also run these DLL/CPL payloads hidden in streams on files and folders.
  • Proactive monitoring is necessary.  Do not solely relay on what was prevented to execute but also review what actually has executed.   Use SysInternals tools to look for indications of ADS.  Streams.exe is a nice tool.  Sysmon/SEM monitoring may reveal interesting strings (i.e. somefile.txt:evil.dll is probably not good).  Of course, this is easier said than done.
  • Visit the other research blogs and Twitter pages of the aforementioned security researchers for further information regarding ADS, AppLocker bypasses, and other offensive security insight.
  • Update [3/17/2018] – Many thanks to @r0wdy_ for providing a Splunk Query that may help locate ADS invocation in Sysmon sources:
Sourcetype=sysmon | eval numColon = mvcount(split(Image, ":")) -1 | where numColon = 2


Well, that wraps up another interesting AppLocker post.  Please feel free to contact me or leave a message if you have any other questions/comments. I will try to update this page regularly with related research links as they become visible.  Thank you for reading!