Lateral Movement via DCOM: Round 2

Most of you are probably aware that there are only so many ways to pivot, or conduct lateral movement to a Windows system. Some of those techniques include psexec, WMI, at, Scheduled Tasks, and WinRM (if enabled). Since there are only a handful of techniques, more mature defenders are likely able to prepare for and detect attackers using them. Due to this, I set out to find an alternate way of pivoting to a remote system.

This resulted in identifying the MMC20.Application COM object and its “ExecuteShellCommand” method, which you can read more about here. Thanks to the help of James Forshaw (@tiraniddo), we determined that the MMC20.Application object lacked explicit “LaunchPermissions”, resulting in the default permission set allowing Administrators access:

empty_launch_permissions

You can read more on that thread here. This got me thinking about other objects that have no explicit LaunchPermission set. Viewing these permissions can be achieved using @tiraniddo’s OleView .NET, which has excellent Python filters (among other things). In this instance, we can filter down to all objects that have no explicit Launch Permission. When doing so, two objects stood out to me: “ShellBrowserWindow” and “ShellWindows”:

interesting_objects

Another way to identify potential target objects is to look for the value “LaunchPermission” missing from keys in HKCR:\AppID\{guid}. An object with Launch Permissions set will look like below, with data representing the ACL for the object in Binary format:

launch_permissions_registry

Those with no explicit LaunchPermission set will be missing that specific registry entry.

The first object I explored was the “ShellWindows” instance. Since there is no ProgID associated with this object, we can use the Type.GetTypeFromCLSID .NET method paired with the Activator.CreateInstance method to instantiate the object via its AppID on a remote host. In order to do this, we need to get the AppID CLSID for the ShellWindows object, which can be accomplished using OleView .NET as well:

[Edit] Thanks to @tiraniddo for pointing it out, the instantiation portions should have read “CLSID” instead of “AppID”. This has been corrected below.

[Edit] Replaced screenshot of AppID wit CLSID

shellwindow_classid

As you can see below, the “Launch Permission” field is blank, meaning no explicit permissions are set.

screen-shot-2017-01-23-at-4-12-24-pm

 Now that we have the AppID CLSID, we can instantiate the object on a remote target:

remote_instantiation_shellwindows

With the object instantiated on the remote host, we can interface with it and invoke any methods we want. The returned handle to the object reveals several methods and properties, none of which we can interact with. In order to achieve actual interaction with the remote host, we need to access the WindowsShell.Item method, which will give us back an object that represents the Windows shell window:

item_instantiation

With a full handle on the Shell Window, we can now access all of the expected methods/properties that are exposed. After going through these methods, “Document.Application.ShellExecute” stood out. Be sure to follow the parameter requirements for the method, which are documented here.

shellwindows_command_execution

As you can see above, our command was executed on a remote host successfully.

Now that the “ShellWindows” object was tested and validated, I moved onto the “ShellBrowserWindow” object. One of the first things I noticed was that this particular object does not exist on Windows 7, making its use for lateral movement a bit more limited than the “ShellWindows” object, which I tested on Win7-Win10 successfully. Since the “ShellBrowserWindow” object was tested successfully on Windows 10-Server 2012R2, it should be noted as well.

I took the same enumeration steps on the “ShellBrowserWindow” object as I did with the “ShellWindows” object. Based on my enumeration of this object, it appears to effectively provide an interface into the Explorer window just as the previous object does. To instantiate this object, we need to get its AppID CLSID. Similar to above, we can use OleView .NET:

[Edit] Replaced screenshot of AppID wit CLSID

shellbrowser_classid

Again, take note of the blank Launch Permission field 🙂

screen-shot-2017-01-23-at-4-13-52-pm

With the AppID CLSID, we can repeat the steps taken on the previous object to instantiate the object and call the same method:

shellbrowserwindow_command_execution

As you can see, the command successfully executed on the remote target.

Since this object interfaces directly with the Windows shell, we don’t need to invoke the “ShellWindows.Item” method, as on the previous object.

While these two DCOM objects can be used to run shell commands on a remote host, there are plenty of other interesting methods that can be used to enumerate or tamper with a remote target. A few of these methods include:

  • Document.Application.ServiceStart()
  • Document.Application.ServiceStop()
  • Document.Application.IsServiceRunning()
  • Document.Application.ShutDownWindows()
  • Document.Application.GetSystemInformation()

Defenses

You may ask, what can I do to mitigate or detect these techniques? One option is to enable the Domain Firewall, as this prevents DCOM instantiation by default. While this mitigation works, there are methods for an attacker to tamper with the Windows firewall remotely (one being remotely stopping the service).

There is also the option of changing the default “LaunchPermissions” for all DCOM objects via dcomncfg.exe by right clicking on “My Computer”, selecting “Properties” and selecting “Edit Default” under “Launch and Activation Permissions”. You can then select the Administrators group and uncheck “Remote Launch” and “Remote Activation”:

dcom_default_lockdown

Attempted instantiation of an object results in “Access Denied”:

remote_instantiation_failure

You can also explicitly set the permissions on the suspect DCOM objects to remove RemoteActivate and RemoteLaunch permissions from the Local Administrators group. To do so, you will need to take ownership of the DCOM’s HKCR AppID key, change the permissions via the Component Services MMC snap-in and then change the ownership of the DCOM’s HKCR AppID key back to TrustedInstaller. For example, this is the process of locking down the “ShellWindows” object.

First, take ownership of HKCR:\AppID\{9BA05972-F6A8-11CF-A442-00A0C90A8F39}. The GUID will be the AppID of the DCOM object; finding this was discussed above. You can achieve this by going into regedit, right click on the key and select “permissions”. From there, you will find the “ownership” tab under “advanced”.

dcom_registry_ownership

As you can see above, the current owner is “TrustedInstaller”, meaning you can’t currently modify the contents of the key. To take ownership, click “Other Users or Groups” and add “Administrators” if it isn’t already there and click “Apply”:

apply_ownership

Now that you have ownership of the “ShellWindows” AppID key, you will need to make sure the Administrators group has “FullControl” over the AppID key of the DCOM object. Once done, open the “Component Services” MMC snap-in, browse to “ShellWindows”, right click on it and select “Properties”. To modify the Remote Activation and Launch permissions, you will need to go over to the “Security” tab. If you successfully took ownership of AppID key belonging to the DCOM object, the radio buttons for the security options should *not* be grayed out.

edit_default_dcom_perms

To modify the Launch and Activation permissions, click the “edit” button under the “Launch and Activation Permissions” section. Once done, select the Administrators group and uncheck “Remove Activation” and “Remote Launch”. Click “Ok” and then “Apply” to apply the changes.

remove_perms_dcom

Now that the Remote Activation and Launch permissions have been removed from the Administrators group, you will need to give ownership of the AppID key belonging to the DCOM object back to the TrustedInstaller account. To do so, go back to the HKCR:\AppID\{9BA05972-F6A8-11CF-A442-00A0C90A8F39} registry key and navigate back to the “Other Users and Groups” section under the owner tab. To add the TrustedInstaller account back, you will need to change the “Location” to the local host and enter “NT   SERVICE\TrustedInstaller” as the object name:

trustedinstaller_restore

Click “OK” and then “Apply” to change the owner back.

One important note: Since we added “Administrators” the “FullControl” permission to the AppID key belonging to the DCOM object, it is critical to remove that permission by unchecking the “FullControl” box for the Administrators group.  Since the updated DCOM permissions are stored as “LaunchPermission” under that key, an attacker can simply delete that value remotely, opening the DCOM object back up if not properly secured.

After making these changes, you should see that instantiation of that specific DCOM object is no longer allowed remotely:

remote_instantiation_failure

Keep in mind that while this mitigation does restrict the launch permissions of the given DCOM object, an attacker could theoretically remotely take ownership of the key and disable the mitigation since it is stored in the registry.

There is the option of disabling DCOM, which you can read about here. I have not tested to see if this breaks anything at scale, so proceed with caution.

As a reference, the three DCOM objects I have found that allows for remote code execution are as follows:

MMC20.Application (Tested Windows 7, Windows 10, Server 2012R2)
AppID: 7e0423cd-1119-0928-900c-e6d4a52a0715

ShellWindows  (Tested Windows 7, Windows 10, Server 2012R2)
AppID: 9BA05972-F6A8-11CF-A442-00A0C90A8F39

ShellBrowserWindow (Tested Windows 10, Server 2012R2)
AppID: C08AFD90-F2A1-11D1-8455-00A0C91F3880

It should also be noted that there may be other DCOM objects allowing for similar actions performed remotely. These are simply the ones I have found so far.

Full Disclosure: I encourage anyone who implements these mitigations to test them extensively before integrating at scale. As with any system configuration change, it is highly encouraged to extensively test it to ensure nothing breaks. I have not tested these mitigations at scale.

As for detection, there are a few things you can look for from a network level. When running the execution of this technique through Wireshark, you will likely see an influx of DCERPC traffic, followed by some indicators.

First, when the object is instantiated remotely, you may notice a “RemoteGetClassObject” request via ISystemActivator:

isystemactivator_getclassobject

Following that, you will likely see “GetTypeInfo” requests from IDispatch along with “RemQueryInterface” requests via IRemUnknown2:

idispatch_gettypeinfo

While this may, in most cases, look like normal DCOM/RPC traffic (to an extent), one large indicator of this technique being executed will be in a request via IDispatch of GetIDsofNames for “ShellExecute”:

method_enumeration

Immediately following that request, you will see a treasure trove of useful information via an “Invoke Request”, including *exactly* what was executed via the ShellExecute method:

method_params_over_wire

That will immediately be followed by the response code of the method execution (0 being success). This is what the actual execution of commands via this method looks like:

shellexecute_returncode

Cheers!
Matt N.

Lateral Movement using the MMC20.Application COM Object

For those of you who conduct pentests or red team assessments, you are probably aware that there are only so many ways to pivot, or conduct lateral movement to a Windows system. Some of those techniques include psexec, WMI, at, Scheduled Tasks, and WinRM (if enabled). Since there are only a handful of techniques, more mature defenders are likely able to prepare for and detect attackers using them. Due to this, I set out to find an alternate way of pivoting to a remote system.

Recently, I have been digging into COM (Component Object Model) internals. My interest in researching new lateral movement techniques led me to DCOM (Distributed Component Object Model), due to the ability to interact with the objects over the network. Microsoft has some good documentation on DCOM here and on COM here. You can find a solid list of DCOM applications using PowerShell, by running “Get-CimInstance Win32_DCOMApplication”.

While enumerating the different DCOM applications, I came across the MMC Application Class (MMC20.Application). This COM object allows you to script components of MMC snap-in operations. While enumerating the different methods and properties within this COM object, I noticed that there is a method named “ExecuteShellCommand” under Document.ActiveView.

executeshellcommad_method

You can read more on that method here. So far, we have a DCOM application that we can access over the network and can execute commands. The final piece is to leverage this DCOM application and the ExecuteShellCommand method to obtain code execution on a remote host.

Fortunately, as an admin, you can remotely interact with DCOM with PowerShell by using “[activator]::CreateInstance([type]::GetTypeFromProgID”. All you need to do is provide it a DCOM ProgID and an IP address. It will then provide you back an instance of that COM object remotely:remote_instantiation

It is then possible to invoke the “ExecuteShellCommand” method to start a process on the remote host:

start_remote_process

As you can see, calc.exe is running under Matt while the user “Jason” is logged in:

process_validation

By using this DCOM application and the associated method, it is possible to pivot to a remote host without using psexec, WMI, or other well-known techniques.

To further demonstrate this, we can use this technique to execute an agent, such as Cobalt Strike’s Beacon, on a remote host. Since this is a lateral movement technique, it requires administrative privileges on the remote host:

validate_admin_beacon

As you can see, the user “Matt” has local admin rights on “192.168.99.132”. You can then use the ExecuteShellCommand method of MMC20.Application to execute staging code on the remote host. For this example, a simple encoded PowerShell download cradle is specified. Be sure to pay attention to the requirements of “ExecuteShellCommand” as the program and its parameters are separated:

command1

The result of executing this through an agent results in obtaining access to the remote target:

execution

To detect/mitigate this, defenders can disable DCOM, block RPC traffic between workstations, and look for a child process spawning off of “mmc.exe”.

Edit: After some investigating and back & forth with James Forshaw, it appears that the Windows Firewall will block this technique by default. As an additional mitigation, ensure the windows firewall is enabled and “Microsoft Management Console” isn’t an enabled rule.

Cheers!
Matt N.

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: https://technet.microsoft.com/en-us/itpro/windows/keep-secure/device-guard-deployment-guide.  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: https://blogs.msdn.microsoft.com/visualstudio/2011/10/19/introducing-the-microsoft-roslyn-ctp/

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: https://github.com/dotnet/roslyn

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:

rcsi_code

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:

rcsi_execution

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:

http://www.exploit-monday.com/2016/09/using-device-guard-to-mitigate-against.html

You can find a comprehensive bypass mitigation policy here:

https://github.com/mattifestation/DeviceGuardBypassMitigationRules

If you want to know more about “Misplaced Trust” bypasses, you can find @subtee’s awesome Bluehat presentation slides here: https://github.com/subTee/BlueHat2016

Cheers!
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: https://technet.microsoft.com/en-us/itpro/windows/keep-secure/device-guard-deployment-guide.  

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:

https://blogs.msdn.microsoft.com/sujitdmello/2015/04/23/step-by-step-installation-instructions-for-getting-dnx-on-your-windows-machine/

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:

csharp_code

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:

dnx_bypass

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:

http://www.exploit-monday.com/2016/09/using-device-guard-to-mitigate-against.html

You can find a comprehensive bypass mitigation policy here:

https://github.com/mattifestation/DeviceGuardBypassMitigationRules

Cheers!
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:

eventvwr_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:

hkcr_mscfile_query

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:

registry_queries

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:

mscfile_key_hijack

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

hijack_query

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”:

powershell_load

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

powershell_procexp

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: https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Invoke-EventVwrBypass.ps1

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’).

TaskElevation

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”.

FolderCreation

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

FileExtraction

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:

dismhostStart

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:

DllsLoaded

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.

ElevatedDllLoad

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: https://gist.github.com/mattifestation/b4072a066574caccfa07fcf723952d54

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: https://github.com/enigma0x3/MessageBox

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:

AlwaysNotify

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”:

actions_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” :

class_id_xml_task

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.

legit_clsid_entry

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.

added_hkcu_entry

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

modified_hkcr_entry

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:

logon_task

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

dll_popup_on_execute

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:

dll_loaded_in_procexp

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:

https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Get-ScheduledTaskComHandler.ps1

 

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):

script_default

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

on_logon_flag

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:

persistence_locations_flag

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!

https://github.com/enigma0x3/MessageBox

Cheers!

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.

generate_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.

output

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:


create_macro

 

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:

add_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:

banner

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

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:

generate_hta

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:

hta_code

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.

host

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:

box

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.

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.

bat_generate

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”

insert_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:

adding_ole

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:

 

icon

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):

final_ole

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.

ole_agent

Conclusion

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.

Find_LocalInfo

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

New_SCCMSession

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.

Get_SCCMComputer

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:

user_hunt

*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.

New_SCCMCollection

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”:

Collection_verify

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.

device_add

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.

New-SCCMApplication

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.

payload_verify

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

gui

 

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).

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.

Checkin

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

execution

 

Cleanup

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.

deployment_cleanup

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

Remove-Application

And finally, we can delete our device collection:

remove_collection

 

Wrapup

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.

Elevation

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).

not_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.

initial_local_admin

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.

bypass_uac

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.

mike_process

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

mike_mimikatz

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.

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”.

creds_filtered

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.

get_user_setu

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

get_user_output

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.

Hunting

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.

user_hunter

It looks like the Domain Admin “DEV\will-da” has a session from 192.168.99.136. 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:
host_resolve

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.
localgroup_setup

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

localgroup_execute

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.

filtered_ps

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

steal_token

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:

WMI_SETUP

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.

wmi_execute

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

da_credentials

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”:

will-da_processes

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.

will-da_inject

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:

domain_controller

Now let’s verify the access:

dev_dc_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:

domain_trust

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:

parent_user_to_sid

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:

dev_krbtgt

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

dev_krbtgt_credstore

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.

golden_ticket

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

lab_local_krbtgt

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

all_krbtgt

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:

final_golden_ticket_setup

final_golden_ticket

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$:

lab_dc_access

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!