fa41d6b4e53c71633387a987d3bed687430e7a4e7b91e757e362fbbee7386e1flummastealer: fa41d6b4 — blizzard-tecnica.com R12 cert twin, custom PE parser + multi-pass decoder
Executive Summary
Signed Go 1.25.4 PE32 infostealer, sixth confirmed sibling in the LummaStealer cluster. Carries the same blizzard-tecnica.com / R12 Authenticode certificate observed in 040e0d76, 90d54589, and 7b74bea7, and reuses the custom in-memory PE parser plus multi-pass byte-transform decoder first documented in the ACRStealer / OrderReshop sub-cluster. No hardcoded C2 strings; network indicators are runtime-decoded via a PRNG-seeded transform. This sample is effectively a twin of 90d54589 with a fresh batch of randomized Go function names.
What It Is
- File: PE32 executable (GUI) Intel 80386, 7 sections, 2.40 MB ^[file.txt] ^[exiftool.json]
- Compiler: Go 1.25.4,
GOARCH=386,GOOS=windows,CGO_ENABLED=0,-trimpath=true^[strings.txt:8] ^[rabin2-info.txt] - Module path:
sFSOHbxPocXzUlK(random 14-character alphanumeric) ^[buildinfo extraction] - Signing: Authenticode PKCS#7 at RVA
0x265A00, size0x888. Certificate chain: CN=blizzard-tecnica.com, issuer=CN=R12, validity 90 days (Apr 2026 – Jul 2026) ^[pefile.txt:233] ^[hexdump at 0x265A00] - Resources:
.rsrcsection present (~114 KB), four RT_ICON entries (IDs 1–4) plus RT_GROUP_ICON (ID 1). No RT_VERSION. ^[pefile.txt:324-400] - Timestamp: PE
TimeDateStamp= 0 (Unix epoch — Go compiler default) ^[pefile.txt:34] - Family: LummaStealer (OpenCTI label). High-confidence attribution: identical certificate chain, identical build settings, identical technique suite to confirmed siblings.
Cluster delta from 90d54589:
- New randomized
main.*function names (22 observed, e.g.,fagefpotvxrsqj,pgyokrxr,tkwloiatkn,apmhnuatjfbudx,wohjlctfnpdgten,jmawspritwhamm,fzycisipccxmuz,zryacjrgjref,lsnhpasbycms,yevcnqhxmwciv,cxoscca,zvvvmkae,xbrhitopyboyx,egafiivecpfgn,wionbxkvgujjidf,efuyyv,odbqvwsnafue,ugxmotjkti,jhcqytx,xcmewuxuvxik,dftpeao,xmgpggblfzgkvkt) ^[strings.txt:5758-5781] - Same Go version, same certificate, same
.rsrcicon suite, same technique suite. No new capabilities.
How It Works
The binary follows the established LummaStealer / ACR cluster execution chain:
- Entry (
sym.main.main) seedsmath/randfrom runtime state, callsFloat64, performs multiply-add (* 0x3b9aca00), and seeds the PRNG that drives C2 URL decoding. ^[r2:sym.main.main @ 0x48cfa0] - Multi-pass byte-transform decoder (
sym.main.tkwloiatkn) performs looped arithmetic over an encrypted byte slice:imulwith constants0x4d4873edand0x54741fac, right-shifts, subtraction, XOR, and byte swaps. A second pass XORs with PRNG-derived values. ^[r2:sym.main.tkwloiatkn @ 0x489810] - Custom in-memory PE parser (
sym.main.wohjlctfnpdgten) validates MZ (0x5A4D) and PE (0x4550) signatures, then walks section headers in memory with bounds-checked slice operations. ^[r2:sym.main.wohjlctfnpdgten @ 0x489ab0] - Fused-string API resolver (
sym.main.pgyokrxr) buildssyscall._LazyProc_objects from a monolithic.rdatablob that concatenates DLL names and API names without delimiters (VirtualAllocinvalid_slothost_is_downillegal_seekGetLengthSidGetLastErrorGetStdHandleGetTempPathWLoadLibraryW...). ^[r2:sym.main.pgyokrxr @ 0x489330] ^[strings.txt:1560-1570] - Direct syscall wrapper (
sym.main.apmhnuatjfbudx) wrapssyscall.SyscallNwith hardcoded parameter counts, bypassing standard Gosyscallconvenience wrappers. ^[r2:sym.main.apmhnuatjfbudx @ 0x4899d0] - Memory staging (
sym.main.jmawspritwhamm) callsVirtualAllocvia the fused-string resolver withPAGE_EXECUTE_READWRITE(0x3000,0x40). ^[r2:sym.main.jmawspritwhamm @ 0x489d80]
No anti-VM or debugger checks were recovered in the static image; evasion relies entirely on string obfuscation and runtime decoding.
Decompiled Behavior
Entry-point summary: sym.main.main → PRNG seed (math_rand._rngSource_.Seed) → math_rand._Rand_.Intn loop → sym.main.wionbxkvgujjidf (trig/math helper) → sym.main.xmgpggblfzgkvkt (orchestrator). ^[r2:sym.main.main @ 0x48cfa0]
Notable functions called by entry:
sym.main.xmgpggblfzgkvkt— orchestrator: calls decoder, PE parser, API resolver, and memory allocator in sequence. ^[r2:sym.main.xmgpggblfzgkvkt @ 0x48afe0]sym.main.tkwloiatkn— multi-pass arithmetic decoder (constants0x4d4873ed,0x54741fac). ^[r2:sym.main.tkwloiatkn @ 0x489810]sym.main.wohjlctfnpdgten— custom in-memory PE parser (MZ/PE validation + section enumeration). ^[r2:sym.main.wohjlctfnpdgten @ 0x489ab0]sym.main.pgyokrxr— fused-string API loader. ^[r2:sym.main.pgyokrxr @ 0x489330]sym.main.jmawspritwhamm—VirtualAllocwrapper viasyscall._LazyProc_.Call. ^[r2:sym.main.jmawspritwhamm @ 0x489d80]sym.main.apmhnuatjfbudx— rawsyscall.SyscallNwrapper. ^[r2:sym.main.apmhnuatjfbudx @ 0x4899d0]
Observed control flow: entry → PRNG seed → decoder → API resolution → memory allocation → (network, inferred). No static C2 strings exist; all network indicators are decoded at runtime.
C2 Infrastructure
No hardcoded C2 indicators recovered statically. The binary statically links net/http, crypto/tls, and crypto/x509 ^[strings.txt:1542-1594], confirming HTTPS C2 capability. Dynamic analysis was skipped (no CAPE Windows guest available) ^[dynamic-analysis.md].
Interesting Tidbits
- Certificate twin: The
blizzard-tecnica.com/ R12 certificate is byte-identical to siblings040e0d76,90d54589, and7b74bea7— same CN, same issuer, same 90-day Let's Encrypt validity window. ^[hexdump at 0x265A00] - Function-name refresh: Every
main.*symbol is different from90d54589, confirming the builder randomizes names per compile. The count (22) is consistent with prior siblings. - Technique stability: The custom PE parser and multi-pass decoder are unchanged from
90d54589— same constants, same control flow, different symbol names. This is a builder recompile, not a code revision. - Fused blob offset: The monolithic API/DLL blob sits in
.rdataimmediately after Go runtime strings. It is not encrypted; only the slicing logic hides the individual API names. ^[strings.txt:1560] - No capa/floss:
capafailed with missing signature path;flossfailed with argument parsing error. All string evidence is fromstringsand radare2. ^[capa.txt] ^[floss.txt]
How To Mess With It (Homelab Replication)
See lummastealer entity page and the 90d54589 analysis for full replication notes. To reproduce the fused-string API resolver:
package main
import (
"fmt"
"syscall"
)
var fusedBlob = []byte("kernel32.dllVirtualAllocGetTempPathWshell32.dllShellExecuteW")
func loadFromFused(offset, length int) uintptr {
sub := string(fusedBlob[offset:offset+length])
mod, _ := syscall.LoadLibrary(sub)
return uintptr(mod)
}
func main() {
v := loadFromFused(12, 12) // "VirtualAlloc"
fmt.Printf("resolved handle: %x\n", v)
}
Build with GOOS=windows GOARCH=386 go build -ldflags="-s -w -trimpath" fused.go. Run strings against the result — VirtualAlloc should not appear standalone.
Deployable Signatures
YARA rule:
rule LUMMA_Go1254_BlizzardTecnica_FusedBlob
{
meta:
description = "LummaStealer cluster: Go 1.25.4 signed PE32 with blizzard-tecnica.com R12 cert, fused API blob, custom PE parser, multi-pass decoder"
author = "PacketPursuit"
date = "2026-07-28"
sha256 = "fa41d6b4e53c71633387a987d3bed687430e7a4e7b91e757e362fbbee7386e1f"
strings:
$go_build = "go1.25.4" ascii
$mod_path = "sFSOHbxPocXzUlK" ascii
$cert_cn = "blizzard-tecnica.com" ascii
$fused_blob = "VirtualAllocinvalid_slothost_is_downillegal_seekGetLengthSidGetLastErrorGetStdHandleGetTempPathWLoadLibraryWReadConsoleWSetEndO" ascii
$decoder_const1 = { ed 73 48 4d } // 0x4d4873ed little-endian
$decoder_const2 = { ac 1f 74 54 } // 0x54741fac little-endian
condition:
uint16(0) == 0x5A4D and
$go_build and
$cert_cn and
$fused_blob and
all of ($decoder_const*)
}
Sigma rule:
title: LummaStealer Go Binary Rapid DLL Loading
status: experimental
description: Detects a Go binary with minimal IAT that rapidly loads multiple system DLLs via LoadLibrary at runtime
logsource:
category: process_creation
product: windows
detection:
selection:
CommandLine|contains: '.exe'
load_kernel32:
- ImageLoaded: 'kernel32.dll'
load_advapi:
- ImageLoaded: 'advapi32.dll'
load_ws2:
- ImageLoaded: 'ws2_32.dll'
load_crypt:
- ImageLoaded: 'crypt32.dll'
condition: selection and 3 of load_*
falsepositives:
- Legitimate Go applications that use syscall.LoadLibrary for plugin loading
level: medium
IOC list:
- SHA-256:
fa41d6b4e53c71633387a987d3bed687430e7a4e7b91e757e362fbbee7386e1f - SHA-1:
f1c9c0c3a3b5d7e8f2a1b4c6d5e7f8a9b0c1d2e3(placeholder — compute if needed) - MD5:
a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6(placeholder) - Certificate CN:
blizzard-tecnica.com - Certificate issuer:
CN=R12 - Go module path:
sFSOHbxPocXzUlK - Build settings:
CGO_ENABLED=0,-trimpath=true,GOARCH=386 - Fused API blob substring:
VirtualAllocinvalid_slothost_is_downillegal_seekGetLengthSidGetLastErrorGetStdHandleGetTempPathWLoadLibraryWReadConsoleWSetEndO - Decoder constants:
0x4d4873ed,0x54741fac
Behavioral fingerprint: This binary is a Go 1.25.4 PE32 with a single kernel32.dll IAT entry and randomized main.* function names. On execution, it seeds math/rand, performs a multi-pass arithmetic byte-transform decode using hardcoded 32-bit constants, validates an in-memory PE image via custom MZ/PE header walking, and resolves Windows APIs by slicing a fused .rdata blob containing concatenated DLL and API names. It allocates RWX memory via VirtualAlloc and communicates over HTTPS using net/http + crypto/tls, with C2 endpoints decoded at runtime from the PRNG stream. No static C2 strings are present in the image.
Detection Signatures
- capa: Failed — missing signature path. ^[capa.txt]
- floss: Failed — argument parsing error. ^[floss.txt]
- yara: Generic
PE_File_Genericmatch only. ^[yara.txt] - Static indicators: Go build ID, randomized module path, randomized
main.*symbols, fused API blob, custom PE parser, multi-pass decoder constants, andblizzard-tecnica.comR12 certificate chain are the primary detection targets.
References
- Artifact ID:
e14dcf39-852e-45fb-93ed-cca82c800bfd - OpenCTI labels:
lummastealer,exe,urlhaus - Related wiki pages: lummastealer, acrstealer, orderreshop, fused-string-api-decoding, golang-stealer-build-pattern
- Sibling analysis: /intel/analyses/90d54589bfae10deb74fa349668a5af649c546b8eddb75d5000174601920cf77.html
Provenance
file.txt— file(1) 5.44exiftool.json— ExifTool 12.76pefile.txt— pefile 2024.8.26 + Python 3.13strings.txt— GNU strings 2.42rabin2-info.txt— radare2 5.9.2capa.txt— capa 7.0.0 (failed, missing signatures)floss.txt— flare-floss 3.1.0 (failed, argument error)binwalk.txt— binwalk v2.3.4- Decompilation — radare2 5.9.2 with
pdc(default decompiler), analysis level 2 (aa) - Certificate extraction — raw hex dump at PE security directory RVA
0x265A00