In May 2026, CN Security Consulting's adversary emulation practice attempted to reconstruct the POWGOOP DLL sideload chain associated with the Iranian state-aligned threat group MuddyWater (also tracked as MERCURY, Static Kitten, Seedworm, and overlapping clusters tracked by Mandiant as UNC3313). The chain, widely documented across public reporting from 2020–2023, abuses a signed GoogleUpdate.exe binary to load a malicious goopdate.dll, which in turn decrypts and executes a PowerShell-based second stage.
Reconstruction against a current signed Chrome installer (file version 149.0.7814.0, x64) yielded the following findings:
goopdate.dll no longer appears in the static import surface of current Chrome installer binaries. Reproduction of the originally reported chain against contemporary binaries is non-functional.version.dll, a frequent fallback in legacy sideload tooling, is blocked by Windows 10/11 KnownDLLs precedence — a runtime protection that postdates the public POWGOOP reporting and is not addressed in any of the cited advisories.msimg32, dbghelp, winmm, uxtheme, winhttp) remain operationally viable as sideload covers when paired with appropriately staged forwarder targets.We assess with high confidence that public reporting on POWGOOP captures a point-in-time pairing of threat actor, host binary version, and Windows runtime state, and that direct emulation against current target environments requires per-engagement re-validation of the cover DLL component of the chain. The underlying technique — DLL sideload via signed Google update infrastructure (MITRE ATT&CK T1574.002) — remains current; the specific named artifact does not.
| Field | Value |
|---|---|
| Primary designation | MuddyWater |
| Aliases | MERCURY, Static Kitten, Seedworm, TEMP.Zagros, ITG17 |
| Vendor cluster overlap | Mandiant UNC3313 (partial), CrowdStrike Static Kitten |
| Attribution | Iran, Ministry of Intelligence and Security (MOIS); high confidence (CISA, NCSC-UK, Mandiant) |
| Active since | 2017 (observed) |
| Targeting | Government, telecommunications, energy, defence; predominantly Middle East, Türkiye, South Asia; tactical interest in IL, SA, AE, JO, IQ, PK |
| Notable toolkits | POWGOOP, POWERSTATS, MuddyC2Go, PhonyC2, SimpleHelp / Atera / ScreenConnect / RemoteUtilities (RMM abuse), BugSleep (Check Point, 2024) |
The POWGOOP chain as documented across CISA AA22-055A (2022), Mandiant M-Trends (2022), and Symantec threat intelligence reporting proceeds as follows:
[Spear-phishing payload]
|
v
[Dropper writes to %LOCALAPPDATA%\Google\Update\]
|
v
[GoogleUpdate.exe (signed Google LLC)]
|
| (DLL search order load)
v
[goopdate.dll (malicious)]
|
| (RC4 decrypt)
v
[config.txt -> PowerShell stager -> C2]
The cover binary's Authenticode signature provides parent-process legitimacy at the EDR telemetry layer. The malicious payload itself is unsigned but is co-located with the cover binary in a directory the loader searches before System32.
A minimal proxy DLL was constructed in C and built with MinGW-w64 (x86_64-w64-mingw32-gcc 13). The DLL implements MessageBoxW in DllMain as an observable execution marker, in lieu of a functional second stage, to permit deterministic validation of the load path:
BOOL APIENTRY DllMain(HMODULE h, DWORD reason, LPVOID rsv) {
if (reason == DLL_PROCESS_ATTACH) {
HANDLE m = CreateMutexW(NULL, TRUE, L"Local\\poc-fired");
if (m && GetLastError() != ERROR_ALREADY_EXISTS) {
MessageBoxW(NULL, L"sideload OK", L"poc",
MB_OK | MB_ICONINFORMATION);
}
}
return TRUE;
}
Three cover DLL names were tested sequentially against a current signed GoogleUpdate.exe obtained from a clean Chrome installer (file version 149.0.7814.0): goopdate.dll, version.dll, and msimg32.dll. Each cover candidate was validated in isolation via rundll32.exe <cover>.dll,<export> to confirm proxy DLL integrity before testing the sideload path. All testing was conducted in an isolated, non-domain-joined Windows 11 virtual machine.
Placement of goopdate.dll adjacent to the current GoogleUpdate.exe produced no observable execution. Static import surface inspection via dumpbin /dependents confirmed goopdate.dll is not present in the binary's implicit dependency list:
ADVAPI32.dll dbghelp.dll GDI32.dll MSIMG32.dll
OLEAUT32.dll SHELL32.dll SHLWAPI.dll USER32.dll
VERSION.dll WINMM.dll WS2_32.dll KERNEL32.dll
ole32.dll WTSAPI32.dll ntdll.dll Secur32.dll
USERENV.dll COMCTL32.dll WINHTTP.dll UxTheme.dll
api-ms-win-core-winrt-l1-1-0.dll
api-ms-win-core-synch-l1-2-0.dll
We assess with high confidence that Google's restructuring of the Chrome update component post-2023 removed goopdate.dll from the implicit dependency set. Public reporting referencing the chain reflects the binary surface available at the time of the original campaign. The technique does not translate forward to contemporary Chrome installers without cover substitution.
This finding is consistent with the broader pattern of TTP rot in published threat reporting: a documented technique is captured as a triple <actor, technique, target binary state>, of which only the first two are typically reproduced in public writeups. The third drifts as vendors patch and refactor.
VERSION.dll is present in the current import surface and represents the obvious substitution path. Reproduction nonetheless failed.
The Windows image loader honours a runtime protection mechanism in which DLLs enumerated under the registry key
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs
are pre-mapped into the \KnownDlls\ section object during session initialisation. The loader resolves names in this set from that section regardless of process-local directory contents, bypassing the standard DLL search order. On default Windows 10 and Windows 11 installations, the following sideload covers documented in legacy offensive tooling are protected by this mechanism and cannot be substituted via co-located file:
version, ole32, oleaut32, shell32, shlwapi, user32, gdi32, comctl32, advapi32, kernel32, ws2_32, imm32, rpcrt4, setupapi, sechost, msvcrt.
This protection is not referenced in the original POWGOOP reporting and is therefore not anticipated by analysts working directly from those advisories. Operators substituting cover DLLs against modern Windows hosts should treat the KnownDLLs registry key as a precondition check before tooling investment in any candidate.
msimg32.dll satisfies all three preconditions required for a viable sideload cover against the current GoogleUpdate.exe:
dumpbin /dependents).KnownDLLs registry key on default Windows 10 / Windows 11.AlphaBlend, DrawShadowText, GradientFill, TransparentBlt, vSetDdrawflag) and has been stable since Windows XP SP2, minimising forwarder maintenance and cross-version risk.The proxy DLL was compiled to export the five msimg32 functions as PE forwarders targeting a co-located msimg32_orig.dll (a renamed copy of C:\Windows\System32\msimg32.dll). The forwarder definitions:
LIBRARY msimg32
EXPORTS
AlphaBlend = msimg32_orig.AlphaBlend
DrawShadowText = msimg32_orig.DrawShadowText
GradientFill = msimg32_orig.GradientFill
TransparentBlt = msimg32_orig.TransparentBlt
vSetDdrawflag = msimg32_orig.vSetDdrawflag
Deployment to a single working directory containing the signed GoogleUpdate.exe, the proxy msimg32.dll, and the renamed msimg32_orig.dll produced clean execution of the DllMain marker within the signed parent process. The forwarder mechanism ensured that subsequent msimg32 calls from the parent binary were transparently proxied to the legitimate system implementation, preserving parent-process stability for the duration of the load.
GoogleUpdate.exe v149 was observed to re-spawn a child instance of itself during initialisation (consistent with Google's documented updater self-relaunch pattern, used to elevate or switch user contexts). The child process independently re-loads the cover DLL, causing the DllMain entrypoint to execute in two distinct processes within a single user-initiated invocation. Single-fire semantics, where operationally required, can be enforced via a Local\-namespace named mutex set during the first execution.
| ID | Technique | Context |
|---|---|---|
T1574.002 | Hijack Execution Flow: DLL Side-Loading | Primary technique under analysis |
T1036.005 | Masquerading: Match Legitimate Name or Location | Co-located DLL named to match expected static import |
T1140 | Deobfuscate/Decode Files or Information | config.txt RC4 decryption in the original chain (not exercised in this reproduction) |
T1059.001 | Command and Scripting Interpreter: PowerShell | Original POWGOOP second-stage execution (not exercised) |
T1218.011 | System Binary Proxy Execution: Rundll32 | Used for DLL integrity validation only |
The artifacts below correspond to the laboratory proxy DLL used in this research. They are provided for detection-engineering validation and are not in-the-wild MuddyWater indicators.
| Field | Value |
|---|---|
| File name | msimg32.dll |
| SHA-256 | 8b79af1959bd7ef2cb8a8a1cc3f1805e64793bd25e93a5231655b5d6dbc90818 |
| File size | 12,800 bytes |
| Compiler timestamp | 0x6A0BC556 (2026-05-19 12:05:10 UTC) |
| Imports | KERNEL32.dll, USER32.dll, msvcrt.dll |
| Mutex (session-local) | Local\poc-fired |
| Forwarder target | msimg32_orig.dll (renamed system DLL, co-located) |
For defenders observing host telemetry against this class of sideload activity:
Microsoft-Windows-Sysmon Event ID 7, CrowdStrike Falcon ImageLoad IOAs) where the loaded module path matches msimg32.dll, dbghelp.dll, winmm.dll, uxtheme.dll, or winhttp.dll and the path does not resolve under C:\Windows\System32\ or C:\Windows\SysWOW64\, particularly when the loading process is a signed third-party updater (GoogleUpdate.exe, OneDriveStandaloneUpdater.exe, vendor RMM agents).SuspiciousDllLoad IOA family covers a subset of this surface; tuning thresholds against signed-parent / unsigned-child combinations is recommended.%LOCALAPPDATA%, %TEMP%, %PUBLIC%) co-locating a signed third-party binary, an unsigned module with a System32 namesake, and a third file with the same stem as the namesake suffixed _orig, _real, or similar. This staging pattern is highly specific to proxy-DLL sideload tradecraft.POWGOOP as a named tool family is, in our assessment, operationally retired in its 2022 form against modern Chrome installers. The technique class — DLL sideload via signed Google update infrastructure — remains viable, and MuddyWater's broader tooling has continued to evolve, with MuddyC2Go (Deep Instinct, November 2023) and BugSleep (Check Point, July 2024) representing the more recent capability investments by this actor. Adversary emulation engagements modelled on MuddyWater should incorporate the actor's continued preference for signed-binary execution chains and legitimate remote-management software (Atera, ScreenConnect, SimpleHelp), while treating named DLL artifacts in 2022-era reporting as starting hypotheses subject to revalidation.
We assess with moderate confidence that the cover-selection framework above (static import presence, KnownDLLs exclusion, low-cardinality export surface) generalises to sideload work against other signed update agents and vendor binaries on Windows 10/11, including but not limited to Adobe Acrobat update components, Citrix Workspace, Zoom, and a range of enterprise RMM agents. Validation against specific binaries remains a per-engagement task.