typeanalysisfamilylummastealerconfidencemediumcreated2026-05-31updated2026-05-31infostealermalware-familygolangsigningobfuscationpec2exfiltration
SHA-256: e03dd36f22e24a323f8db11ba3a220786ea14c5617538b5433911e5a6d1f66a3

lummastealer: e03dd36f — x64 sibling, fraudulent cert, runtime API decoding

Second observed lummastealer sibling: PE32+ x64, same self-signed CN=www.sjabr.org certificate as the founding PE32 sample, still no .rsrc section, and a runtime string-decoder that fuses DLL and API names into indivisible blobs. No CAPE detonation available; static-only.

What It Is

  • SHA-256 e03dd36f22e24a323f8db11ba3a220786ea14c5617538b5433911e5a6d1f66a3 ^[file.txt:1]
  • Filename sunwukongs.exe (social-engineering masquerade) ^[metadata.json]
  • 7.0 MB PE32+ x86-64, 8 sections, Windows GUI subsystem ^[file.txt:1] ^[rabin2-info.txt]
  • Compiled Go (lang: go, default 1970-01-01 Go timestamp) ^[rabin2-info.txt]
  • No .rsrc section (VirtualAddress 0x0, Size 0x0) ^[pefile.txt:249-251]
  • Authenticode certificate at RVA 0x6BDA00, CN www.sjabr.org ^[pefile.txt:255-257] ^[strings.txt:10834]
  • Minimal IAT: only kernel32.dll imported directly ^[pefile.txt:292-347]

How It Works

Cluster sibling; shared build fingerprint documented at golang-stealer-build-pattern and lummastealer. Deltas for this sample:

Architecture shift. Prior sibling d5647efd was GOARCH=386; this binary is amd64 (0x8664 machine type) ^[pefile.txt:36]. The builder is cross-platform.

Runtime API resolution via fused string blobs. sym.main.rxzsirwk constructs string slices from .rdata blobs that concatenate DLL names with API names: kernel32.dllVirtualAllocGetTempPathWinvalid_slothost_is_downillegal_seek... ^[r2:sym.main.rxzsirwk @ 0x140089ce0] ^[strings.txt:1615]. sym.main.lkezaikuw slices these blobs by offset, converts the subrange to a Go string via sym.main.xhqsnoekoztspb, and loads the module via syscall.LoadLibrary ^[r2:sym.main.lkezaikuw @ 0x140087e80] ^[r2:sym.main.xhqsnoekoztspb @ 0x140088620]. The result is that static tools see no discrete VirtualAlloc string; it only emerges at runtime after slicing.

RNG-driven C2 decoding. sym.main.main seeds math/rand with time.Now, then loops drawing Int63 values and normalizing them to [0,1) with floating-point operations ^[r2:sym.main.main @ 0x14008b900]. The RNG state is likely fed into a string-transform or table-index routine to recover C2 URLs. No hardcoded domains, IPs, or Telegram handles found in the entire binary.

Decompiled Behavior

  • Entry (sym.main.main @ 0x14008b900) — initializes a math/rand source, seeds from wall-clock time, then iteratively calls the RNG and performs a type assertion on a closure stored at 0x1403967a0. The loop exits only when a floating-point comparison fails, suggesting PRNG-derived branching ^[r2:sym.main.main @ 0x14008b900].
  • String decoder (sym.main.rxzsirwk @ 0x140089ce0) — allocates Go objects for a table of fused DLL+API strings using runtime.newobject and runtime.gcWriteBarrier1. Each entry pairs a length prefix with a pointer into .rdata. ^[r2:sym.main.rxzsirwk @ 0x140089ce0].
  • Module loader (sym.main.lkezaikuw @ 0x140087e80) — receives index pairs into the table, validates slice bounds, substrings the fused blob, and issues syscall.LoadLibrary. A secondary dword table at offset +0x10 may cache ordinals or resolved addresses. ^[r2:sym.main.lkezaikuw @ 0x140087e80].
  • Slice helper (sym.main.xhqsnoekoztspb @ 0x140088620) — pure byte-range-to-Go-string converter via runtime.slicebytetostring. ^[r2:sym.main.xhqsnoekoztspb @ 0x140088620].

No anti-debug, anti-VM, or timing-based evasion observed in these functions.

C2 Infrastructure

None observed statically. The RNG loop and string-decoder strongly imply runtime-resolved C2 URLs. Network packages present: net/http, crypto/tls, crypto/x509 ^[strings.txt:1615]. No IPs, domains, or Telegram handles.

Interesting Tidbits

  • OpenCTI label collision: tagged sunwukong, but the sunwukong entity page describes an unrelated MSVC x64 loader. This is a label collision, not code reuse. ^[metadata.json]
  • Double build ID: two Go build IDs (wQ9dsajz... and 5oEZqR5...) appear in .rdata, possibly from a vendored module or merged build cache. ^[strings.txt:9,2503]
  • Binwalk false positives: mcrypt 2.2 encrypted data at 0x2B67AB is high-entropy .rdata noise; no second payload or genuine encryption envelope found. ^[binwalk.txt]

How To Mess With It

Replication guidance identical to the golang-stealer-build-pattern cluster: Go >=1.25, GOARCH=amd64 GOOS=windows CGO_ENABLED=0, -ldflags="-s -w -trimpath". To reproduce the fused-string anti-analysis, concatenate fmt.Sprintf("%s%s", "kernel32.dll", "VirtualAlloc") variants into a single large constant and slice at runtime.

Deployable Signatures

YARA:

rule Lummastealer_x64_sibling_e03dd36f {
    meta:
        description = "Lummastealer x64 sibling, fraudulent CN=www.sjabr.org cert, no .rsrc"
        sha256 = "e03dd36f22e24a323f8db11ba3a220786ea14c5617538b5433911e5a6d1f66a3"
        author = "PacketPursuit"
        date = "2026-05-31"
    strings:
        $cert_cn = "www.sjabr.org" ascii wide
        $go1 = "go:buildinfo" ascii
        $go2 = "runtime.main.func2" ascii
        $fused1 = "kernel32.dllVirtualAlloc" ascii
        $fused2 = "shell32.dllCreateFileW" ascii
    condition:
        uint16(0) == 0x5A4D and
        pe.number_of_sections == 8 and
        pe.data_directories[pe.IMAGE_DIRECTORY_ENTRY_RESOURCE].virtual_address == 0 and
        $cert_cn and
        2 of ($go1, $go2) and
        1 of ($fused1, $fused2)
}

Sigma:

title: Lummastealer x64 sibling execution
logsource:
    category: process_creation
    product: windows
detection:
    selection:
        CommandLine|contains: 'sunwukongs.exe'
    hashes:
        sha256: e03dd36f22e24a323f8db11ba3a220786ea14c5617538b5433911e5a6d1f66a3
    condition: selection or hashes
level: high

IOCs:

  • SHA-256: e03dd36f22e24a323f8db11ba3a220786ea14c5617538b5433911e5a6d1f66a3
  • Filename: sunwukongs.exe
  • Certificate CN: www.sjabr.org

Behavioral fingerprint: A 64-bit Go static binary with zero resource section and a fraudulent Authenticode certificate. On launch it seeds math/rand from wall-clock time, then iteratively decodes fused DLL+API name strings from .rdata, resolves them via syscall.LoadLibrary, and prepares network I/O via net/http and crypto/tls. No hardcoded C2 is present; endpoints are derived at runtime.

Detection Signatures (capa)

capa signatures were not installed during this run and produced no results ^[capa.txt]. Inferred capabilities: load-library, resolve-api-at-runtime, use-crypto-tls, use-http-client.

References

Provenance

  • File type: file.txt (file(1))
  • PE header / sections / imports: pefile.txt (pefile 2024.x)
  • Strings: strings.txt (strings -n 8)
  • Go build metadata: rabin2-info.txt (radare2 rabin2 -I)
  • Decompilation: radare2 pdc on sym.main.main, sym.main.rxzsirwk, sym.main.lkezaikuw, sym.main.xhqsnoekoztspb
  • Certificate extraction: Python pefile raw read at RVA 0x6BDA00