typeanalysisfamilyacrstealerconfidencehighcreated2026-06-09updated2026-06-09infostealercompilersigninggolangc2
SHA-256: d5655568fee9c610139d41d367afc74e768e1c8baf70e37912e9ebeb27b5d411

acrstealer: d5655568 — Fourth signed Go 1.26.2 sibling, custom PE parser + multi-pass decoder

What It Is

Fourth observed sibling of the ACR Stealer cluster. A signed PE32 executable compiled with Go 1.26.2 (GOARCH=386, GOOS=windows, CGO_ENABLED=0, -trimpath=true) carrying a randomized module path (JPYhJIzovpOdAaG) and the same Authenticode certificate (CN=me.muz.li, issuer=R13) seen in sibling 16a4344d ^[strings.txt:1675]. The binary embeds a custom in-memory PE parser and a multi-pass byte-transformation decoder — TTPs previously documented on the related orderreshop entity but now confirmed present in this PE32 acrstealer lineage.

Family attribution is from OpenCTI labels (acrstealer, flur-constzoo-surf, signed, 5-252-155-72) ^[triage.json]. No CAPE detonation was available, so dynamic behaviour is inferred from static artefacts and family metadata ^[dynamic-analysis.md].

Attribute Value
SHA-256 d5655568fee9c610139d41d367afc74e768e1c8baf70e37912e9ebeb27b5d411
Filename hjbk.exe ^[metadata.json]
Size 2,463,360 bytes (2.5 MB)
Type PE32 executable (GUI) Intel 80386, 7 sections ^[file.txt]
Compiler Go 1.26.2, GOARCH=386, GOOS=windows, CGO_ENABLED=0, -trimpath=true ^[strings.txt:1673-1680]
Module JPYhJIzovpOdAaG (devel) — randomized per-build ^[strings.txt:1675]
Build ID PSCioB1MKYaFM9sNgZAa/IOMtzCRaKWar5JHR4EqI/OGOaB66ms6QDBBZz9gzL/QM2VFsMEgGnpAVrhLuk7 ^[strings.txt:8]
Signed Authenticode certificate embedded at offset 0x258e00, size 0x880 ^[pefile.txt] ^[rabin2-info.txt]
Cert subject CN = me.muz.li
Cert issuer CN = R13
Resources .rsrc section with multiple icons (social-engineering masquerade) ^[pefile.txt] ^[binwalk.txt]
IAT kernel32.dll only (45 imports); Go runtime resolves the rest dynamically ^[pefile.txt]

How It Works

Entry Point — PRNG Seeding & Obfuscated Dispatch

Static decompilation of main.main (radare2, 0x0049a590) shows the same entry pattern as siblings 6871848b, c577c6c8, and 16a4344d:

  1. Stack growth checksym.runtime.morestack_noctxt if the goroutine stack is exhausted ^[r2:sym.main.main].
  2. PRNG seeding — constructs a math/rand.Source, then seeds it with timestamp-derived constants 0x3d1a0000 and 0xa1b203eb (byte locations 0x8f56f and 0x8f579 in .text) ^[r2:sym.main.main].
  3. Randomised dispatch — invokes sym.main.tupfnstb and sym.main.kwlgcx after generating indices via math/rand.Intn ^[r2:sym.main.main] ^[ghidra:main.main-0049a590].

Custom In-Memory PE Parser

Function main.immxjegqx (Ghidra, 0x00496fc0) implements an in-memory parser for Microsoft PE headers:

  • Validates the MZ magic 0x5a4d at the candidate base ^[ghidra:main.immxjegqx-00496fc0].
  • Walks the DOS stub to locate the PE signature (0x4550) ^[ghidra:main.immxjegqx-00496fc0].
  • Checks the optional header magic (0x10b for PE32 vs 0x20b for PE32+) and parses section headers accordingly ^[ghidra:main.immxjegqx-00496fc0].
  • Returns section count, image base, entry point RVA, and section header array via out-parameters.

This routine is called from main.kwlgcx, suggesting reflective loading or payload mapping — a capability previously attributed to the orderreshop PE64 branch but now confirmed in this PE32 acrstealer.

Multi-Pass String Decoder

Function main.muwjcdzxjhqlde (Ghidra, 0x00496bb0) performs a multi-pass byte-transformation on embedded ciphertext:

  • XOR with a runtime-derived byte key ^[ghidra:main.muwjcdzxjhqlde-00496bb0].
  • Subtraction of a loop-dependent constant ^[ghidra:main.muwjcdzxjhqlde-00496bb0].
  • Bitwise shifting and pairwise byte swaps within 8-byte blocks ^[ghidra:main.muwjcdzxjhqlde-00496bb0].
  • The outer loop iterates over the source slice, applying the transformations in sequence before writing the result to a newly allocated Go byte slice.

The decoded output is likely C2 URLs, target paths, or API names. No hardcoded plaintext C2 strings were found in .text or .rdata — consistent with runtime decoding.

Dynamic API Resolution

Function main.howhtpulgjucujl (Ghidra, 0x00496350) wraps syscall_LazyProc_Call, the Go runtime mechanism for resolving Win32 APIs via LoadLibraryExW/GetProcAddress ^[ghidra:main.howhtpulgjucujl-00496350]. Called from main.kwlgcx, it bridges the statically-linked kernel32 IAT to additional APIs needed post-decoding.

C2 Infrastructure

  • IP: 5.252.155.72
  • Domain: laserlogdnsop.icu
  • Label: flur-constzoo-surf (OpenCTI campaign tag) ^[triage.json]

These IOCs are not present as plaintext strings in the binary. They are extracted from OpenCTI enrichment labels and are consistent across all four siblings, indicating a shared C2 infrastructure.

Interesting Tidbits

  • Identical certificate to sibling 16a4344d: CN=me.muz.li, issuer=R13, 90-day validity window. This is the first time the same cert has been reused across siblings, suggesting either a bulk signing event or a single purchase from a low-reputation CA. ^[pefile.txt]
  • Custom PE parser is new for this PE32 lineage: Prior acrstealer siblings (6871848b, c577c6c8) did not surface a reflective-loader routine in static analysis. The presence of main.immxjegqx in d5655568 closes the TTP gap with orderreshop and confirms the two families share tooling beyond the compiler flags. ^[ghidra:main.immxjegqx-00496fc0] ^[/intel/analyses/16a4344dcdb51bd043a360dd954bbee9ed5d497dce177e3114740598cc90d78b.html]
  • No UPX or external packer: .text entropy is ~6.19, well below packed thresholds. Obfuscation relies on Go's native mechanisms (-trimpath, randomized names) plus the custom decoder. ^[binwalk.txt]
  • Same PRNG salt constants: The seeding values 0x3d1a0000 and 0xa1b203eb are byte-for-byte identical across all four siblings, confirming a shared source template rather than per-build randomisation of the seed algorithm. ^[r2:sym.main.main] ^[/intel/analyses/6871848bb724a184e393a734c9de9c17c41da1f26359755696f0df40685c42f2.html]

Deployable Signatures

YARA

rule ACRStealer_Go126_Signed_PE32_Reflective
{
    meta:
        description = "ACR Stealer — Go 1.26.2 signed PE32 with custom PE parser and multi-pass decoder"
        author = "PacketPursuit"
        date = "2026-06-09"
        hash1 = "d5655568fee9c610139d41d367afc74e768e1c8baf70e37912e9ebeb27b5d411"
        hash2 = "16a4344dcdb51bd043a360dd954bbee9ed5d497dce177e3114740598cc90d78b"
    strings:
        $go_build  = "go1.26.2" ascii wide
        $mod_path = /path\t[A-Za-z0-9]{12,20}\r?\n/ ascii
        $trimpath = "-trimpath=true" ascii
        $cgo_off  = "CGO_ENABLED=0" ascii
        $mz_check = { 4D 5A }                  // MZ magic checked in-memory
        $pe_magic = { 50 45 00 00 }            // PE\0\0 signature
    condition:
        uint16(0) == 0x5A4D and
        $go_build and
        $trimpath and
        $cgo_off and
        #mod_path >= 1 and
        pe.number_of_signatures > 0 and
        all of ($mz_check, $pe_magic)
}

Behavioral Fingerprint

A signed PE32 executable compiled with Go 1.26 (GOARCH=386, CGO_ENABLED=0, -trimpath=true) whose module path is a random alphanumeric string of 15–20 characters. On execution it seeds a PRNG with the current time using constants 0x3d1a0000 and 0xa1b203eb, then invokes obfuscated main functions that decode strings via XOR-subtraction-shift-swap passes and parse in-memory PE headers for reflective loading. Network IOCs include 5.252.155.72 and laserlogdnsop.icu.

IOC List

Type Value Source
SHA-256 d5655568fee9c610139d41d367afc74e768e1c8baf70e37912e9ebeb27b5d411 triage.json
Filename hjbk.exe metadata.json
IP 5.252.155.72 triage.json (OpenCTI label)
Domain laserlogdnsop.icu triage.json (OpenCTI label)
Cert Subject CN=me.muz.li manual DER extraction ^[pefile.txt]
Cert Issuer CN=R13 manual DER extraction ^[pefile.txt]
Module path JPYhJIzovpOdAaG strings.txt:1675
Build ID PSCioB1MKYaFM9sNgZAa/IOMtzCRaKWar5JHR4EqI/OGOaB66ms6QDBBZz9gzL/QM2VFsMEgGnpAVrhLuk7 strings.txt:8
PRNG salt 1 0x3d1a0000 byte at .text+0x8f56f ^[r2]
PRNG salt 2 0xa1b203eb byte at .text+0x8f579 ^[r2]
Custom parser main.immxjegqx @ 0x00496fc0 Ghidra decompilation
Custom decoder main.muwjcdzxjhqlde @ 0x00496bb0 Ghidra decompilation
Dynamic API main.howhtpulgjucujl @ 0x00496350 Ghidra decompilation

Related

  • See acrstealer cluster page for the full family overview and prior siblings.
  • See orderreshop for the PE64 branch that shares the custom PE parser and decoder TTPs.
  • See golang-stealer-build-pattern for the common Go infostealer build artefacts.