typeanalysisfamilyacrstealerconfidencehighcreated2026-05-29updated2026-05-29infostealercompilersigninggolangc2
SHA-256: 16a4344dcdb51bd043a360dd954bbee9ed5d497dce177e3114740598cc90d78b

acrstealer: 16a4344d — Signed Go 1.26.2 PE32, module hlHtIOAoWQhvCrI, cert CN=me.muz.li

Executive Summary

Third observed sibling of the ACR Stealer family. A signed PE32 executable compiled with Go 1.26.2 (GOARCH=386, CGO_ENABLED=0) carrying a randomized module path (hlHtIOAoWQhvCrI) and a fresh Authenticode certificate (CN=me.muz.li, issuer=R13). No CAPE detonation was available, so behavior is inferred from static artefacts, radare2 decompilation, and family metadata. The build fingerprint is identical to siblings 6871848b and c577c6c8; the deltas are the module name, the signing certificate, and the per-build randomized function names. See acrstealer cluster page for shared TTPs.

What It Is

Attribute Value
SHA-256 16a4344dcdb51bd043a360dd954bbee9ed5d497dce177e3114740598cc90d78b
Filename gXjgD.exe ^[metadata.json]
Size 2,569,344 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]
Module hlHtIOAoWQhvCrI (devel) — randomized per-build ^[strings.txt:1676]
Build ID v-vYN8mN5wTA6BixdLFM/fRHeHYLSb99LOUUFj161/KgcsfglCAUcW9FES2o1s/A9tx8U4EAXj7mL3kEWeG ^[strings.txt:8]
Signed Authenticode certificate embedded at offset 0x272C00, size 0x880 ^[pefile.txt] ^[rabin2-info.txt]
Cert subject CN = me.muz.li
Cert issuer CN = R13
Cert serial 05:6d:b7:5a:d9:aa:9b:d0:a6:fe:9c:04:4a:fc:c9:b0:7c:b5
Cert validity Not Before: 2026-05-07 19:29:00 UTC — Not After: 2026-08-05 19:28:59 UTC
Resources .rsrc section with 4 icons up to 256×256 PNG (social-engineering masquerade) ^[pefile.txt] ^[binwalk.txt]
IAT kernel32.dll only (45 imports); Go runtime resolves the rest via LoadLibraryExW/GetProcAddress ^[pefile.txt]

Family attribution is from OpenCTI labels (acrstealer, td-distributedruntimehub-surf, signed, 5-252-155-72) ^[triage.json].

How It Works

Static decompilation of main.main (radare2, 0x0049a570) shows the same control-flow pattern as siblings 6871848b and c577c6c8:

  1. Stack growth check — calls sym.runtime.morestack_noctxt if the goroutine stack is exhausted ^[r2:sym.main.main].
  2. PRNG seeding — constructs a math/rand.Source, then calls sym.math_rand._rngSource_.Seed with values derived from the current timestamp (constants 0x3d1a0000 and 0xa1b203eb appear in the seeding arithmetic) ^[r2:sym.main.main].
  3. Randomised dispatch — invokes sym.math_rand._Rand_.Intn twice (args 0x1868f and 0x320) to generate indices, then calls main.mjkcvkwfzcpokrp and main.fwyztmsofq ^[r2:sym.main.main].
  4. No direct syscall or API strings in the decompiled body; all Win32 interaction goes through Go's syscall package wrappers.

The randomized main package function names (main.xbmrmupjziby, main.nnwcdpv, main.hilbvfdm, main.pgpsqubceedoqsp, main.hfbgmpn, main.lntwfjsxmteajs, main.Gwurod, main.rnoqukiyrkdtcy, main.sjvwvlgend, main.mgwsrbbjcfukcd, main.tjpbjfrqdlk, main.fvutue, main.jqprvlqxjmdis, main.nvapmwasav, main.mzpcazrsgoib, main.xhvpznikendmw, main.mjkcvkwfzcpokrp, main.uvvnnhclhdvke, main.jbbhdkp, main.usnwnr, main.idpegu, main.lsnculvfrohpkd, main.vybymhla, main.fwyztmsofq) ^[r2:sym.main.main] are meaningless alphanumeric strings, confirming build-time name randomisation seen across this family.

Standard-library linkage implies runtime use of crypto/tls, net/http, crypto/x509, and crypto/rsa ^[strings.txt:1603], but no hardcoded C2 URL or credential-target strings were found in .text or .rdata. C2 configuration is likely decoded at runtime using the seeded PRNG, consistent with sibling behaviour.

No dynamic execution data is available — CAPE skipped this sample because no Windows guest was online ^[dynamic-analysis.md].

Decompiled Behavior

Radare2 decompilation of sym.main.main (address 0x0049a570) reveals:

// Stack growth check
sym.runtime.morestack_noctxt()

// PRNG seeding with timestamp-derived constants
sym.math_rand._rngSource_.Seed(..., 0x3d1a0000, 0xa1b203eb)

// Randomised index generation
sym.math_rand._Rand_.Intn(..., 0x1868f)
sym.math_rand._Rand_.Intn(..., 0x320)

// Obfuscated dispatch
sym.main.mjkcvkwfzcpokrp()
sym.main.fwyztmsofq()

^[r2:sym.main.main]

The constants 0x3d1a0000 and 0xa1b203eb are the same seeding salts observed in sibling c577c6c8 ^[/intel/analyses/c577c6c87bd8a143598000e63d53c8e09b4f7d7a8b8c5de36f7479b5f4411274.html], suggesting a shared source template rather than per-build randomisation of the seed algorithm itself.

C2 Infrastructure

Type Value Source
IP 5.252.155.72 OpenCTI label ^[triage.json]
Domain laserlogdnsop.icu OpenCTI label ^[triage.json]

These IOCs were not found as plaintext strings in the binary. They are consistent across all three siblings, indicating a shared C2 infrastructure.

Interesting Tidbits

  • Identical build toolchain, different module name and cert: The build fingerprint (go1.26.2, CGO_ENABLED=0, -trimpath=true) is byte-for-byte identical to siblings 6871848b and c577c6c8; only the randomized module path (hlHtIOAoWQhvCrI) and the signing certificate differ. This is strong evidence of an automated build pipeline that randomises the module name and re-signs per compilation. ^[strings.txt:1673-1676]
  • Certificate details: The DER-encoded PKCS#7 blob at 0x272C00 parses cleanly. Subject CN=me.muz.li, issuer CN=R13, 90-day validity. The issuer name "R13" is not a recognised public CA; this is likely a self-signed or reseller certificate acquired via a low-reputation signing service. ^[binwalk.txt] ^[pefile.txt]
  • No UPX or external packer: .text entropy 6.19, .rdata 7.22. The Go compiler's native obfuscation (trimpath + randomised names) is sufficient. ^[pefile.txt]
  • Capa signatures missing: The triage pipeline's capa run failed because the default signature path was not installed ^[capa.txt]; no ATT&CK capability map is available.
  • FLOSS failure: The floss pipeline mis-invoked the tool (argument parsing error) and produced no decoded strings ^[floss.txt]. All string evidence comes from raw strings and radare2 iz.

How To Mess With It (Homelab Replication)

To reproduce the build fingerprint:

# Go 1.26.2 on Windows or cross-compile from Linux
go version  # must report go1.26.2

# Create a random module name (15–20 chars)
MOD=$(tr -dc 'A-Za-z0-9' </dev/urandom | head -c 18)
mkdir /tmp/$MOD && cd /tmp/$MOD
go mod init $MOD

# Write a minimal main.go that seeds math/rand with time.Now()
cat > main.go <<'EOF'
package main

import (
    "fmt"
    "math/rand"
    "time"
)

func main() {
    r := rand.New(rand.NewSource(time.Now().UnixNano()))
    fmt.Println(r.Intn(0x1868f))
    fmt.Println(r.Intn(0x320))
}
EOF

# Build with exact flags observed in the cluster
GOARCH=386 GOOS=windows CGO_ENABLED=0 go build -trimpath -buildmode=exe -o repro.exe

# Verify
r2 -e bin.cache=true -qc 'iz~go1.26.2; iz~trimpath' repro.exe
pefile.py repro.exe  # check for security directory

Verification step: Run capa repro.exe (with signatures installed) and compare to the expected Go infostealer capability set. Since capa is not available in this environment, compare entropy values and section names to sibling samples.

What you learn: How Go's -trimpath and CGO_ENABLED=0 produce a deterministic PE32 footprint that is trivially recognisable yet obscures source paths, and how a self-signed Authenticode blob adds a false legitimacy signal.

Deployable Signatures

YARA

rule ACRStealer_Go126_Signed_PE32
{
    meta:
        description = "ACR Stealer — Go 1.26.2 signed PE32 with randomized module path"
        author = "PacketPursuit"
        date = "2026-05-29"
        hash = "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
    condition:
        uint16(0) == 0x5A4D and
        $go_build and
        $trimpath and
        $cgo_off and
        #mod_path >= 1 and
        pe.number_of_signatures > 0 and
        pe.number_of_resources >= 2
}

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 resolves kernel32 APIs via LoadLibraryExW/GetProcAddress, seeds a PRNG with the current time using constants 0x3d1a0000/0xa1b203eb, then invokes two obfuscated main functions. Network IOCs include 5.252.155.72 and laserlogdnsop.icu.

IOC List

Type Value Source
SHA-256 16a4344dcdb51bd043a360dd954bbee9ed5d497dce177e3114740598cc90d78b triage.json
Filename gXjgD.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]
Cert Serial 05:6d:b7:5a:d9:aa:9b:d0:a6:fe:9c:04:4a:fc:c9:b0:7c:b5 manual DER extraction ^[pefile.txt]
Module path hlHtIOAoWQhvCrI strings.txt:1676
Build ID v-vYN8mN5wTA6BixdLFM/fRHeHYLSb99LOUUFj161/KgcsfglCAUcW9FES2o1s/A9tx8U4EAXj7mL3kEWeG strings.txt:8

Sigma Rule

title: ACR Stealer Go Binary Network Connection
logsource:
  category: network_connection
  product: windows
detection:
  selection:
    Initiated: 'true'
    DestinationIp:
      - '5.252.155.72'
    DestinationHostname:
      - 'laserlogdnsop.icu'
  filter_go:
    Image|endswith:
      - '.exe'
    CommandLine|contains:
      - 'gXjgD'
  condition: selection or filter_go
falsepositives:
  - Unknown
level: high

Detection Signatures

Technique ATT&CK ID Evidence
Execution via signed PE T1203 Authenticode certificate present ^[pefile.txt]
Data Encoding T1132 PRNG-seeded string decode (inferred) ^[r2:sym.main.main]
Exfiltration Over C2 Channel T1041 crypto/tls + net/http linkage ^[strings.txt]
Ingress Tool Transfer T1105 Signed executable masquerade ^[pefile.txt]

Capa was unavailable during triage; the map above is manually inferred from static artefacts.

References

  • OpenCTI artifact ID: fbd89450-367f-4f6f-ab7b-9d4aeb9ce7f4 ^[triage.json]
  • Sibling analysis: /intel/analyses/6871848bb724a184e393a734c9de9c17c41da1f26359755696f0df40685c42f2.html
  • Sibling analysis: /intel/analyses/c577c6c87bd8a143598000e63d53c8e09b4f7d7a8b8c5de36f7479b5f4411274.html
  • Cluster entity: acrstealer
  • Build pattern: golang-stealer-build-pattern

Provenance

Analysis derived from static artefacts generated by the PacketPursuit triage pipeline:

  • file.txtfile v5.44
  • exiftool.json — ExifTool 12.76
  • pefile.txt — pefile 2024.8.26
  • strings.txtstrings (GNU binutils)
  • rabin2-info.txt / radare2 decompilation — radare2 5.9.8
  • binwalk.txt — binwalk v2.4.3
  • capa.txt — capa v9.1.0 (signatures missing, run failed)
  • floss.txt — flare-floss v3.1.1 (mis-invoked, no output)
  • Certificate extraction — manual dd + openssl pkcs7/x509