Skip to content

Mshta.exe - proxy execution of an attacker DLL via user-writable InProcServer32 (not COM activation) - #540

Open
xhaabx wants to merge 1 commit into
LOLBAS-Project:masterfrom
xhaabx:xhaabx-patch-1
Open

xhaabx wants to merge 1 commit into
LOLBAS-Project:masterfrom
xhaabx:xhaabx-patch-1

Conversation

@xhaabx

@xhaabx xhaabx commented Nov 9, 2026

Copy link
Copy Markdown

Binary: mshta.exe (C:\Windows\System32\mshta.exe, C:\Windows\SysWOW64\mshta.exe)

Summary

On Windows 11 24H2/25H2, mshta.exe reads the default value of HKCU\Software\Classes\CLSID\{25336920-03F9-11CF-8FD0-00AA00686F13}\InProcServer32 and passes it directly to LoadLibrary, loading that DLL in-process with no signature or path validation. A standard user can set this value (HKCU, no elevation) to an attacker-controlled DLL and get code execution inside the signed mshta.exe, with an empty command line - bypassing all command-line and script-content detection.

This is NOT COM activation / COM hijacking (the obvious objection), and it is falsifiable:

  • A DLL exporting only RunHTMLApplication (no DllGetClassObject, no COM metadata of any kind) executes. COM in-proc activation would fail such a DLL with REGDB_E_CLASSNOTREG before running any code. It ran, so the load path is not COM activation.
  • mshta.exe statically imports NO ole32/combase, and has no delay-load imports. Verified on build 26300: x64 = msvcrt.dll, KERNEL32.dll, ADVAPI32.dll; x86 = msvcrt.dll, KERNEL32.dll, ADVAPI32.dll, iertutil.dll. (ADVAPI32 = the registry read, KERNEL32 = LoadLibrary - exactly the described mechanism, with zero COM surface.)
  • Scanning the OS image, mshta.exe is the only binary that consumes this GUID as a module path.

Precedent

This is the same shape as the already-accepted cmstp.exe /nf entry ("Proxy execution of a DLL through a registry modification" - it reads CmstpExtensionDll and passes it to LoadLibrary). This one is arguably stronger: cmstp /nf requires Administrator (HKLM), whereas this works as a standard user (HKCU).

Proposed addition

New Command on the existing Mshta entry (passes validation.py and yamllint):

  - Command: mshta.exe
    Description: Reads the default value of `HKCU\Software\Classes\CLSID\{25336920-03F9-11CF-8FD0-00AA00686F13}\InProcServer32` and passes it to LoadLibrary, loading that DLL in-process. Pointing this user-writable value at an attacker DLL side-loads it through the signed mshta.exe with an empty command line.
    Usecase: Proxy execution of an attacker-controlled DLL through a user-writable (HKCU) registry modification, which bypasses mshta.exe command-line and script-content detection.
    Category: Execute
    Privileges: User
    MitreID: T1218.005
    OperatingSystem: Windows 11 24H2, Windows 11 25H2
    Tags:
      - Execute: DLL Side-Load
      - Sideload: InProcServer32 Registry Redirect

Plus two detection IOCs, and reporter credit in Acknowledgement. Happy to adjust framing, MitreID, or wording per maintainer preference.

Standard-user DLL proxy execution via the user-writable HKCU InProcServer32 value
@xhaabx
xhaabx requested a review from a team as a code owner November 9, 2026 19:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant