0. Preface
This set started as 19 MalwareBazaar samples tagged WailsLoader, plus one live capture of the actual drop and its benign installer stub. It ends as six parallel fake-desktop-app campaigns running through the Microsoft Store at once — a PDF editor, an e-signature app, a TOTP authenticator, a task manager, a document signer, and a business tool called AdPayWorks — all built from the same toolkit and fronted by the same distribution mechanism.
Every campaign follows the same five-stage shape: a Microsoft Store listing whose publisher identity is fabricated but which passes Microsoft’s own review; a genuinely Microsoft-signed installer stub that does nothing wrong itself, it just asks WinGet to fetch a URL the actor controls; an x86 Advanced Installer wrapper signed with a throwaway EV/OV certificate; a Go/Wails desktop application — signed with the same certificate as the wrapper — that is a fully working decoy app with one hidden method whose name is a Cyrillic homoglyph; and, behind that hidden method, a cluster of native and .NET stagers ending in an in-memory ConfuserEx-protected backdoor.
The most useful finding in the whole set is not any one binary, it’s a pattern: the actor buys one EV/OV code-signing certificate per fake product and uses it to sign both the installer and the final-stage Go/Wails binary for that product. Any two files sharing a leaf certificate can be treated as the same delivery chain before their code is even compared, and section 2 uses that to tie six certificates to six storefronts.
The most surprising finding is operational, not technical: during live capture, the actor’s own server was down, and Microsoft’s own content delivery network kept serving the malicious installer anyway, because WinGet’s manifest pointed at a URL Microsoft’s edge had already cached.
Static work covered all 20 files — PE/MSI structure, Go symbol recovery via debug/gosym (the samples are Go 1.26.x, and kuna’s bundled gopclntab pass doesn’t yet recognize that layout; the pclntab itself is intact, so nothing here was garbled), and full decompilation of the native and .NET stager cluster. One live capture against the actual Store listing supplied the network evidence in section 3. Dynamic capture ends before the installer runs, which is the largest gap in this writeup and is stated plainly in section 11 rather than papered over.

1. The Threat at a Glance
| Attribute | Assessment |
|---|---|
| Malware type | Multi-stage loader campaign — fake desktop app to native/.NET backdoor cluster |
| Scope | At least 6 parallel fake-product campaigns, 20 analyzed files |
| Distribution | Microsoft Store listings with fabricated publisher identities, WinGet-resolved installer URLs |
| Delivery chain | Genuine MS-signed installer stub -> x86 Advanced Installer/MSI wrapper -> Go/Wails desktop app -> native/.NET stager cluster -> in-memory .NET backdoor |
| Signature abuse | One throwaway EV/OV code-signing certificate per product line, reused across the installer and the Go/Wails final stage |
| C2 resolution | Telegram dead-drop (invite page scraped for two delimited tokens) |
| Persistence | WMI __EventFilter/ActiveScriptEventConsumer (WebSocket RAT); none in the Go loader itself |
| Evasion | Cyrillic-homoglyph JS-bound Go method; AMSI/ETW patching; extensive VM/sandbox detection; parent-PID spoofing under explorer.exe; C2-gated activation |
| Toolchain | Go 1.26.4/1.26.5 (Wails v2.11.0 + WebView2), MinGW, MSVC, .NET Framework 4 / ConfuserEx v1.0.0 |
| Confidence | High through the Go/Wails lure stage (direct static and dynamic evidence); the loader-to-stager handoff is inferred, not observed executing (section 11) |
2. The Certificate-Sharing Pattern — the Key Pivot
The actor buys one EV/OV code-signing certificate per fake product and signs both the x86 installer wrapper and the Go/Wails final-stage binary for that product with it. That pairing is the strongest link in the whole corpus, because it survives a rebuild of either binary independently.
| Fake product | Installer (SHA-256, short) | Final-stage Go/Wails binary (short) | Shared certificate | Issuer / country |
|---|---|---|---|---|
| PDF-Editor Free v1.0.0 | f48cd2db | 9714e527 | Osauhing Karusoftware | SSL.com, EE |
| PDF-Editor v1.0.1 (live) | 5fe31560 | 9ba0779e | Fast Home Group LLC | GlobalSign EV, KG |
| AdPayWorks | 860fc154 | 603264cb | Code Beyond d.o.o. | Certum EV, HR |
| Signature Nib / DocumSign | c64bc948 | 660f1a38 (poss. e203208a) | CODE LOFTS d.o.o. | Certum EV, HR |
| TMS Desktop | 56b6a194 | f1711b81 | MINERALS GROUP AS | GlobalSign EV, NO |
| PDF Municipal | b7b4d20f | not identified | Progenies d.o.o. / Darko Parun | Certum CS 2021, HR |
| T2Auth Bastion | no matching installer | 89c1bb04 | PROGRAMVARE PARTNER ANS | Certum CS 2021, NO |
The 9ba0779e pairing is worth calling out specifically: it carries the identical Go module name (pdf-editor-ui), the identical C2 API-key UUID as 9714e527 (section 5.3), and a GlobalSign EV certificate issued to a Kyrgyz shell company that matches the certificate already observed on 5fe31560 — the installer the Store is currently serving. That makes 9ba0779e the strongest candidate for the binary actually behind the live v1.0.1 listing.
A second reuse cuts across product lines rather than versions: eec6fb4f (the sandbox-evasive beacon covered in section 6.2) carries the same campaign tagging as the PDF-Editor chain, and is also the middle stage of the separate AdPayWorks chain (860fc154 -> eec6fb4f -> 603264cb, Store product xpdcjdx0gjh2bj). If that positioning holds, eec6fb4f is not campaign-specific tooling — it’s a shared component the actor drops into more than one storefront. Confirming its exact position in that second chain needs further static work this writeup doesn’t complete (section 11).
Report all seven certificates/entities in this table to their issuing CAs (SSL.com, GlobalSign, Certum) if not already revoked — 5fe31560 is already MalwareBazaar-tagged revoked-cert.
3. Stage 1 — Distribution: Microsoft Store Abuse
This section is the one part of the chain confirmed by live dynamic capture, against Store product XPDNW909QJ8Z9R (“PDF-Editor Free”, publisher VIACHESLAV).
The Store installer stub itself is clean. Its Authenticode digest matches Microsoft’s own signature exactly, it writes no persistence, drops no payload, and delegates entirely to WinGet through the DesktopAppInstaller packaged-COM server. It is not part of the malicious chain in any technical sense — it’s a legitimate tool the actor is abusing by controlling what it’s told to fetch.
WinGet’s own msstore manifest, fetched live from Microsoft’s endpoint with an HTTP 200, names the installer source as:
InstallerUrl: https://pdf-editore.com/download/1.0.1/pdf_editor.exe
SHA-256: 5fe31560...
Publisher: VIACHESLAV
PrivacyUrl: https://pdf-editore.com/policy
The actor’s own origin was down. 64.94.85.16 (ARIN BNL-77, BL Networks) took 11 connection attempts over roughly three minutes, every SYN unanswered until a delayed RST/ACK about 80 seconds later each time — the host was alive and the port was filtered or rate-limited, not unallocated.
Microsoft’s own CDN mirrored the malicious installer anyway. cdn.storeedgefd.dsx.mp.microsoft.com served the full 9.54 MB installer with no issue. The campaign keeps functioning even with the actor’s infrastructure offline, because Microsoft’s edge is doing unwitting double duty as a CDN for it.
The Store installer stub’s local install attempt failed with 1612 (ERROR_INSTALL_SOURCE_ABSENT) once the origin timed out, and handed off to the Store app UI on the same product page — which keeps the victim on the same path, since retrying succeeds via the Microsoft mirror per the manifest fallback.
The listing was still live at the time of writing. It passed Microsoft’s own ratings questionnaire (ESRB/PEGI/IARC “Everyone”) and carries no publisher support URL.
This same shape — a Store listing whose declared installer URL routes to a throwaway domain, backed by a matching EV-cert-signed x86 wrapper — is the distribution mechanism behind every product line in section 2, not just PDF-Editor Free.
4. Stage 2 — The x86 Advanced Installer Wrappers
Six samples (56b6a194, 5fe31560, 860fc154, b7b4d20f, c64bc948, f48cd2db) are all x86, MSVC, WinUI3/XAML, built with Advanced Installer (MSI-inside-CAB-inside-EXE). Pairwise 4KB-block similarity sits at 26-30% — consistent with one shared build template carrying a different bundled payload per product, not independent authorship.
The transform layer pulled from f48cd2db’s CAB (final_exit_early_ca_Id.mst) is stock Advanced Installer environment detection (AI_DETECT_MODERNWIN/AI_DETECT_WINTHEME) — not itself malicious. The actual MSI database — the real install sequence, and any custom-action DLLs beyond Advanced Installer’s own aicustact.dll — sits in a high-entropy region past the CAB and was not decompressed for any of the six installers. That’s the largest unclosed static gap in this corpus: it’s where any dropper logic distinct from Advanced Installer’s stock behavior would live.
5. Stage 3 — The Go/Wails Loader Family
5.1 Toolchain
Seven confirmed binaries — five “all-in-one” lures, the original thin drop, and one evolved variant — are all Go 1.26.4/1.26.5, CGO_ENABLED=0, built -tags=desktop,wv2runtime.download,production -trimpath=true, statically linking Wails v2.11.0 and WebView2. The pclntab is intact in every sample; kuna’s bundled gopclntab pass simply doesn’t recognize the Go 1.26.x layout yet, which is a tooling gap rather than obfuscation. Symbols were recovered directly via debug/gosym — around 11,600 functions per binary.
5.2 The JS-Go Surface, and the Homoglyph Trick
Every sample exposes a plausible, on-brand main.App API to its embedded React UI — config, minimize/quit, an NPS survey modal shared verbatim across builds. A fully working, unremarkable app is exactly what a victim sees.
Every sample also carries at least one bound method whose name is a Cyrillic homoglyph of a benign one, wired into the same JS binding table the legitimate methods use — invisible to any diff or grep that only compares visible ASCII:
| Sample(s) | Rendered name | Real codepoints |
|---|---|---|
| 5 all-in-one lures | Dо | D + U+043E (Cyrillic о) |
9714e527 (drop, v1.0.0) | GеtStаts | G + U+0435 (е) + tSt + U+0430 (а) + ts |
9ba0779e (variant, v1.0.1-era) | GеtStаts | same codepoints; function nearly doubled in size (3,008 vs 1,568 bytes) |
In 9ba0779e the JS caller is directly confirmed: window.go.main.App.G\u0435tSt\u0430ts(), gated behind if (await GetStatus() !== 200) { <homoglyph>() }. The malicious path only fires when the operator’s C2 signals activation with a non-200 /status response, and fails safe to the benign PDF editor otherwise — which defeats naive sandbox detonation outright.
5.3 What the Thin Drop Does
9714e527 (v1.0.0 era) and 9ba0779e (v1.0.1 era, functionally an evolved successor) both:
- Resolve their C2 from a Telegram dead-drop at launch. They GET the invite page and regex out two values delimited by
i1il...i1il/i2il...i2ilmarkers.9714e527usest[.]me/+ELxonbrgbH82M2My;9ba0779eusest[.]me/+YqZP3uv-e1A3MWYy. - Reuse the identical C2 API-key UUID,
904a3fac-6233-41d2-b72f-fd1217581b0b, across both builds. The header is renamed fromX-API-Key(v1) toauth(v2), but the value is byte-identical — a hard technical link between the two. - Beacon AV/EDR presence via WMI (
SELECT displayName, productState FROM AntiVirusProductonroot\SecurityCenter2), filtering out Windows Defender, then POST the inventory to the C2 (/compatibility,/cmp). - Execute a payload fetched live from the C2. In v1 this is entirely fileless:
cmd.exe /c start /b "" powershell.exe ... -Command -, with the script piped over stdin — it never touches disk and never appears on a command line.
9ba0779e materially expands on this with capability the thin drop lacked:
- UAC self-elevation (
RunMeElevated: checksToken.IsElevated, then relaunches viaShellExecuteverbrunas). - Parent-PID spoofing under
explorer.exe(findExplorerPIDvia a Toolhelp snapshot andOpenProcess, thenplatformLaunchspawnspowershell.exeas its child) — defeats naive process-lineage detection. - An on-disk drop path (
getAppDataFolder+os.WriteFile) alongside the fileless one, with the C2 itself choosing which mode to use per victim (getPayloadType,GET /type). - Granular per-stage telemetry — numeric status codes (198-214) beaconed to a new
/expectendpoint at every step.
The progression — a thin, fileless v1 to an elevation-and-spoofing-capable, modular v2, sharing the same key material throughout — reads as active, iterative development of one loader by one author.
5.4 The Shared Toolkit in the All-in-One Lures
The five non-drop Go builds (603264cb, 660f1a38, 89c1bb04, e203208a, f1711b81) additionally carry a name-identical function set the thin drop lacks:
AddrFromKey CheckCompatibilities Decrypt FindProcessByName GetConfig
GetCont IsE RunDLLMiMain RunMeElevated Rundll32 checkup deriveKey
getAppDataFolder main maskToRegex platformLaunch sendCompatibility
sendNotify
9ba0779e now independently reimplements RunMeElevated, getAppDataFolder, and platformLaunch under its own names, which points to the thin-drop and all-in-one-lure product lines converging on the same capability set rather than being architecturally distinct — most likely one builder/toolkit assembled with different feature flags per build.
RunMeElevated’s call shape — parent-process-path spoofing ahead of a COM elevation-moniker call — matches api.exe exactly (section 6.1), which strongly suggests the lures either embed the same UAC-bypass technique directly or shell out to api.exe-equivalent logic. The exact elevation moniker/CLSID in use is still unconfirmed.
5.5 A Suspected Wallet-Targeting Module
e203208a (DocumSign.exe) and f1711b81 (TMS Desktop.exe) — the two heaviest builds by Go module weight — additionally statically link the full go-ethereum stack and expose:
GetBSCRPCURLs GetCurrentDomain GetNodeList CreateRoute
ReserveGetCurrentDomain decodeString
A literal Ethereum 2.0 Beacon Chain deposit-contract address, 0x00000000219ab540356cbb839cbe05303d7705fa, sits in .rodata of both. That’s consistent with a crypto-clipper or wallet-drain routing module, but it was not traced function-by-function to a confirmed mechanism. 603264cb (AdPayWorks) links the same go-ethereum tree but exposes none of these main.* functions — whether that dependency is dead code there or reached a different way is an open question.
5.6 Per-Build Telegram Invites
t[.]me/+3KxzpB3tzKgyMDA6 (603264cb), +WUiDcN4CU_tjMzdi (660f1a38), +iIoD9gfWUFU4NzAy (89c1bb04), +ELxonbrgbH82M2My (9714e527), +YqZP3uv-e1A3MWYy (9ba0779e) — one invite per build. Dead-drop use is confirmed for the last two (section 5.3); it’s unconfirmed for the other three. Treat these as IOC only — do not join or interact with them from analysis infrastructure.
6. Stage 4 — The Native/COM/.NET Stager Cluster
6.1 api.exe — a Standalone UAC-Bypass COM Invoker
6 KB, MinGW, stripped, x64. Two functions carry all the logic:
Process-parameter spoofing. It walks its own PEB RTL_USER_PROCESS_PARAMETERS loader-data-table, finds the entry matching its own image path, and overwrites ImagePathName/CommandLine with %WINDIR%\explorer.exe — making the calling process look like explorer.exe to anything that checks a caller’s claimed image path before trusting it.
A generic COM elevation-moniker invoker. It parses argv as (moniker, IID, vtable-offset, BSTR-arg), calls CoGetObject on the moniker, and invokes the method at the given vtable offset. The specific moniker/CLSID is supplied by the caller — api.exe itself is a generic UAC auto-elevate bypass tool in the ICMLuaUtil/CMSTPLUA family, and the actual bypass target is decided by whatever invokes it, presumably the Go loader’s RunMeElevated (section 5.4).
6.2 eec6fb4f (lib.dll) — a Sandbox-Evasive Beacon and CLR Loader
550,912 bytes, x64 PE DLL, MSVC 2015+, no packer, with OLLVM-style control-flow mangling in DllMain and a custom bytecode-VM string encryptor — fully broken statically, all 234 strings recovered.
It exports the exact shape of a native WMI MI provider (MI_Main, GetProviderClassID, DllGetClassObject, DllRegisterServer/DllUnregisterServer), and every one of those exports is a stub. Its version resource brands it “Eta Diagnostics Agent” / “Eta Software”, internal name ytm.exe / ytm_LLVM_fmbuild_1_1789139889.dll — the embedded build epoch decodes to 2026-09-11, two days before this analysis, so this is an actively maintained, recently rebuilt component. None of the WMI-provider branding is real functionality; it’s cover for what actually runs from a thread spawned in DllMain on process attach:
- Runtime AMSI/ETW evasion (
amsi_patch,EtwEventWriteFull/NtTraceEventpatching) andrdtsc-based anti-debug/anti-emulation timing checks. - Extensive sandbox/VM detection — registry keys, driver files, named pipes, DLLs, ACPI tables, MAC-address prefixes for VirtualBox, VMware, QEMU/KVM/Xen/Bochs, and Parallels, plus Sandboxie, Anubis, Cuckoo, JoeBox, Wine, and AV-hook DLL presence (AVG/Kaspersky), assembled into one
vm_detect_compositeverdict. - Host fingerprinting over WMI — BIOS serial, MAC, manufacturer/model, CPU core count and ProcessorId, disk size, PnP DeviceIDs, thermal/fan sensors — serialized into one JSON beacon body.
- An HTTPS POST beacon to
evangelicool[.]com/rteh4e5y46hesr/gre/...with headerX-Api-Key: 798yhdxgbf9870yes4r987ydtgrf098h7urdtgand a customftl-http-post/1.0protocol marker, over WinAPI resolved by hash rather than by name, viawinhttp.dll. - A second URL,
myslimwave[.]com/unwelcome/.../log-ADP.txt, is processed through a .NET CLR-hosting path (CorBindToRuntimeEx/CLRCreateInstance,mscorlib 4.0,System.AppDomain,Marshal.GetFunctionPointerForDelegate) that resolves and invokesConsoleApp2.Program::Main. - A full process-injection primitive set (
Nt/VirtualAlloc/Read/WriteVirtualMemory, thread/section creation) is present but not confirmed exercised.
Cross-corpus correlation. The WebSocket-RAT stager described in section 6.4 is the assembly ConsoleApp2. The class name eec6fb4f loads via CLR hosting — ConsoleApp2.Program::Main — is an exact match, which makes it very likely eec6fb4f’s secondary URL is the actual delivery path for that RAT. This is a static code-level correlation, not a dynamically observed one, so it’s flagged for confirmation rather than stated as settled (section 11).
6.3 PSCom52.dll — a COM-Surrogate, In-Process PowerShell Service
.NET Framework 4, unobfuscated, fully decompiled. It self-registers as a COM class factory (CLSID 964ED7B9-0682-4555-BEB6-6FCF1DDAED4E, ProgId PSCom.Host50) via CoRegisterClassObject/CoAddRefServerProcess — no regsvr32 needed, just running the assembly turns the host process into a persistent local COM server.
RunPowerShell(script, timeout) builds a System.Management.Automation runspace with a no-op host and executes entirely in-process — no powershell.exe child, no command-line artifact. It’s explicitly designed, per its own logging, to run under dllhost.exe as a DCOM surrogate, and it logs to the world-writable C:\Users\Public\PSCom\*.log.
6.4 starter_<GUID>.dll (ConsoleApp2) — a WebSocket RAT Client
.NET Framework 4, unobfuscated, fully decompiled — the cleanest, most complete artifact in the corpus.
C2: wss://gentle-hall-f741.luckluck8889991111.workers[.]dev/signup?token=<UUID> (Cloudflare Workers). The token in the URL is the same UUID that names the dropped file, which confirms per-victim/per-build keying at generation time.
Protocol: ##-delimited command frames — download (base64 to file or named pipe), check (SHA-256 or pipe liveness), subscr (persistence, below), info (full host recon), launch (spawn any process with optional stdin/stdout capture).
subscr installs permanent WMI persistence — an __EventFilter (Name=NetFilter, WQL on Win32_LocalTime every 20 seconds) bound via __FilterToConsumerBinding to an ActiveScriptEventConsumer (Name=NetCon, JScript, operator-supplied script). Classic fileless WMI persistence: it survives reboot, and there’s no Run key or scheduled task to find.
6.5 stage3_payload.dll — the ConfuserEx-Protected Final Payload
.NET Framework 4, protected with ConfuserEx v1.0.0 (anti-tamper plus method-body encryption; ilspycmd fails outright, and dnlib shows every method body as il=0 except housekeeping). It is byte-identical to the payload black-jun10-with-logs2.ps1 decrypts and loads:
AES-256-CBC -> gzip-decompress -> 367,104-byte .NET assembly
-> Reflection.Assembly.Load(bytes) [entirely in-memory]
-> 15s poll loop, feed-forward return value, ~36-minute session cap
Type and method names are themselves mangled, consistent with ConfuserEx name obfuscation on top of anti-tamper. Full behavioral recovery of this stage needs de4dot under Flare-VM — outside the Linux static toolchain used here.
7. Indicators of Compromise
Network
| Type | Indicator | Confidence |
|---|---|---|
| Domain | pdf-editore[.]com | High — live InstallerUrl |
| URL | https://pdf-editore[.]com/download/1.0.1/pdf_editor.exe | High |
| URL | https://pdf-editore[.]com/policy | High |
| IPv4 | 64.94.85.16 | High |
| CIDR | 64.94.84.0/23 (ARIN BNL-77, BL Networks) | Medium — pivot range |
| Dead-drop | t[.]me/+ELxonbrgbH82M2My | High |
| Dead-drop | t[.]me/+YqZP3uv-e1A3MWYy | High |
| Dead-drop | t[.]me/+3KxzpB3tzKgyMDA6, +WUiDcN4CU_tjMzdi, +iIoD9gfWUFU4NzAy | High |
| C2 auth | X-API-Key/auth: 904a3fac-6233-41d2-b72f-fd1217581b0b | High — reused literal key |
| C2 URL | https://evangelicool[.]com/rteh4e5y46hesr/gre/g4e5/y54h/6/ewfg/rewy4/5uh6u | High |
| C2 URL | https://myslimwave[.]com/unwelcome/.../log-ADP.txt | High |
| Header | X-Api-Key: 798yhdxgbf9870yes4r987ydtgrf098h7urdtg | High |
| C2 | wss://gentle-hall-f741.luckluck8889991111.workers[.]dev/signup?token=<per-build GUID> | High |
| Mirror — do not block | cdn.storeedgefd.dsx.mp.microsoft.com | n/a — Microsoft’s own CDN |
Files
| SHA-256 | Name | Role |
|---|---|---|
b083085da6281e7bfa92bd195972744a52811bf29fc3c09f6d69f93f7c25f2c6 | PDF-Editor Free Installer.exe | Benign, Microsoft-signed stub |
f48cd2db9e47caf70aca8cd3465509365248586d319e2b09a12d4354743746de | PDF-Editor Free.exe 1.0.0 | x86 installer |
5fe315609f09970c936310dea43318c2c5aca71da236c7f890c72e61f7696b5f | PDF-Editor.exe 1.0.1 | x86 installer, currently live on the Store |
9714e527b424152df7391a7c9dc5b3a537c77ccfcb299d85d31f48771897c52b | PDF-Editor.exe | Go/Wails thin drop, v1.0.0 |
9ba0779e868f29ffb1738ff2f95b9bb18951527ff3283b8dff20ef2896448259 | PDF-Editor.exe | Go/Wails evolved drop, v1.0.1 |
860fc154444167d8411d3796d047093ad242fcb071eb645e845ea9e048c15cb5 | AdPayWorks.exe | x86 installer |
603264cbf503d230902ee89324431bf3b81aebbdb31ca3cafe2deef0652405fc | AdPayWorks.exe | Go/Wails lure (all-in-one) |
eec6fb4f124564fea83670faf7b61140347020a3ca3eef052d4dc6bad4097893 | lib.dll (“Eta Diagnostics Agent”) | Sandbox-evasive beacon + CLR loader |
d1585ac714ef2f5bd01e2a782c1442b188b5b0c5c068abc91ef484434bbbe8f6 | api.exe | UAC-bypass COM invoker |
52b70540c5bb90fa31db0b4f68bff5becd3e56a45e19aebc7ca18cd26a81b815 | PSCom52.dll | COM-surrogate fileless PowerShell |
9741e24cffbf4549bf5f5d3aa20ee691c1bcb1b5fbe45274cee257b310c70257 | starter_<GUID>.dll | WebSocket RAT |
3ba7b714468ba7983a36f8ad5b188141dc4288949ecf01b11079908e1e6e4e3c | stage3_payload.dll | ConfuserEx in-memory backdoor |
f83bbe06704086ae3e0a85eb3d465885696a1070ec0fd04be0dfd4601cbe50be | black-jun10-with-logs2.ps1 | PowerShell loader for stage3 |
Host artifacts
| Artifact | Meaning |
|---|---|
Downloads\Microsoft.Management.Deployment.winmd, Microsoft.Services.Store.winmd next to a StoreInstaller-signed EXE | A Store install stub ran from that directory |
HKLM\SOFTWARE\Microsoft\Tracing\<app name>_RASAPI32|RASMANCS | Stub name recorded at first RAS use |
BAM entry under HKLM\System\CurrentControlSet\Services\bam\State\UserSettings\<SID> | Execution timestamp |
MSI ProductCode {0d732e58-7045-4a9e-b6a5-fd17fe5d1a1e}, Apps & Features “PDF Editor 1.0.1”, publisher VIACHESLAV | The malicious MSI completed |
COM CLSID 964ED7B9-0682-4555-BEB6-6FCF1DDAED4E (ProgId PSCom.Host50) | Fileless PowerShell-as-COM-service |
C:\Users\Public\PSCom\*.log | World-writable log location |
WMI __EventFilter Name=NetFilter / ActiveScriptEventConsumer Name=NetCon | Fileless persistence |
Homoglyph bound methods (Dо, GеtStаts) | Static/dynamic detection signature — grep for non-ASCII in a Go binary’s main.App/pclntab symbol table |
Abused certificates are listed in section 2 — report all seven to their issuing CAs if not already revoked.
8. MITRE ATT&CK Mapping
| Tactic | Technique | Stage |
|---|---|---|
| Resource Development | T1583.001 Acquire Infrastructure: Domains | pdf-editore[.]com, evangelicool[.]com, myslimwave[.]com |
| Resource Development | T1588.003 Obtain Capabilities: Code Signing Certificates | Section 2 |
| Initial Access | T1195.002 Supply Chain Compromise: Software Supply Chain | Microsoft Store abuse |
| Execution | T1204.002 User Execution: Malicious File | Store stub to installer |
| Execution | T1059.001/.003 Command & Scripting Interpreter: PowerShell/cmd | Fileless loader, PSCom52 |
| Persistence | T1546.003 WMI Event Subscription | starter_*.dll subscr |
| Privilege Escalation | T1548.002 Abuse Elevation Control Mechanism (UAC) | RunMeElevated, api.exe |
| Defense Evasion | T1553.002 Subvert Trust Controls: Code Signing | Abused EV certs throughout |
| Defense Evasion | T1036 Masquerading | Fake product names, “Eta Diagnostics Agent” |
| Defense Evasion | T1036.005 Masquerading: Match Legitimate Name | WMI-provider export shape on eec6fb4f |
| Defense Evasion | T1134.004 Parent PID Spoofing | 9ba0779e explorer.exe spoof; api.exe |
| Defense Evasion | T1622 Debugger/VM Evasion | eec6fb4f sandbox detection |
| Defense Evasion | T1562.001 Impair Defenses (AMSI/ETW patch) | eec6fb4f |
| Discovery | T1057 Process Discovery | findExplorerPID |
| Discovery | T1518.001 Security Software Discovery | WMI SecurityCenter2 AV enumeration |
| Discovery | T1082 System Information Discovery | eec6fb4f WMI fingerprinting |
| Command and Control | T1071.001 Web Protocols | HTTPS/WSS beacons throughout |
| Command and Control | T1102.001 Web Service (dead drop resolver) | Telegram invite links |
| Command and Control | T1105 Ingress Tool Transfer | Payload fetched live from C2 |
| Command and Control | T1480 Execution Guardrails | GetStatus-gated activation |
9. Detection Opportunities
- Non-ASCII characters inside a Go binary’s
main.App/pclntab symbol table. The homoglyph signature is cheap to detect and present in every variant found so far. - Any two binaries sharing a leaf code-signing certificate where one is an Advanced-Installer x86 EXE and the other a Go/Wails x64 EXE. This is the single strongest cross-file pivot in the whole corpus.
*.winmdfiles dropped in a user-writable directory next to a StoreInstaller-signed EXE.- WinGet
msstoremanifests whoseInstallerUrlhost doesn’t match the publisher’s declared domain, or resolves into a known bulletproof-hosting range. - Native DLLs exporting the full MI-provider set (
MI_Main,GetProviderClassID, etc.) where every export is a one-line stub — that shape has no legitimate reason to exist. - A process whose imports contain nothing managed loading
mscoree.dllwith no child process created (CLR-hosting-in-place, as ineec6fb4f’s secondary path). - A JScript
ActiveScriptEventConsumerbound to aWin32_LocalTime-polling__EventFilter— the specific WMI persistence shape used by the WebSocket RAT.
10. Recommendations
- Report to Microsoft (MSRC/Partner Center abuse): product IDs
XPDNW909QJ8Z9Rand, pending confirmation,xpdcjdx0gjh2bj; publisherVIACHESLAV; and the fact that Microsoft’s own CDN is mirroring the malicious installer while the actor’s origin is down. - Block
pdf-editore[.]com,evangelicool[.]com,myslimwave[.]com,64.94.85.16,64.94.84.0/23. Do not block Microsoft Store or CDN hosts — they’re carrying legitimate traffic alongside this. - Revoke/report all seven abused certificates in section 2 to their issuing CAs if not already revoked.
- Re-run dynamic capture with an unfiltered, longer-window trace to observe the MSI actually executing and the Go loader actually beaconing to a live C2 — this is the single biggest confidence gap in the investigation (section 11).
11. Analysis Limitations
Stated plainly, because several of the connections above are inferred rather than observed executing:
- The MSI-to-Go-loader-to-stager handoff has never been observed executing end-to-end. The live dynamic capture’s evidence window ends before the MSI runs. Everything from the installer’s drop behavior onward is reconstructed from static analysis of each stage individually, not from watching one process hand off to the next.
eec6fb4f’s link to the WebSocket RAT is a strong static hypothesis, not a confirmed one. TheConsoleApp2.Program::Mainclass-name match is exact, but nothing here shows the CLR-hosting path actually being taken at runtime. Confirming it needs either a debugger on the CLR-loader call, or a sinkholedmyslimwave[.]comto see what it actually serves.GetCurrentDomain/CreateRoute/GetBSCRPCURLs’s exact behavior is unconfirmed. Whether the embedded ETH2 deposit-contract literal is a clipper target, a routing constant, or incidental dead code needs a debugger session againste203208aorf1711b81.RunMeElevated’s exact elevation moniker/CLSID is unconfirmed.api.exe’s call shape matches, but the specific COM object being abused for auto-elevation hasn’t been isolated.stage3_payload.dll’s real logic is still opaque. ConfuserEx’s method-body encryption needsde4dotunder Flare-VM to strip before a meaningful decompile is possible; that wasn’t available for this pass.- The x86 installers’ actual MSI database was never decompressed. The high-entropy region past the CAB, for any of the six installers, would show the real install sequence and any custom-action DLLs beyond stock Advanced Installer behavior.
b7b4d20f(PDF Municipal.exe) and89c1bb04(T2Auth Bastion.exe) have no matching counterpart binary yet identified in this corpus to complete their installer-to-final-stage pairing.- The AdPayWorks chain’s exact topology is unconfirmed. The ordering
860fc154 -> eec6fb4f -> 603264cbin section 2 — installer directly to the shared beacon to the Go/Wails lure, rather than the beacon being fetched by the lure’s own toolkit later — would revise the chain diagram in the preface if verified, but it currently rests on shared MalwareBazaar campaign tagging plus the code-level correlation in section 6.2, not a confirmed drop relationship.
Static analysis covered all 20 files in this set: PE and MSI structure, Go symbol recovery via debug/gosym, and full decompilation of the native and .NET stager cluster. One live capture against the actual Microsoft Store listing supplied the network evidence in section 3 — the Store’s own CDN, WinGet’s manifest, and the actor’s unreachable origin were all observed directly, not inferred. The MSI-to-loader-to-stager handoff was not observed executing; section 11 states exactly which links in the chain are inference rather than direct evidence.