In the last couple of years I have had an interest in application whitelisting bypasses and avidly followed the work of Casey Smith (@subtee) and Matt Graeber (@mattifestation). The major conclusion from their work is that application whitelisting has to be locked down to avoid trusted application launching attacker code. While it seems quite clear that on Windows 7 and 8.1 Powershell is an easy way to bypass application whitelisting through reflective PE injection, Windows 10 is a different story. With the activation of Powershell Constrained Language Mode along with AppLocker in Windows 10 this avenue seems closed. While Casey Smith has a lot of research on bypassing application whitelisting in other ways here, they all assume prior code execution on the victim machine. I am a great fan of PowerShell Empire by Veris Group as an attack framework, and I really like the HTML Application attack vector. As I will show below this attack does not work out of the box when Powershell Constrained Language Mode is enabled. But then I got to thinking whether using prior public research and code would it make it possible to make the attack vector viable again. This blog post describes how I did that though a lot of nested techniques and code.
HTA Attack
If you have not heard of HTML Applications as an attack vector or not seen Powershell Empire in action before, I will quickly describe and show how it normally works. After starting Powershell Empire and creating a Listener, in my case called test, we create a HTA stager and simply set the Listener name and the output file:
We place it on a webserver which is accessible from the victim. The HTA file contains the following code:
Since HTA files are opened outside the browser sandbox ActiveX objects are allowed to execute. It simply launches Powershell with a base64 encoded command which pulls another larger Empire agent stager and executes it in memory. The victim browses to the link and sees:
Followed by:
After clicking Run the callback happens and Empire launches a new agent on the victim:
AppLocker and Powershell Constrained Language
This post was about how to gain that Empire agent through a HTA file even though AppLocker and Powershell Constrained Language Mode is enabled. Before that, I want to highlight the consequences for the attacker. If I try to run a piece of malware on the machine, in this case called Malware.exe, I get the following prompt:
And if I try to run commands using .NET components in Powershell like shown below it gets blocked:
Likewise, if I try to launch the same attack as before using the HTA it will be stopped as well
We get the same error from Powershell due to Constrained Language Mode. We now have to work our way around that.
Powershell Without Powershell
There has been some research into running Powershell commands without the use of Powershell.exe. The idea is that Powershell.exe is really only an interpreter for the .NET assembly System.Management.Automation and it is perfectly possible to write our own interpreter invoking that assembly. The problem we face is the presence of application whitelisting so we need to launch our custom interpreter somehow. Furthermore, this interpreter has to run in some process space and I would like to inject it into an existing process instead of it creating its own which must keep running while the agent is in use. After looking around I found the PowerPick project by Veris Group, which contains a module called ReflectivePick, which again is built from work done by Lee Christensen (@tifkin_). It is a C++ application that is compiled to a single DLL and invokes a custom runspace from System.Management.Automation, in effect allowing Powershell commands to be executed.
To start my tests I compiled the ReflectivePick DLL with a simple command to be executed in the runspace as shown below:
I then ran the ReflectivePick DLL by using rundll32 from a folder which I whitelisted and got the result below:
The Powershell commands were executed and even more importantly the Language Mode of the runspace is FullLanguage even though AppLocker locked Powershell.exe down to Constrained Language.
Using this I updated the argument parameter to contain the base64 encoded Powershell Empire stager from earlier, along with a decoding routine since we are no longer using the -Encoded parameter. I also logged the decoded command to a file to be able to debug it. The full command can be seen below:
Running the updated DLL from the command line shows the decoded Empire stager in the text file:
And an Empire agent is launched:
Going to Other Processes
So far, we are creating a new process through rundll32.exe and loading the DLL into that. This is not a viable way since the DLL is not whitelisted, furthermore, we are creating a new process. To avoid those two problems we can load the ReflectivePick DLL into another process by using the Powershell script Invoke-ReflectivePEInjection. This, of course, creates the problem of launching Powershell script when Constrained Language Mode is enabled, but let’s return to that later. Invoke-ReflectivePEInjection takes two arguments for our use case, the DLL as a byte array and the process ID of the process to be injected into. I would like to inject the ReflectivePick DLL into the explorer process so we find the PID of that first:
Then we get the content of the ReflectivePick DLL into a byte array as shown below:
The Invoke-ReflectivePEInjection script is written as a function, so we import the module first, making sure to place it in a whitelisted folder to avoid Constrained Language for the moment. And then invoke it using the PID and the DLL:
We notice that the debugging text file is created with the Empire stager, as seen below we are successful in getting the agent running from inside the explorer process:
Let us embed the commands for getting the PID and the bytes from the DLL into the Powershell script, as well as calling the function so we don’t need to import it first. This is done by adding the following to the end of the script file:
We then simply run the Powershell script file without any arguments:
And we get our Empire agent callback:
We still face the problem of having the ReflectivePick DLL as an external file on disk, so let’s embed it into the Powershell script. This is done by encoding the bytes of the DLL to base64 as seen below:
The content of the encoded file is then copied into the Powershell script and assigned to a variable:
And instead of getting the bytes of the file from disk, we get them by base64 decoding the content of the variable:
And again, we receive the Empire agent:
Calling Powershell from InstallUtil.exe
In principle, we have not achieved anything yet, since we now use Powershell to load a DLL into memory which calls Powershell and Constrained Language Mode will still block it. However, we have made sure that the Powershell execution happens from inside an existing process and not a new one. We do need to overcome the problem of calling Invoke-ReflectivePEInjection when Constrained Language Mode will block it. To achieve this, we use InstallUtil.exe to run execute a custom EXE which creates an unmanaged Powershell runspace. Casey Smith as published a way to use InstallUtil.exe to bypass AppLocker some time ago along with proof of concept code for creating a Powershell runspace.
I modified the code to just execute a single predefined command, which to begin with is just some dummy code to make sure it works as seen below:
Compiling this to an EXE called Bypass.exe and trying to run it on the victim clearly gets blocked by AppLocker:
Then we run InstallUtil.exe to execute the uninstall method using the command line parameters described by Casey Smith:
From the picture above we can see that the command was executed and that the custom Powershell runspace does not have Constrained Language Mode enabled. From this, we change the test command to be the entire Invoke-ReflectivePEInjection script along with the embedded DLL and the launching commands we added earlier. We face another difficulty, Powershell breaks commands either on a new line or with at semicolon. Invoke-ReflectivePEInjection is created with new lines, but embedding it into the C# project requires it to be in one line, to amend for this we base64 encode the entire file first. This is seen below:
This is then embedded into the EXE along with a base64 decoding routine:
We also write the decoded Powershell command to the test5.txt file to make sure it works. Running InstallUtil.exe against the updated code yields:
The Invoke-ReflectivePEInjection script was decoded and retained its new lines, furthermore, the Empire stager is also written to its debug file. And we can see below that the Empire agent was successfully launched:
Calling InstallUtil.exe
So far, we managed to convert our bypass for Powershell Constrained Language Mode into a AppLocker bypass for EXE files. While we also succeeded in executing the EXE we still need some way of calling InstallUtil.exe and downloading the EXE to disk. To achieve this we are going to use Regsvr32.exe which is another AppLocker bypass Casey Smith discovered.
Regsvr32.exe can be used to execute scriptlets, which can contain arbitrary JavaScript. So, to start out we cheat and still have the EXE on disk but execute InstallUtil.exe from a scriptlet run by Regsvr32.exe. The scriptlet used is modified from Casey Smith’s proof of concept:
Running it is shown below:
Which gives us an Empire agent callback:
Now you may wonder why I use Regsvr32.exe to launch InstallUtil.exe since I did not really gain anything. But the point is that Regsvr32.exe can also be used to download the EXE to disk, furthermore, the scriptlet file may also be stored on a web server, as shown below:
Downloading Files
To test the download through Regsvr32.exe we base64 encode some dummy text:
We then use another method found by Casey Smith of abusing certutil.exe to decode and write it to disk. The base64 encoded text is placed inside BEGIN CERTIFICATE and END CERTIFICATE tags to provide the correct format to certutil.exe. We then write the base64 encoded text to a file and decode it using certutil.exe as shown below:
Executing it like so:
And the content of the file is clearly decoded. It is now time to take this up a nudge and embed the EXE provided to InstallUtil.exe instead. So, we encode it using certutil.exe on another computer:
To allow the base64 blob over multiple lines we add a backwards slash to each line end:
While testing, it turned out that I was not able to embed the entire encoded EXE in just one scriptlet. So, I had to split it up into 4 parts inserted into separate scriptlets. Each of these four scriptlets simply takes the embedded base64 code and write it to a file as shown below:
Executing shows the file being written:
I then create a fifth scriptlet file which takes the four files on disk and combines them to one text file and proceeds to invoke certutil.exe to decode it and write the EXE to disk:
Running all the scriptlets like so:
Yields an Empire agent callback:
To compact this I, embed the call to the four slave scriptlets inside the master scriptlet by adding
Which when run again gives an Empire agent callback:
Back To HTA
Now we finally have a single command we can call which in the end will create our Empire agent. To launch it we can embed that command inside a HTA file just as when AppLocker is not present:
The link to this file is sent in a phishing mail like we normally do and end up in the users browser:
Which when run gives the Empire agent we longed for, despite AppLocker and Powershell Constrained Language Mode being enabled:
Conclusion
To sum it up this method serves a HTA from a webserver, which invokes Regsvr32.exe to execute five scriptlets, which downloads an embedded base64 encoded EXE, decodes it and writes it to disk. Then executes InstallUtil.exe bypass AppLocker and in turn, execute the uninstall method of the EXE. The EXE contains a base64 encoded Powershell script, which is decoded and executed in a custom Powershell runspace created by the EXE. The Powershell script contains an embedded base64 encoded DLL, which is decoded and reflectively loaded into the explorer process by the Powershell script. The reflectively loaded DLL contains an embedded base64 encoded Powershell script which is decoded and executed inside a custom Powershell runspace inside the explorer process. The Powershell script is the normal stager for the Powershell Empire agent.
For this attack to work the following binaries need to be whitelisted by AppLocker:
- MSHTA.EXE
- REGSVR32.EXE
- CERTUTIL.EXE
- INSTALLUTIL.EXE
While it does require all four to be whitelisted, they will be if the default AppLocker rules are used or if all Microsoft signed binaries are trusted. While the attack does bypass both AppLocker and Powershell Constrained Language Mode and in addition AMSI, it does not bypass ScriptBlock Logging so detection is possible as seen below:
I want to appreciate the awesome work done by Casey Smith, Lee Christensen and everyone else I’ve referenced in this post. The code for the individual code parts can be found on GitHub here:
https://github.com/MortenSchenk/Babuska-Dolls