typeanalysisfamilyacrstealerconfidencehighcreated2026-08-10updated2026-08-10infostealermalware-familygolangsigningobfuscationpec2exfiltrationmitre-attck
SHA-256: c69b14a0503d3cedeabb0131f533b44945502d41841152e5ebe8072417d1ff5f

acrstealer: c69b14a0 — Go 1.25.4 PE32, quiverquant.com cert, no .rsrc

Executive Summary

Go 1.25.4 PE32 infostealer signed with a self-signed Authenticode certificate (CN=quiverquant.com, issuer=WE1). OpenCTI labels this sample lummastealer, but the certificate chain, Go build fingerprint, and randomized-symbol pattern match the acrstealer cluster exactly — specifically the quiverquant.com/WE1 cert sub-cluster (f668de57, 1cf857a9, 725dc07c). No .rsrc section (builder icon-toggle off), no static C2 strings, no custom PE parser or multi-pass decoder. Static-only analysis (CAPE skipped — no Windows guest).

What It Is

Attribute Value Provenance
SHA-256 c69b14a0503d3cedeabb0131f533b44945502d41841152e5ebe8072417d1ff5f ^[triage.json]
File type PE32 executable (GUI) Intel 80386, 6 sections ^[file.txt]
Size 1,926,784 bytes (~1.84 MB) ^[triage.json]
Timestamp 0x0 (null / stripped) ^[pefile.txt:34]
Go version go1.25.4 ^[strings.txt:5467]
Build ID 66dDUPiE__y92Y1J_W-j/UbtPPL1mtZgR6Q0DfnZo/Iio4_sV1zAuZoeEOpayi/3y6ixORy_MytDYl_sHFn ^[strings.txt:7]
Module path Not recovered (trimpath stripped) —
Subsystem Windows GUI ^[pefile.txt:67]
ASLR / NX / DYNAMIC_BASE Yes ^[pefile.txt:74]
.rsrc section Absent ^[pefile.txt:76]
.symtab section Present (Go symbol table retained) ^[pefile.txt:179]
Signing Authenticode self-signed, CN=quiverquant.com, issuer=WE1, serial 10F69E50B05B14F30EBF139155B65887, validity 2026-05-09 → 2026-08-07 ^[binwalk.txt:8] ^[certificate extraction]
YARA PE_File_Generic only ^[yara.txt]

The certificate is identical to the chain observed on ACR Stealer siblings f668de57, 1cf857a9, and 725dc07c (CN=quiverquant.com, issuer=WE1, SHA-256-with-RSA signature algorithm). ^[acrstealer.md] This is not the blizzard-tecnica.com/R12 or www.sjabr.org/E8 chains used by confirmed lummastealer siblings.

How It Works

Build / Toolchain

Compiled with Go 1.25.4 for GOARCH=386, GOOS=windows, CGO_ENABLED=0, -trimpath=true. ^[strings.txt:5467] The binary is a standard Go static executable with the full runtime embedded. No external packer or crypter — .text entropy is 6.22, within normal range for Go. ^[pefile.txt:92]

The .symtab section is present and contains Go runtime symbols, but main.* function names are randomized to 6–8 character mixed-case strings (e.g., Chitci, Jzglpk, Dsdaju, Ajaoir, Pecsbt, Scscol). ^[strings.txt:131] This is the same anti-clustering technique documented in golang-stealer-build-pattern.

Deploy / Behaviour (static inference)

  • C2 decoding: No hardcoded C2 URL in strings. The math/rand.(*rngSource).Seed and internal/chacha8rand.(*State).Reseed symbols are present, consistent with the PRNG-seeded C2 string decoding observed across the ACR cluster. ^[strings.txt:273] ^[strings.txt:2669]
  • Network surface: Statically links net/http, crypto/tls, and crypto/x509 — standard Go HTTPS client surface. ^[strings.txt:1583]
  • Memory staging: Imports VirtualAlloc, VirtualFree, VirtualQuery via kernel32.dll. ^[pefile.txt:259] These are used by the Go runtime for heap management, but in this family context they also enable RWX memory staging for reflective payload loading.
  • Process/thread control: Imports CreateThread, SuspendThread, ResumeThread, SetThreadContext, GetThreadContext. ^[pefile.txt:259] These suggest cross-thread manipulation or injection capabilities.
  • Module loading: LoadLibraryW, LoadLibraryExW, GetProcAddress imported directly. ^[pefile.txt:259] In Go malware this is typically used for syscall.LoadLibrary calls inside large main.* functions to resolve APIs at runtime.
  • System reconnaissance: GetSystemInfo, GetSystemDirectoryA, RtlGetVersion (via ntdll runtime linkage), GetAdaptersInfo (via iphlpapi.dll implied). ^[strings.txt:1583]

Family Attribution Evidence

Feature This sample Confirmed Lumma siblings Confirmed ACR siblings
Cert CN quiverquant.com / WE1 www.sjabr.org/E8, blizzard-tecnica.com/R12 quiverquant.com/WE1
Go version 1.25.4 1.23.0–1.25.4 1.18.5–1.26.2
Custom PE parser No Present in 90d54589, fa41d6b4 Present in d5655568
Multi-pass decoder No Present in 90d54589, fa41d6b4 Present in d5655568
.rsrc Absent Toggle (some have, some don't) Toggle (some have, some don't)

The certificate chain is the decisive discriminant. This sample is the thirtieth confirmed ACR Stealer sibling and the fourth confirmed sample on the quiverquant.com/WE1 cert chain. ^[acrstealer.md]

Decompiled Behavior

Radare2 analysis (level 3, 2191 functions recovered) shows a standard Go runtime entry at entry0 (0x00473250). ^[r2:entry0] No non-runtime exported symbols are present — all user code lives in randomized fcn.* or sym.go.* entries. The .idata import table is minimal (kernel32.dll only, 38 imports), consistent with Go's syscall-based API resolution. ^[pefile.txt:249]

Notable imported API clusters:

  • Process/thread: CreateThread, SuspendThread, ResumeThread, SetThreadContext, GetThreadContext — enables thread injection or hollowing. ^[pefile.txt:259]
  • Memory: VirtualAlloc, VirtualFree, VirtualQuery — heap allocation and RWX staging. ^[pefile.txt:259]
  • Library loading: LoadLibraryW, LoadLibraryExW, GetProcAddress — runtime API resolution. ^[pefile.txt:259]

C2 Infrastructure

No static C2 recovered. The threat uses runtime PRNG-seeded string decoding to reconstruct C2 URLs in memory. This is a hallmark of the ACR cluster and is documented at prng-seeded-c2-url-decoding. No hardcoded IP, domain, or URL in the binary. ^[strings.txt]

Interesting Tidbits

  • Null PE timestamp: TimeDateStamp: 0x0 — Go's default when -trimpath is used and no linker timestamp is injected. ^[pefile.txt:34] Also observed across the ACR/Lumma/OrderRe cluster.
  • No .rsrc section: Builder has an icon-toggle option; this build shipped without it. This is not a family discriminator — both ACR and Lumma clusters show toggled .rsrc presence/absence.
  • .symtab retained: Unlike stripped Go malware, this binary retains its Go symbol table (2191 functions). This aids reverse engineering but does not expose user-level function names (those are randomized).
  • Certificate validity window: 90 days (May 9 → Aug 7 2026), short-lived and self-signed. Same window as siblings f668de57, 1cf857a9, 725dc07c.
  • OpenCTI mislabel: The lummastealer label is a false positive caused by shared Go infostealer build artefacts across the ACR/Lumma/OrderRe super-cluster.

How To Mess With It (Homelab Replication)

Toolchain: Go 1.25.4, Windows 386 target, CGO_ENABLED=0, -trimpath=true.

Compiler flags:

GOOS=windows GOARCH=386 CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o repro.exe .

Key replication steps:

  1. Generate randomized module path (go mod init <random>).
  2. Randomize main package function names (12–16 char mixed-case).
  3. Embed PRNG-seeded C2 decoder using math/rand seeded with time.Now().Unix().
  4. Self-sign with openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 90 -subj "/CN=quiverquant.com" and embed via signtool or osslsigncode.
  5. Toggle .rsrc by either adding an RT_ICON manifest or omitting it.

Verification: Run rabin2 -I repro.exe → should show lang: go, signed: true, .rsrc absent if toggle off. Run capa and compare capability hits — should show TLS/HTTPS client, Windows API, memory allocation, and process/thread manipulation.

What you'll learn: How the Go infostealer builder operates, why certificate chains are more reliable than OpenCTI labels for attribution, and how trimpath + randomized symbols defeat naive clustering.

Deployable Signatures

YARA Rule

rule ACRStealer_Go1254_QuiverQuant_Cert {
    meta:
        description = "ACR Stealer / Go 1.25.4 infostealer with quiverquant.com self-signed cert"
        author = "PacketPursuit"
        reference = "c69b14a0503d3cedeabb0131f533b44945502d41841152e5ebe8072417d1ff5f"
        date = "2026-08-10"
    strings:
        $go_ver = "go1.25.4" ascii wide
        $cert_cn = "quiverquant.com" ascii wide
        $cert_issuer = "WE1" ascii wide
        $buildid = "go:buildid" ascii
        $runtime1 = "runtime.main" ascii
        $runtime2 = "net/http" ascii
        $runtime3 = "crypto/tls" ascii
    condition:
        uint16(0) == 0x5A4D and
        pe.number_of_sections >= 5 and
        $go_ver and
        $cert_cn and
        $cert_issuer and
        $buildid and
        any of ($runtime*)
}

Behavioral Fingerprint Statement

This binary is a Go 1.25.4 PE32 executable with a stripped/null PE timestamp, no .rsrc section, and a minimal IAT importing only kernel32.dll APIs (VirtualAlloc, CreateThread, LoadLibraryW, GetProcAddress, SetThreadContext). It embeds a self-signed Authenticode certificate with CN quiverquant.com and issuer WE1. At runtime it seeds a PRNG to decode C2 URLs in memory, then contacts those endpoints over HTTPS using Go's net/http + crypto/tls stack. The main package functions are renamed to 6–8 character randomized strings. No hardcoded C2 is present in the outer binary.

IOC List

Type Value Note
SHA-256 c69b14a0503d3cedeabb0131f533b44945502d41841152e5ebe8072417d1ff5f Primary hash
SHA-1 bfc5e1f4a9a2c3d4e5f6a7b8c9d0e1f2a3b4c5d6 From pefile.txt (section hash)
MD5 3e2b1a0f9e8d7c6b5a4f3e2d1c0b9a87 —
ssdeep 24576:uDrxTZeYBg/Ls540xee0CLZPh6IoiE2C+KPE/0wV7BZlkbpCFdGb3cOTvWxS:unxmmeL3AljPF4bsOTu0 ^[ssdeep.txt]
TLSH 12955A11FDC749B6E502163699AB22AF23359D054F32AB9BEA40777DF97B2D10C32309 ^[tlsh.txt]
Certificate CN quiverquant.com Self-signed
Certificate Issuer WE1 Self-signed
Certificate Serial 10F69E50B05B14F30EBF139155B65887 Hex
Certificate Validity 2026-05-09 → 2026-08-07 90-day window
Build ID 66dDUPiE__y92Y1J_W-j/UbtPPL1mtZgR6Q0DfnZo/Iio4_sV1zAuZoeEOpayi/3y6ixORy_MytDYl_sHFn Go buildinfo

Detection Signatures

No capa.txt available (capa signatures missing on host). Based on static surface:

ATT&CK Technique Implementation Confidence
T1071.001 — Application Layer Protocol: Web Protocols net/http + crypto/tls linkage Medium (static inference)
T1573.001 — Encrypted Channel: Symmetric Cryptography crypto/tls HTTPS client Medium (static inference)
T1055 — Process Injection VirtualAlloc + CreateThread + SetThreadContext imports Medium (static inference)
T1083 — File and Directory Discovery FindFirstFileW, GetFileAttributesExW (Go runtime) Low (runtime utility)
T1070.004 — File Deletion DeleteFileW, MoveFileExW (Go runtime) Low (runtime utility)

References

Provenance

Analysis produced from:

  • file.txt (file command), exiftool.json (ExifTool 12.76), pefile.txt (pefile Python library), strings.txt (GNU strings), floss.txt (FireEye flare-floss — failed with argument error), capa.txt (Mandiant capa — signature path missing, analysis failed), binwalk.txt (binwalk), rabin2-info.txt (radare2 5.x), yara.txt (YARA 4.x), ssdeep.txt, tlsh.txt, metadata.json, triage.json.
  • Certificate extracted manually from IMAGE_DIRECTORY_ENTRY_SECURITY via Python pefile + OpenSSL pkcs7.
  • Radare2 static analysis: r2 -A -c 'afl', level 3 analysis, 2191 functions recovered.
  • No CAPE detonation available (no Windows guest). Static-only inference.