MedusaLocker: CMSTPLUA COM UAC Bypass — Detection

MedusaLocker Image

Detection material for the auto-elevated COM bypass MedusaLocker uses to reach high integrity without a consent prompt. Technique write-up: MedusaLocker_CMSTPLUA_UACBypass.

MITRE ATT&CK: T1548.002

Detection Indicators

Indicator Value
CLSID (CMSTPLUA → ICMLuaUtil) {3E5FC7F9-9A51-4367-9063-A120244FBEC7}
CLSID (ColorDataProxy → ICMLuaUtil) {D2E7041B-2927-42FB-8E9F-7CE93B6DC937}
Provider DLLs cmlua.dll, colorui.dll
Moniker string Elevation:Administrator!new:
Process artifact dllhost.exe /Processid:{<clsid>} at High integrity
Discriminator a High-integrity child of a Medium-integrity parent with no consent.exe in between

The last row is the one that matters. The CLSIDs are fast to match and trivial to rotate; the absence of consent.exe before a silent elevation is structural and survives the attacker switching to a different auto-elevate object.

Log Sources

Files

File Contents
sigma_cmstplua_uac_bypass.yml 5 Sigma rules — surrogate launch, elevated child, LOLBin backstop, moniker in script, provider DLL load
cmstplua_uac_bypass.yar 4 YARA rules — file, native PE, script and memory scanning
hunting_queries.md KQL, SPL and EQL hunts, plus the Sysmon config needed to feed them

Detection Engineering with Sigma

Five rules, layered from most specific to most durable.

Rule Level Catches
COM Surrogate Launched for an Auto-Elevating CLSID high the setup step — dllhost.exe spawned for a known-abused CLSID
Child Process Spawned by Auto-Elevating COM Surrogate critical the payload itself, as a child of that surrogate
Suspicious Interpreter or LOLBin Spawned by COM Surrogate high the same shape for CLSIDs not on the list
Elevation Moniker String in Script or Command Line critical PowerShell / JScript / C# variants, via script block logs
ICMLuaUtil Provider DLL Loaded by Unexpected Process medium in-process variants and provider hijacks — hunt input, not an alert

The highest-fidelity signal is the second: ICMLuaUtil::ShellExec runs the payload as a child of the surrogate, so the parent command line still carries the CLSID.

detection:
    selection:
        ParentImage|endswith: '\dllhost.exe'
        ParentCommandLine|contains:
            - '3E5FC7F9-9A51-4367-9063-A120244FBEC7'
            - 'D2E7041B-2927-42FB-8E9F-7CE93B6DC937'
    condition: selection
level: critical

Detection Engineering with Defender XDR

The CLSID-agnostic hunt — a silent elevation with no consent prompt in the preceding 30 seconds. This is the one to weight alerting toward.

let window = 30s;
let elevated =
    DeviceProcessEvents
    | where ProcessIntegrityLevel in ("High", "System")
    | where InitiatingProcessIntegrityLevel == "Medium"
    | project Timestamp, DeviceId, DeviceName, AccountName, FileName,
              ProcessCommandLine, InitiatingProcessFileName,
              InitiatingProcessCommandLine, ProcessId;
let consents =
    DeviceProcessEvents
    | where FileName =~ "consent.exe"
    | project DeviceId, ConsentTime = Timestamp;
elevated
| join kind=leftouter consents on DeviceId
| summarize ConsentInWindow = countif(ConsentTime between ((Timestamp - window) .. Timestamp))
          by DeviceId, ProcessId, Timestamp, DeviceName, AccountName, FileName,
             ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine
| where ConsentInWindow == 0
| order by Timestamp desc

The remaining queries — surrogate launch, elevated child, moniker in script content, plus the Splunk and Elastic equivalents — are in hunting_queries.md.

Detection Engineering with YARA

Four rules covering file, native PE, script and memory scanning. The CLSIDs are matched in three forms: ASCII, UTF-16LE, and the little-endian binary GUID a compiler emits into .rdata, so a sample that never stores the CLSID as text is still caught.

{3E5FC7F9-9A51-4367-9063-A120244FBEC7}
  -> F9 C7 5F 3E 51 9A 67 43 90 63 A1 20 24 4F BE C7

UACBypass_ICMLuaUtil_Memory is deliberately loose and is meant for process dumps only, not a filesystem sweep.

Validation and tuning

Baseline first. Query 30 days of dllhost.exe command lines and allow-list the CLSIDs your estate legitimately surrogates. On most fleets these never appear, which makes the CLSID rules near zero-noise. Environments deploying Connection Manager profiles through cmstp.exe are the main exception.

Test with vetted tooling. Atomic Red Team T1548.002 has sandboxed, documented atomics for this technique. Use those to confirm the rules fire rather than authoring a bypass.

Known blind spot. If the payload is delivered in-process — for example by writing a registry value through ICMLuaUtil::SetRegistryStringValue and letting another process consume it — there is no elevated child to catch. The provider-DLL-load rule and registry monitoring cover that path.

Disclaimer

For educational purposes only!!!