b3ffa06a189a3454d74ee20e24d7c6a4c49673c360d9fc7cc0423e263f0fcbf8lummastealer: b3ffa06a — Go 1.25.4 PE32, 14-icon .rsrc suite, invalid certificate table, PRNG sleep gate
Executive Summary
Go 1.25.4 PE32 infostealer with 130 randomized main.* functions, a 14-icon .rsrc suite, and an invalid Authenticode certificate table that points beyond EOF. Shares the PRNG sleep gate (800–1120 s) and dense namespace with the Lumma cluster, but carries no valid signing — neither the blizzard-tecnica.com R12 chain nor the ACR quiverquant.com chain. Static-only; CAPE skipped (no Windows guest).
What It Is
- File: PE32 executable (GUI) Intel 80386, 7 sections, 2.94 MB ^[file.txt]
- Compiler: Go 1.25.4+,
GOARCH=386,GOOS=windows,CGO_ENABLED=0,-trimpath=true^[strings.txt:1663-1671] - Module path:
LkYepTgpfGoTJPv(randomized, 16-char mixed-case) ^[strings.txt:1663] - Build ID:
BVrnoOrAVVaYdOlHLAPK/cOUBfNGrV1efNoya0Gh2/IGI22km3b5jkeMNXyJTd/7zDSX1Qeu_ZisY8QI7oe^[strings.txt:8] - PE timestamp: null (1970-01-01 00:00:00) in all headers and resource directories ^[pefile.txt:34,274,328,339,350,370,390,410,430,451]
- Signing: none valid. Security directory VA =
0x46DA00(4,643,328), file size = 2,944,978 — points beyond EOF. rabin2 flagsInvalid certificate table/signed: false. ^[rabin2-info.txt:1,28] ^[pefile.txt:232-234] - Resources:
.rsrcpresent (~57 KB). 14 RT_ICON entries (16×16, 32×32, 64×64, 128×128, 256×256 RGBA PNG) plus RT_GROUP_ICON. ^[binwalk.txt:8-17] ^[pefile.txt:333,445] - Function count: 130 randomized
main.*names (densest Lumma sibling observed). ^[strings.txt]
How It Works
This is a cluster sibling of lummastealer. The threat logic is concealed behind standard Go obfuscation patterns documented on the entity page. Distinctive features of this sample:
-
Broken certificate table — unlike siblings
040e0d76through46e32500which carry theblizzard-tecnica.com/ R12 Let's Encrypt chain, this sample has a security directory that references memory outside the file. No valid Authenticode. This may represent a builder misconfiguration, an unsigned test build, or deliberate stripping. -
14-icon
.rsrcsuite — larger than the typical 4-icon set seen on040e0d76and7b74bea7. The builder clearly has an icon-toggle with variable quantity. -
PRNG sleep gate —
main.mainseedsmath/randwith hardcoded 64-bit constants (0xd7b17f80upper,0xa1b203eblower,0x3d1a0000delta), then sleepsIntn(0x320) + 0x320= 800–1120 seconds before network activity. ^[r2:sym.main.main @ 0x49d820] This matches the gate observed in siblings46e32500and142261c674f9. -
No static C2 — consistent with the cluster's runtime C2 decoding via prng-seeded-c2-url-decoding. No domain, IP, or URL strings recovered.
-
Process manipulation imports —
VirtualAlloc,CreateThread,ResumeThread,SetThreadContext,GetThreadContext,LoadLibraryW,LoadLibraryExW,GetProcAddressall imported statically via syscall stubs. ^[strings.txt:6053-6075]
Decompiled Behavior
Ghidra was not run (static-only pipeline). radare2 level-2 analysis recovered 2191 functions. Entry point is standard _rt0_386 Go runtime bootstrap (0x473250). main.main (0x49d820) performs:
- Allocate
math/randRNG source and seed with composite constants. - Call
main.skwogikfupwtfn(likely string decoder / API resolver). - Sleep via
math/rand.(*Rand).Intn(0x320) + 0x320. - Call
main.qxvfumjqexrbi(likely C2 connector / beacon). - Additional PRNG-derived timing loops feeding
main.sbkoaiqhtm,main.iqtypn, andmain.szqhkacm(payload stages).
The repeated pattern — seed → decoder → sleep → beacon → stage — is identical to siblings 46e32500 and 142261c674f9. ^[r2:sym.main.main]
C2 Infrastructure
No static C2 recovered. C2 is decoded at runtime via PRNG transform, consistent with prng-seeded-c2-url-decoding. No hardcoded domains, IPs, or URLs in strings.
Interesting Tidbits
- Certificate table beyond EOF is unusual. Most Lumma siblings are signed (self-signed
www.sjabr.orgor Let's Encrypt R12blizzard-tecnica.com). This sample may be an unsigned builder output or a post-processing strip. - 14 icons is the largest
.rsrcsuite in the Lumma cluster so far; previous max was ~8. - 130
main.*functions is the densest randomized namespace observed in this cluster, exceeding142261c674f9(92 functions). - capa and floss both failed on this sample — capa missing signatures, floss argument-parsing error. Reinforces the need for manual Go string analysis.
How To Mess With It (Homelab Replication)
Build a comparable Go binary:
go version # need 1.25.4+
export GOOS=windows GOARCH=386 CGO_ENABLED=0
go build -trimpath -ldflags="-s -w -H=windowsgui" .
Target a binary with:
- 100+ short randomized function names in
mainpackage math/randseed with hardcoded 64-bit composite- Sleep gate
rand.Intn(800) + 800 syscall.LoadLibrary/syscall.GetProcAddressfor runtime API resolution- Optional: embed multiple PNG icons via
go:embed+github.com/akavel/rsrc
Verification: run rabin2 -I reproducer.exe — should show lang: go, signed: false, stripped: false, and a dense sym.main.* namespace.
Deployable Signatures
YARA rule
rule LUMMA_Go1254_PRNG_SleepGate {
meta:
description = "LummaStealer Go 1.25.4+ PE32 with PRNG sleep gate and dense randomized main namespace"
author = "PacketPursuit"
date = "2026-08-26"
sha256 = "b3ffa06a189a3454d74ee20e24d7c6a4c49673c360d9fc7cc0423e263f0fcbf8"
strings:
$go_build = "go:buildid"
$mod_path = /path\t[a-zA-Z]{16}/
$trimpath = "build\t-trimpath=true"
$cgo_off = "build\tCGO_ENABLED=0"
$goarch = "build\tGOARCH=386"
$goos = "build\tGOOS=windows"
$seed1 = { 80 7F B1 D7 }
$seed2 = { EB 03 B2 A1 }
$virtalloc = "VirtualAlloc"
$createthread = "CreateThread"
$resume = "ResumeThread"
$setctx = "SetThreadContext"
$getctx = "GetThreadContext"
condition:
uint16(0) == 0x5A4D and
6 of ($go_build, $mod_path, $trimpath, $cgo_off, $goarch, $goos) and
2 of ($seed1, $seed2) and
3 of ($virtalloc, $createthread, $resume, $setctx, $getctx) and
#mod_path >= 1
}
Behavioral fingerprint
This binary is a Go 1.25.4 PE32 with a null PE timestamp, 100+ randomized main.* functions, and standard Go runtime strings. On execution it seeds math/rand with hardcoded constants, sleeps 800–1120 seconds, then resolves APIs via syscall.LoadLibrary/GetProcAddress and initiates HTTPS C2. No hardcoded network indicators are present in the file.
IOC list
| Indicator | Value | Type |
|---|---|---|
| SHA-256 | b3ffa06a189a3454d74ee20e24d7c6a4c49673c360d9fc7cc0423e263f0fcbf8 | hash |
| Build module | LkYepTgpfGoTJPv |
string |
| Go build ID | BVrnoOrAVVaYdOlHLAPK/... |
string |
| Sleep gate | 800–1120 s via math/rand.Intn(0x320)+0x320 |
behavior |
| PRNG seed constants | 0xd7b17f80, 0xa1b203eb, 0x3d1a0000 |
constants |
| Certificate status | Invalid table (VA beyond EOF) | anomaly |
Detection Signatures
- capa: failed (missing signature path) ^[capa.txt]
- Manual ATT&CK mapping:
- T1055 — Process Injection (CreateThread, SetThreadContext, VirtualAlloc) ^[strings.txt:6053-6069]
- T1027 — Obfuscated Files or Information (PRNG C2 decoding, randomized names)
- T1497 — Virtualization/Sandbox Evasion (time-based sleep gate)
- T1071 — Application Layer Protocol (HTTPS via
net/http+crypto/tls) ^[strings.txt:1587]
References
- lummastealer — family entity page
- golang-stealer-build-pattern — shared build artefacts
- prng-seeded-c2-url-decoding — runtime C2 decoding technique
- fused-string-api-decoding — runtime API resolution obfuscation
Provenance
file.txt— file(1) outputstrings.txt— Go strings and runtime artefacts (line numbers cited)rabin2-info.txt— radare2 binary header summary (rabin2 -I)pefile.txt— pefile.py parsed headers and resource directorybinwalk.txt— embedded PNG icon extraction- radare2 level-2 analysis +
pdgdecompilation ofsym.main.mainat0x49d820 - capa v7.1.0 (failed — missing signature path) ^[capa.txt]
- floss v3.1.1 (failed — argument parsing error) ^[floss.txt]