d8a6366c9fbf5a41c82774f1e499aebe1a9bf9b078331f5a2c174ca0785c3b9254e64e: d8a6366c — Go 1.25.9 reflective PE loader, self-signed unscramblex.com, 13-function PRNG decryptor
Executive Summary
Go 1.25.9 PE64+ reflective loader with a PRNG-driven multi-stage payload decryptor. Self-signed Authenticode certificate CN=unscramblex.com. Thirteen randomized main.* functions — a stripped-down variant of the Go loader morph first seen in 018ef44b. No infostealer surface; no browser, crypto, or exfiltration strings. Static-only (CAPE skipped — no Windows guest).
What It Is
- File: PE32+ executable (GUI) x86-64, 8 sections, 1.93 MB ^[file.txt]
- Compiler: Go 1.25.9,
CGO_ENABLED=0,trimpath=true,GOOS=windows,GOARCH=amd64,GOAMD64=v1^[strings.txt:1510-1520] - Build ID:
YPlgVebmwN1vrIfko_PW/L5EZKau57xXoiFJs7kxb/DaomgXQ-haVMc8iRHmEz/O9M77OW2iEhlXOoJrbzv^[strings.txt:9] - Module path:
fkfcQPBhFOUhPHI(randomized) ^[strings.txt:1512] - Signing: Self-signed Authenticode, 4096-bit RSA. Subject CN=
unscramblex.com, issuer CN=E7, validity 2026-04-06 to 2026-07-05. ^[binwalk.txt:4-5] ^[pefile.txt:252-254] - IAT: 44 kernel32.dll imports only —
LoadLibraryW,GetProcAddress,VirtualAlloc,CreateThread, etc. No ws2_32, winhttp, or crypt32 in static IAT. ^[pefile.txt:288-344] - Stripping: Not stripped;
.symtabsection present (95,316 bytes) with 2,219 symbols. Unusual for Go malware — suggests builder does not runstriporgo build -ldflags="-s -w". ^[pefile.txt:218-235] - Packing: None. No UPX, no outer crypter. ^[yara.txt]
- Resources: No
.rsrcsection; no version info, no icon, no masquerade. ^[pefile.txt:245-248] - Timestamp: Zeroed (Thu Jan 1 00:00:00 1970). ^[pefile.txt:34]
How It Works
This sample is a fourteenth confirmed build morph under the 54e64e OpenCTI umbrella. It belongs to the Go reflective PE loader lineage (Morph 12, first seen in 018ef44b), but uses a newer Go toolchain (1.25.9 vs 1.25.4) and a significantly reduced function count (13 randomized main.* functions vs 55 in the prior sibling). The reduced surface suggests either a stripped-down builder configuration or compiler optimization / inlining that collapsed the earlier multi-stage pipeline into fewer functions.
Entry-Point Behavior (static inference from decompilation)
main.main ^[r2:sym.main.main] performs the following:
- PRNG seeding: Computes a seed value from a constant base (
0xdd7b17f80) mixed withtime.Now().UnixNano()viamath_rand._rngSource_.Seed. - Delay gates: Calls
math_rand._Rand_.Intnandmath_rand._Rand_.Float64in loop structures gated byucomisd(floating-point comparison) against hardcoded constants (e.g.,0x3ff0000000000000= 1.0,0x4020000000000000= 8.0). These are time-delay or entropy-accumulation loops. ^[r2:sym.main.main] - Payload decryption: Calls
sym.main.efvsjgrpysok^[r2:sym.main.efvsjgrpysok], the primary decryptor/loader function. This function:- Allocates a large stack frame (
0x71a30bytes). - Copies
0xe200quadwords (≈ 455 KB) from a fixed.rdataoffset (rip + 0x48d10) into the stack buffer — this is the encrypted payload. ^[r2:sym.main.efvsjgrpysok] - Calls
sym.main.ifzkojaandsym.main.pjceupx— likely key-schedule or initialization routines. - Calls
sym.main.gibxwporkamofscwith arguments0x40(PAGE_EXECUTE_READWRITE) and0x3000(MEM_COMMIT | MEM_RESERVE) — aVirtualAllocwrapper. ^[r2:sym.main.efvsjgrpysok] - Calls
sym.main.wmisltgayandsym.main.jzvghmcfnazgg— data-transform routines that operate on the copied payload.wmisltgaycontains word-level XOR/ADD logic with 0xfff masks and shift operations consistent with a stream-cipher or block-cipher round. ^[r2:sym.main.wmisltgay] - Calls
sym.syscall.Syscallwith five arguments — direct Windows native API invocation. ^[r2:sym.main.efvsjgrpysok] - Re-seeds the PRNG with
time.Now().Unix()and enters nested loops that callmath_rand._Rand_.Float64andmath_rand._Rand_.Intnwith constants (e.g.,0x4034000000000000= 20.0,0x402e0000000000000= 15.0) to build or modify the decoded payload structure. ^[r2:sym.main.efvsjgrpysok] - Calls
sym.runtime.growslicerepeatedly — the decrypted payload is being parsed into a Go slice structure, likely a PE header walk or import table rebuild.
- Allocates a large stack frame (
- Execution transfer: Not directly visible in the decompiled
main.main(the function is truncated), but the pattern matches the Morph 12 sequence: decoded payload parsed as a PE image, mapped into RWX memory, and execution transferred viasyscall.Syscallor a Go function pointer call.
Notable Functions
| Function | Role (inferred) |
|---|---|
main.main |
Entry point; PRNG seeding, delay gates, orchestrates decryptor |
main.efvsjgrpysok |
Primary decryptor/loader; copies payload, allocates RWX, transforms data, syscall dispatch |
main.wmisltgay |
Word-level payload transformation (XOR/ADD/SHIFT with 0xfff masks) |
main.jzvghmcfnazgg |
Secondary payload transformation (called after wmisltgay) |
main.ifzkoja |
Key-schedule / decryptor initialization (called before alloc) |
main.pjceupx |
Secondary decryptor initialization (called after ifzkoja) |
main.gibxwporkamofsc |
VirtualAlloc wrapper (0x40, 0x3000 arguments) |
main.xqfxklpdi |
Float arithmetic helper (used in delay gate) |
main.awyhoepgiwsu |
Float arithmetic helper (used in delay gate) |
main.hsksieodze |
String parsing helper (strings.SplitN, strings.TrimSpace, strconv.ParseFloat) |
main.uwzhxrbzqeselt |
Floating-point summation loop (entropy accumulator) |
C2 Infrastructure
No hardcoded network IOCs recovered statically. The payload is decrypted at runtime; any C2 configuration lives inside the encrypted blob. The static IAT contains no Winsock, WinHTTP, or WinInet imports, but the runtime syscall.Syscall surface can resolve any API dynamically. No domains, IPs, URLs, or mutex names found in cleartext. ^[strings.txt]
Interesting Tidbits
- Reduced function count: Only 13
main.*functions vs 55 in018ef44b(Morph 12). This is the smallest-function-count Go loader seen in the54e64ecluster. Likely caused by Go compiler inlining or a stripped-down builder template. ^[strings.txt] .symtabpreserved: The binary retains a full symbol table (95 KB). Most Go malware strips with-ldflags="-s -w". This suggests the builder is either misconfigured or intentionally left symbols to aid debugging/repacking. ^[pefile.txt:218-235]- Certificate CN:
unscramblex.comis a new masquerade domain not seen in prior siblings (previous CNs:WE1,godaddy.com,askart.com,seekingalpha.com,xxx.com). The issuer is bareE7— minimal self-signing template. ^[binwalk.txt] - No infostealer strings: Zero evidence of browser credential theft, cryptocurrency wallet extraction, clipboard hijacking, or Telegram/Discord exfiltration. This is a pure loader, not a stealer. Contrast with Morphs 3, 6, and 9 which are Go infostealers. ^[strings.txt]
- Go 1.25.9: Newer than the 1.25.4 used in Morph 12. The runtime strings contain updated Go 1.25 standard-library artifacts (e.g.,
internal/runtime/atomicgenerics,fips140indicators). ^[strings.txt:1510] - capa/floss failures:
capafailed due to missing signatures directory.flossfailed with argument-parsing error. Both tools require manual re-run with corrected paths. ^[capa.txt] ^[floss.txt]
How To Mess With It (Homelab Replication)
Toolchain: Go 1.25.9, Windows amd64 target, CGO_ENABLED=0, trimpath=true.
Build recipe:
go mod init fkfcQPBhFOUhPHI
go build -ldflags="-H=windowsgui" -o loader.exe main.go
To reproduce the PRNG-driven decryptor pattern:
- Embed a PE payload as a byte slice in
main.go. - Seed
math/randwithtime.Now().UnixNano()mixed with a constant. - Implement a delay gate: loop
rand.Float64()until the value exceeds a threshold (e.g., 0.5). - Implement a word-wise transform: for each 16-bit word, XOR with
rand.Intn(0xfff)and ADD arand.Float64()-derived offset. - Allocate RWX memory with
VirtualAllocviasyscall.Syscall(orgolang.org/x/sys/windows). - Copy decoded payload and transfer execution with
syscall.Syscallto the entry point.
Verification: Run capa on the reproducer — should hit T1620 (reflective code loading) if signatures are installed. Compare strings output to this sample: expect go1.25.9, math/rand, syscall.Syscall, time.Now, and randomized main.* function names.
Deployable Signatures
YARA Rule
rule Go_Reflective_Loader_54e64e_D8A6366C
{
meta:
description = "Go 1.25.x reflective PE loader with PRNG-driven decryptor (54e64e cluster)"
author = "Titus"
date = "2026-09-07"
sha256 = "d8a6366c9fbf5a41c82774f1e499aebe1a9bf9b078331f5a2c174ca0785c3b92"
reference = "raw/analyses/d8a6366c9fbf5a41c82774f1e499aebe1a9bf9b078331f5a2c174ca0785c3b92"
strings:
$go_ver = "go1.25." ascii
$build_id = "Go build ID:" ascii
$trimpath = "build\t-trimpath=true" ascii
$cgo_disabled = "build\tCGO_ENABLED=0" ascii
$mod_rand = "math/rand" ascii
$mod_syscall = "syscall.Syscall" ascii
$mod_time = "time.Now" ascii
$mod_unix = "time.Time.UnixNano" ascii
$main_prefix = "*main." ascii
$runtime_newobj = "sym.runtime.newobject" ascii
condition:
uint16(0) == 0x5a4d and
$go_ver and
$build_id and
$trimpath and
$cgo_disabled and
$mod_rand and
$mod_syscall and
$mod_time and
$mod_unix and
#main_prefix >= 10 and
filesize < 3MB
}
Behavioral Hunt Query (Sigma-like)
title: Go Reflective PE Loader PRNG Decryptor
detection:
selection_pe:
- FileType: PE32+
- Image: '*.exe'
selection_go:
- Strings|contains:
- 'go1.25.'
- 'math/rand'
- 'syscall.Syscall'
- 'time.Now'
- 'Go build ID'
selection_behavior:
- ProcessCommandLine|contains:
- 'VirtualAlloc'
- LoadedDlls:
- 'kernel32.dll'
condition: selection_pe and selection_go and selection_behavior
IOC List
- SHA-256:
d8a6366c9fbf5a41c82774f1e499aebe1a9bf9b078331f5a2c174ca0785c3b92 - SHA-1:
406d1405171e191239d6ffa67218c46181463c17(from .text section) ^[pefile.txt:94] - MD5:
4c28afc6c382d0c3f93ad55feb9aa5be(from .data section) ^[pefile.txt:133] - SSDEEP:
24576:gc58li5AOmBOa3nqfiGe0TOHF7WwG0cljYMxwELfLBele5ZK2h48YT:gc2liyOmBJXqfiyTOHxLaQeHA^[ssdeep.txt] - TLSH:
1D955B1BACA109E6C49A63338DB762817BB5B8480F3223C72E50B6783F767D45D3A754^[tlsh.txt] - Certificate CN:
unscramblex.com - Certificate Issuer:
E7 - Certificate Validity: 2026-04-06 to 2026-07-05
- Build ID:
YPlgVebmwN1vrIfko_PW/L5EZKau57xXoiFJs7kxb/DaomgXQ-haVMc8iRHmEz/O9M77OW2iEhlXOoJrbzv - Module Path:
fkfcQPBhFOUhPHI - Entry Point:
0x71540(RVA) ^[pefile.txt:50]
Behavioral Fingerprint
This binary is a Go 1.25.x PE64+ executable with a Windows GUI subsystem and no visible window code. It imports only kernel32.dll statically (LoadLibraryW, GetProcAddress, VirtualAlloc, CreateThread). On launch, it seeds a math/rand PRNG with a time-derived value, enters floating-point comparison delay loops, copies an embedded encrypted payload from .rdata into a large stack-allocated buffer, applies word-wise XOR/ADD transformations, allocates RWX memory via a VirtualAlloc wrapper, and transfers execution to the decoded payload through a syscall.Syscall direct native API call. The binary retains a full .symtab symbol table and carries a self-signed Authenticode certificate with a randomized CN.
Detection Signatures
| Capability | ATT&CK ID | Evidence |
|---|---|---|
| Reflective Code Loading | T1620 | Go-based PRNG decryptor → RWX VirtualAlloc → execution transfer ^[r2:sym.main.efvsjgrpysok] |
| Native API | T1106 | syscall.Syscall direct Windows API invocation ^[r2:sym.main.efvsjgrpysok] |
| Deobfuscate/Decode Files or Information | T1027 | math/rand-driven custom decryptor with word-wise transforms ^[r2:sym.main.wmisltgay] |
| Process Injection | T1055 | Reflective PE loader pattern; payload mapped into RWX region and executed ^[r2:sym.main.efvsjgrpysok] |
| Virtualization/Sandbox Evasion | T1497.001 | PRNG seeded with time.Now().UnixNano() acts as time-based gate ^[r2:sym.main.main] |
| Masquerading | T1036.005 | Self-signed Authenticode cert CN=unscramblex.com masquerades as legitimate software ^[binwalk.txt] |
References
- 54e64e — Family entity page with full cluster analysis and prior morphs
- raw/analyses/018ef44b2d71de8d1bfb768592daa406a91a6187bc87a74dee67cb2a0d344f0a — Morph 12 (Go 1.25.4 reflective PE loader, 55 functions, CN=xxx.com)
- raw/analyses/8017acd59116f1a84c43953daa1fc856afb65f34b72f438710fcd6094ac9486b — Morph 3 (Go 1.25.4 infostealer, CN=WE1)
- raw/analyses/2f23087fd9b9804115c782d2d0f88046d370162b5b982299ae0a518ade9664b5 — Morph 6 (Go 1.20.6 infostealer, GlobalSign cert)
- raw/analyses/0b6c65cde50cae62eb3e15a9857193abd2ed130f8d73de6afc3e58ac2397c49a — Morph 9 (Go 1.24.0 AFK Stealer, UPX-packed)
Provenance
file.txt—filecommand output (PE32+ x86-64, 8 sections)exiftool.json— PE header metadata (Win64 EXE, GUI subsystem, zero timestamp)pefile.txt— pefile full dump (sections, imports, directories, hashes per section)strings.txt—strings -n 6output (7,743 lines, Go runtime, main.* symbols, build info)rabin2-info.txt— radare2 binary header (lang=go, signed=true, canary=true, nx=true)binwalk.txt— Embedded signature scan (PKCS#7 cert at 0x1E2A08)ssdeep.txt/tlsh.txt— Fuzzy hashescapa.txt— capa failure log (missing signatures)floss.txt— floss failure log (argument parsing error)yara.txt— YARA match:PE_File_Genericonly- Radare2 analysis (level 2, 1,925 functions) — decompilation of
sym.main.main,sym.main.efvsjgrpysok,sym.main.wmisltgay,sym.main.hsksieodze,sym.main.awyhoepgiwsu,sym.main.xqfxklpdi dynamic-analysis.md— CAPE skipped (no Windows guest available)- OpenCTI labels:
54e64e,dropped-by-amadey,exe,malware-bazaar,signed^[triage.json]