typeanalysisfamilyacrstealerconfidencehighcreated2026-07-28updated2026-07-28infostealermalware-familygolangsigningobfuscation
SHA-256: 7620884e50fd7741417ecdb81b41f7c7d9452b89d6905a837ad30a7bc8dc9969

acrstealer: 7620884e — Go 1.25.4 sibling, blizzard-tecnica.com cert, bridge to lummastealer cluster

Ninth confirmed ACR Stealer sibling. Notable deltas from the prior eight: compiled with Go 1.25.4 (not 1.26.2), and signed with a Let's Encrypt R12 certificate for blizzard-tecnica.com — the same certificate chain already seen across the lummastealer cluster. This is the first confirmed bridge between the ACR and Lumma clusters via shared signing infrastructure, suggesting a common builder, certificate reseller, or operator overlap.

Executive Summary

Go 1.25.4 PE32 infostealer with randomized main.* function names, a 0x3d600-byte encrypted payload blob decoded via multi-pass byte-transform, and PRNG-seeded C2 resolution. Signed blizzard-tecnica.com / R12. Four RT_ICON resources. No static C2. Static-only (CAPE skipped — no Windows guest). ^[file.txt] ^[rabin2-info.txt] ^[pefile.txt]

What It Is

Attribute Value
SHA-256 7620884e50fd7741417ecdb81b41f7c7d9452b89d6905a837ad30a7bc8dc9969
Size 2,556,040 bytes (2.6 MB)
Format PE32 executable (GUI) Intel 80386, 7 sections ^[file.txt]
Compiler Go 1.25.4 (build ID present in strings) ^[strings.txt:1616]
Module path rjVxxnjkTTMPaie ^[strings.txt:5964]
main.* functions 106 randomized identifiers (e.g., main.ngeqcu, main.rygqtugg, main.hcqwhi) ^[strings.txt]
Subsystem Windows GUI (0x2) ^[pefile.txt]
Entry point 0x72560 (runtime.main → main.main) ^[pefile.txt]
.text entropy 6.206873 ^[pefile.txt]
Stripped No (.symtab retained, 0x19950 bytes) ^[pefile.txt]
Timestamp 0x0 (null, stripped) ^[pefile.txt]
ASLR / DEP Enabled (DllCharacteristics=0x8140) ^[pefile.txt]

Build / RE

Toolchain

  • Go 1.25.4 — one minor version behind the go1.26.2 used by the eight prior ACR siblings. This suggests either an older build or a deliberate toolchain downgrade. ^[strings.txt:1616] ^[strings.txt:3256]
  • CGO_ENABLED=0 — single IAT (kernel32.dll, 44 imports), no C runtime dependencies. Standard Go static binary for Windows. ^[pefile.txt]
  • -trimpath=true — source paths reduced to rjVxxnjkTTMPaie/main.go; no absolute developer paths. ^[strings.txt:5964]

Signing

  • Authenticode certificate embedded at overlay offset 0x26F800, size 2184 bytes. ^[pefile.txt] ^[binwalk.txt]
  • CN=blizzard-tecnica.com, issuer=CN=R12 (Let's Encrypt R12 intermediate). ^[openssl output from cert extraction]
  • This is a new certificate rotation — the eight prior ACR siblings used me.muz.li / R13 (also Let's Encrypt). The blizzard-tecnica.com / R12 chain is identical to that observed across six lummastealer siblings (040e0d76, 90d54589, 7b74bea7, fa41d6b4, and two others). This constitutes a cross-cluster certificate overlap.

Obfuscation

  • Randomized module path: rjVxxnjkTTMPaie (16 chars, mixed-case alphanumeric). Poisons Go dependency graphs and hinders attribution. ^[strings.txt:5964]
  • Randomized function names: 106 main.* identifiers with no semantic meaning. Hinders capa-style behavioural clustering. ^[strings.txt]
  • No external packer: .text entropy ~6.2, well below packed thresholds. Obfuscation is compile-time only. ^[pefile.txt]

Resources

  • .rsrc section contains 4 RT_ICON entries (~114 KB inferred from section size 0x1BE60) plus 1 RT_GROUP_ICON. ^[pefile.txt] ^[python resource scan]
  • Binwalk identifies a 256×256 PNG at offset 0x2687E8 inside .rsrc. ^[binwalk.txt]
  • Social-engineering masquerade via rich icon suite (standard for this cluster; some siblings omit .rsrc entirely).

Anti-analysis

  • Null PE timestamp: TimeDateStamp=0x0 — deliberate stripping to prevent time-based clustering. ^[pefile.txt]
  • No static C2: No IP, domain, URL, or Telegram handle found in strings. C2 is fully runtime-resolved via PRNG. ^[strings.txt (exhaustive grep)]

Decompiled Behavior

main.main (sym.main.main @ 0x48cfa0) performs the following sequence: ^[r2:sym.main.main]

  1. Seeds PRNG with time.Now().UnixNano() via math_rand.NewSource() → math_rand._rngSource_.Seed(). ^[r2:sym.main.main]
  2. Draws two Intn random values (ranges 0x1868f and 0x320) — likely iteration counts or array offsets for the decoder. ^[r2:sym.main.main]
  3. Calls sym.main.sywgper (0x48a870) — a short routine built around math.Sin() and floating-point transforms. Appears to generate an internal key/angle value used downstream. ^[r2:sym.main.sywgper]
  4. Calls sym.main.hcqwhi (0x48afe0) — the primary payload decoder.

sym.main.hcqwhi (0x48afe0) decompilation shows: ^[r2:sym.main.hcqwhi]

  • Allocates a large stack frame (esp -= 0xf6144).
  • Copies a 0x3d600-byte encrypted blob from .rdata (0x4cc83c) into a local buffer. ^[r2:sym.main.hcqwhi @ 0x48b001]
  • Calls sym.main.zpoevktxpftiri (0x489810) — the multi-pass byte-transform decoder. Operates on the copied blob in-place.
  • The decoder performs at least five distinct passes over the buffer:
    • Pass 1: per-index arithmetic (0x35 multiplier, 0x4d4873ed / 0x54741fac constants, XOR, subtraction, left-shifts). ^[r2:sym.main.zpoevktxpftiri]
    • Pass 2: byte-swap pairs ([i] ↔ [i+1]). ^[r2:sym.main.zpoevktxpftiri]
    • Pass 3: subtract edx >> 8 from each byte. ^[r2:sym.main.zpoevktxpftiri]
    • Pass 4: XOR with edx and index. ^[r2:sym.main.zpoevktxpftiri]
    • Subsequent passes (observed in later hcqwhi blocks) involve Float64()-driven transforms with constants 0x3fe0000000000000, 0x4010000000000000, 0x3fa999999999999a, 0x4049000000000000, 0x4059000000000000, 0x4034000000000000, 0x3f847ae147ae147b, 0x408f400000000000, 0x4014000000000000. ^[r2:sym.main.hcqwhi]
  • After decoding, hcqwhi calls sym.main.ngeqcu and sym.main.rygqtugg — these are the post-decode execution routines, likely performing VirtualAlloc + memcpy + CreateThread or reflective PE injection. The constant 0x3000 (MEM_RESERVE|MEM_COMMIT) and 0x40 (PAGE_EXECUTE_READWRITE) appear as arguments to a VirtualAlloc-like wrapper inside hcqwhi. ^[r2:sym.main.hcqwhi @ 0x48b0b4]
  • hcqwhi also calls time.Now() and math_rand._Rand_.Float64() repeatedly during the transform, confirming the PRNG dependency.

This is the same multi-pass byte-transform decoder and custom in-memory PE parser pattern documented in ACR sibling d5655568 and the Lumma siblings 90d54589 / fa41d6b4. ^[entities/acrstealer.md] ^[entities/lummastealer.md]

C2 Infrastructure

None statically present. Exhaustive string analysis finds no IP, domain, URL, Telegram handle, Discord webhook, or SMTP credential. ^[strings.txt (multiple grep passes)]

C2 is inferred to be resolved at runtime after the payload blob is decoded, consistent with the PRNG-seeded pattern documented across this cluster. The net/http and crypto/tls packages are statically linked (standard Go runtime strings), but no http.Client or tls.Config call sites are visible without dynamic execution. ^[strings.txt:1542] ^[strings.txt:1545]

Interesting Tidbits

  • Go version regression: Prior eight ACR siblings were go1.26.2; this sample is go1.25.4. Either the builder was pinned to an older toolchain, or this build predates the 1.26.2 upgrade. The Lumma cluster also uses go1.25.4, strengthening the bridge hypothesis. ^[entities/acrstealer.md] ^[entities/lummastealer.md]
  • Certificate bridge: First ACR sample to carry blizzard-tecnica.com / R12 instead of me.muz.li / R13. The blizzard-tecnica.com domain is also seen across six Lumma siblings. Shared infrastructure, not independent actors. ^[openssl cert extraction]
  • Four icons retained: Unlike ACR sibling f93d8b79 (stripped .rsrc) or Lumma siblings d5647efd/e03dd36f (no .rsrc), this build keeps the icon suite. Builder has a toggle. ^[pefile.txt]
  • Capa/floss failure: Neither tool produced usable output on this host during the initial triage pass (capa missing signatures; floss not installed). This binary would benefit from re-analysis once the triage station is repaired. ^[capa.txt] ^[floss.txt]

How To Mess With It (Homelab Replication)

Goal: Reproduce the behavioural fingerprint (Go static PE32, randomized module path, null timestamp, signed with a self-signed or Let's Encrypt cert, PRNG-seeded payload decode).

  1. Toolchain: Install Go 1.25.4 on Windows or cross-compile from Linux with GOOS=windows GOARCH=386 CGO_ENABLED=0.
  2. Build flags: go build -trimpath=true -ldflags="-s -w" (note: -s strips symtab; omit if you want .symtab like this sample).
  3. Randomize: Use a script to generate a 16-char random module path (go mod init <rand>) and rename all main.* functions to random alphanumeric strings.
  4. Timestamp: Use a PE editor or rsrc to zero the TimeDateStamp field.
  5. Signing: Obtain a Let's Encrypt certificate (e.g., via certbot for a throwaway domain) and sign the PE with osslsigncode or signtool.
  6. Decoder: Implement a multi-pass byte transform seeded from time.Now().UnixNano() — the constants observed are 0x4d4873ed, 0x54741fac, 0x35, 0x61, plus the floating-point constants listed above.
  7. Verification: Run capa (once signatures are installed) and strings on your reproducer. The strings output should show go1.25.4, a random module path, ~100 randomized main.* names, and standard Go runtime strings. Capa should hit create thread, allocate RWX memory, resolve API by hashing (if you implement the fused-string pattern).

Deployable Signatures

YARA rule

rule ACR_Stealer_Go1254_BlizzardCert
{
    meta:
        description = "ACR Stealer / Lumma cluster Go 1.25.4 signed PE with blizzard-tecnica.com cert overlap"
        author = "PacketPursuit"
        date = "2026-07-28"
        sha256 = "7620884e50fd7741417ecdb81b41f7c7d9452b89d6905a837ad30a7bc8dc9969"
    strings:
        $go_ver = "go1.25.4" ascii
        $mod_path = /[A-Za-z0-9]{12,20}\/main\.go/ ascii
        $main_rand = /main\.[A-Za-z]{6,20}/ ascii
        $blizzard_cn = "blizzard-tecnica.com" ascii
        $r12_issuer = "CN=R12" ascii
        $r13_issuer = "CN=R13" ascii
        $prng_seed = "math/rand" ascii
        $net_http = "net/http" ascii
        $crypto_tls = "crypto/tls" ascii
        $null_ts = { 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 }
    condition:
        uint16(0) == 0x5A4D and
        $go_ver and
        #main_rand > 50 and
        ($blizzard_cn or $r12_issuer or $r13_issuer) and
        $prng_seed and
        $net_http and
        $crypto_tls and
        filesize < 5MB
}

Sigma rule (process creation)

title: ACR Stealer / Lumma Go Static Binary Execution
logsource:
    category: process_creation
    product: windows
detection:
    selection:
        - ImageLoaded|contains:
            - 'rjVxxnjkTTMPaie'
        - CommandLine|contains:
            - 'rjVxxnjkTTMPaie'
    # Generic behavioural fingerprint
    behaviour:
        - CommandLine|re:
            - '(?i)\.exe$'
        # Parent is explorer or user-initiated; child does rapid DLL enumeration
        # followed by network connections within 30s
    condition: selection or behaviour
falsepositives:
    - Unknown
level: high

IOC list

Type Value Note
SHA-256 7620884e50fd7741417ecdb81b41f7c7d9452b89d6905a837ad30a7bc8dc9969 This sample
Certificate CN blizzard-tecnica.com Let's Encrypt R12
Certificate issuer CN=R12 Let's Encrypt R12 intermediate
Module path rjVxxnjkTTMPaie Randomized per build
Go version go1.25.4 Build toolchain
File size ~2.5 MB Typical for this cluster
.rsrc Present (4 icons) Builder toggleable
.symtab Present Not stripped
PE timestamp 0x0 Null/stripped

Behavioural fingerprint statement

This binary is a Go 1.25.4 static PE32 (CGO_ENABLED=0) with a randomized module path and ~100 randomized main.* function names. It carries an Authenticode certificate (CN=blizzard-tecnica.com, issuer=R12). On execution, it seeds the Go math/rand PRNG with time.Now().UnixNano(), draws random integers, then performs a multi-pass floating-point and arithmetic byte-transform on a ~0x3d600-byte embedded payload blob. The decoded payload is staged into RWX memory (VirtualAlloc with 0x3000|0x40) and executed. No C2 infrastructure is hardcoded; network contact is established only after runtime decoding. The .rsrc section contains four icon resources used for social-engineering masquerade. The PE timestamp field is zeroed.

Detection Signatures

Capability ATT&CK ID Evidence
PRNG-seeded string decoding T1027.002 main.main seeds math_rand with time.Now().UnixNano() ^[r2:sym.main.main]
Obfuscated files or information T1027 Multi-pass byte-transform decoder in zpoevktxpftiri ^[r2:sym.main.zpoevktxpftiri]
Reflective code loading T1620 VirtualAlloc RWX + decoded payload execution in hcqwhi ^[r2:sym.main.hcqwhi]
Data collection T1005 Inferred from family behaviour and crypto/tls + net/http linkage ^[strings.txt]
Exfiltration over C2 channel T1041 Inferred from family behaviour; no static C2 confirmed ^[strings.txt]
Masquerading T1036.005 Signed PE with 4 RT_ICON resources ^[pefile.txt]
Null timestamp T1070.004 TimeDateStamp=0x0 ^[pefile.txt]

References

Provenance

Analysis based on static artefacts gathered 2026-05-26 and re-analysed 2026-07-28 with radare2 (rabin2-info.txt, r2 decompilation at analysis level 2). Capa and floss failed during initial triage (missing signatures / missing binary). CAPE dynamic analysis skipped — no Windows guest available. Certificate chain extracted via Python pefile + openssl pkcs7. All claims cite source file or r2 function address.