82ee3cddf123a959a53832e969045f5552dee6867fb7d359fe766b37e8479baeunclassified-go-pe64: 82ee3cdd — Go 1.25.4 signed PE64 with multi-pass payload decryption and in-memory PE loader
Executive Summary
Signed Go 1.25.4 PE64 dropper/loader. The outer binary decrypts a ~744 KB embedded payload in-place via a four-pass custom algorithm, performs PE relocation fixups, and executes it in RWX memory. No C2 strings, browser-targeting strings, or stealer indicators survive statically — they live inside the decrypted second stage. Shares a GoDaddy DV certificate and build pattern with the 589af0f8 sibling already catalogued under unclassified-go-pe64.
What It Is
| Field | Value | Provenance |
|---|---|---|
| SHA-256 | 82ee3cddf123a959a53832e969045f5552dee6867fb7d359fe766b37e8479bae |
^[metadata.json] |
| Size | 2.4 MB (2,443,448 bytes) | ^[metadata.json] |
| File type | PE32+ executable (GUI) x86-64, 8 sections | ^[file.txt] |
| Go version | go1.25.4 |
^[strings.txt] (buildinfo at offset 0x222200) |
| Build | GOOS=windows GOARCH=amd64 GOAMD64=v1 CGO_ENABLED=0 -trimpath |
^[strings.txt] |
| Module path | ufyMQEPaAMBKqYk (randomized 15-char alpha) |
^[strings.txt] |
| TimeDateStamp | 0x0 (fabricated/stripped) |
^[pefile.txt] |
| Authenticode | GoDaddy G2 DV, CN=maybe.us, serial 86:ee:39:e0:b3:fd:88:5f, 4096-bit RSA, SHA-256, valid Jun 2025–Jun 2026 |
^[binwalk.txt] + openssl extraction |
| Signed | Yes (overlay PKCS #7 at file offset 0x254000) |
^[pefile.txt] |
| Stripped | No — .symtab retained with 2,540 symbols |
^[pefile.txt] |
.rsrc |
Absent (no icon masquerade) | ^[pefile.txt] |
| YARA match | PE_File_Generic only |
^[yara.txt] |
| CAPE | Skipped — no Windows guest available | ^[dynamic-analysis.md] |
The binary is entirely standard-library Go; no third-party dependency paths appear in strings because -trimpath was used.^[strings.txt]
How It Works
Entry point (main.main) calls three helper functions in sequence:
-
main.rwpabdjnjvkz— allocates a 256-byte buffer, fills it with sequential bytes0x00–0xff, computescrypto/md5.Sumover the buffer, and stores the 16-byte digest into a global.^[r2:sym.main.rwpabdjnjvkz] This digest becomes a keying material source for later stages. -
main.xbgysp— seeds the Go math/rand generator withtime.Now().UnixNano(), fills a 512-byte buffer withmath/rand.Intn(256), computescrypto/sha256.Sum256over that buffer, then sums the 32 bytes into a 64-bit integer stored to the same global.^[r2:sym.main.xbgysp] This produces a second key derivation path. -
main.bivfnuttklixoi— the orchestrator. It builds a 100-element slice of sequential multiples-of-three integers, callsmain.pzkkljvngbdx(the heavy lifter), then sums the slice elements and stores the result.^[r2:sym.main.bivfnuttklixoi]
The Heavy Lifter: main.pzkkljvngbdx
This ~3,700-line function (decompiled) performs the full reflective-loading pipeline:
-
API resolution via fused-string concatenation. It constructs Go string objects by slicing long concatenated blobs where Win32 API names are fused with Go runtime strings:
"advapi32.dllGetUserNameAVirtualAllocrandautoseedsweepWaiterscleanupQueuetraceStringsspanSetSpinemspanSpecialtraceTypeTabgcBitsA"^[r2:sym.main.pzkkljvngbdx]"VirtualProtectuserArenaStateGC__dedicated_read_mem_statsupdatemaxprocsasynctimerchangcstoptheworldprofstackdepthtraceallocfreeG"^[r2:sym.main.pzkkljvngbdx] It instantiatessyscall.NewCallbackandsyscall._LazyProc_, then callsVirtualProtectto mark the target region executable.^[r2:sym.main.pzkkljvngbdx]
-
Payload extraction. Copies
0xb5c00(744,448) bytes from a hardcoded.rdatablob viamain.pyoeursboua.^[r2:sym.main.pzkkljvngbdx] -
Decryption. Invokes
main.sysyjbbndnbsto decrypt the copied payload in-place. The decryption algorithm is a custom four-pass stream:- Pass 1: modular subtraction using constants
0x4d4873ecade304d5and0xa8e83f5717c0a8e9.^[r2:sym.main.pyoeursboua] - Pass 2: in-place byte shuffle (swap pairs, then iterate with stride-2 XOR/replace).^[r2:sym.main.pyoeursboua]
- Pass 3: subtract a rolling 8-bit value shifted right by eight.^[r2:sym.main.pyoeursboua]
- Pass 4: XOR each byte with its index and a derived 8-bit key.^[r2:sym.main.pyoeursboua]
- Pass 1: modular subtraction using constants
-
Memory allocation. Calls
main.cfgwqjto allocate an RWX (PAGE_EXECUTE_READWRITE,0x40) region of size0x3000or larger viaVirtualAlloc.^[r2:sym.main.pzkkljvngbdx] -
Relocation fixups. If the decrypted payload’s
IMAGE_FILE_HEADER.Characteristicsindicate it requires relocation (or if a flag is set), callsmain.lckgmwhkhto apply base-relocation fixups. The function walks the.relocdirectory, handlingIMAGE_REL_BASED_DIR64(type 10),IMAGE_REL_BASED_HIGHLOW(type 3),IMAGE_REL_BASED_HIGHADJ(type 4), andIMAGE_REL_BASED_LOW(type 2).^[r2:sym.main.lckgmwhkh] -
Execution. Calls
main.fbmzdfrtddzto parse the decrypted PE’s export table, resolve APIs viaGetProcAddress, thenmain.zotyvxtransfers control to the decrypted entry point.^[r2:sym.main.pzkkljvngbdx]
Because the payload is encrypted in the .rdata section and only decrypted at runtime, static extraction of C2, browser paths, or stealer strings is impossible without reimplementing the cipher.
C2 Infrastructure
None recovered statically. All network, browser-targeting, and exfiltration indicators live inside the encrypted second-stage payload. The outer Go wrapper provides pure loader functionality. The decrypted payload (~744 KB) is likely a commodity infostealer (historically Lumma/ACR/Meno in this cluster), but that is an inference, not a proven fact for this SHA-256.
Interesting Tidbits
- The
main.pyoeursboua(decryptor) function name and themain.sysyjbbndnbs(pre-processor) name are 15-character randomized strings, matching the module path length — the builder uses a uniform random-naming scheme for everything.^[r2:sym.main.pyoeursboua] - The fused strings in
.rdataare not obfuscated with XOR or encryption; they are simply concatenated end-to-end, relying on Go’s slice-bounds slicing to extract substrings at runtime. This defeats naivestrings-based IOC extraction but is trivially recoverable with Ghidra orfloss.^[r2:sym.main.pzkkljvngbdx] - Certificate
CN=maybe.usis a throwaway domain parked with GoDaddy. It has been observed on at least one prior sibling (589af0f8). The serial number (86:ee:39:e0:b3:fd:88:5f) is identical between those two samples, confirming certificate reuse across builds.
How To Mess With It (Homelab Replication)
Toolchain: Go 1.25.4 windows/amd64, CGO_ENABLED=0.
Compiler flags:
go build -ldflags="-H windowsgui -s" -trimpath
Replication sketch:
- Embed a PE payload as a
//go:embed payload.binresource. - Implement the four-pass decryptor in Go (see
main.pyoeursbouafor constants). - Use
syscall.VirtualProtect(viasyscall.NewLazyDLL+NewProc) to mark memory RWX. - Use
reflect.SliceHeaderorunsafe.Pointerto cast the decrypted blob to a function pointer and call it. - Add
runtime.ReadMemStatsandtime.Sleep(0x989680)(10s) loops to match thevzcegglcftbzfkotelemetry pattern observed in this cluster.
Verification: Compile, run strings on the output, and confirm the presence of build\tGOOS=windows, path\t<random>, and no absolute module paths.
Deployable Signatures
YARA Rule
rule UnclassifiedGoPE64_Loader_MaybeUS {
meta:
description = "Go 1.25.4 PE64 signed dropper/loader cluster, CN=maybe.us"
author = "PacketPursuit"
date = "2026-06-07"
sha256 = "82ee3cddf123a959a53832e969045f5552dee6867fb7d359fe766b37e8479bae"
family = "unclassified-go-pe64"
strings:
$go_build = "go1.25.4"
$go_os = "build\tGOOS=windows"
$go_arch = "build\tGOARCH=amd64"
$mod_path = /path\t[a-zA-Z]{12,20}/
$mod_dev = /mod\t[a-zA-Z]{12,20}\t\(devel\)/
$advapi_fused = "advapi32.dllGetUserNameAVirtualAllocrandautoseedsweepWaiterscleanupQueuetraceStringsspanSetSpinemspanSpecialtraceTypeTabgcBitsA"
$vp_fused = "VirtualProtectuserArenaStateGC (dedicated)read mem statsupdatemaxprocsasynctimerchangcstoptheworldprofstackdepthtraceallocfreeG"
condition:
uint16(0) == 0x5a4d and
filesize > 2MB and filesize < 5MB and
$go_build and $go_os and $go_arch and
($mod_path or $mod_dev) and
($advapi_fused or $vp_fused)
}
Sigma Rule
title: Go PE64 Signed Loader Process Creation with RWX Allocation
logsource:
category: process_creation
product: windows
detection:
selection:
- Image|endswith:
- '.exe'
- CommandLine|contains:
- 'VirtualProtect'
- 'VirtualAlloc'
condition: selection
# Operationalized: hunt for Go-compiled executables (Go build ID in .text) that call VirtualAlloc
# with PAGE_EXECUTE_READWRITE (0x40) within 5 seconds of process start.
IOC List
| Type | Value | Note |
|---|---|---|
| SHA-256 (outer) | 82ee3cddf123a959a53832e969045f5552dee6867fb7d359fe766b37e8479bae |
Loader |
| SHA-256 (payload) | Unknown | In-memory only |
| Certificate CN | maybe.us |
GoDaddy G2 DV |
| Certificate serial | 86:ee:39:e0:b3:fd:88:5f |
Reused from 589af0f8 sibling |
| Module path | ufyMQEPaAMBKqYk |
Randomized per build |
| Function names | rwpabdjnjvkz, xbgysp, bivfnuttklixoi, pzkkljvngbdx, pyoeursboua, sysyjbbndnbs, cfgwqj, lckgmwhkh, fbmzdfrtddz, zotyvx, hidyepfce, lxmoxfslpsjdnk, Ecmeqfevvyhfkf, imvehatitmen, ykjbzfootuzxk, arxsco, cfgwqj, gogwakcldizwvj, ihwljw, wmsqgyj, vzcegglcftbzfko |
23 randomized main.* identifiers |
| Payload size | 0xb5c00 (744,448 bytes) |
Embedded in .rdata |
| Memory permission | PAGE_EXECUTE_READWRITE (0x40) |
Via VirtualProtect |
Behavioral Fingerprint
This binary is a Go 1.25.4 PE64 with a GUI subsystem and Authenticode signature. On launch it seeds the PRNG with wall-clock time, performs two hash-based key derivations (MD5 and SHA-256), allocates a scratch buffer, decrypts a ~744 KB embedded payload using a four-pass custom stream cipher (modular subtraction, byte shuffle, rolling subtraction, index-XOR), parses the decrypted blob as a PE image, applies relocation fixups if required, marks the target region RWX via VirtualProtect, and transfers execution to the decrypted entry point. No C2 strings are present in the outer binary; all network behavior is expected to reside in the decrypted second stage.
Detection Signatures
| Technique | ATT&CK ID | Evidence |
|---|---|---|
| Reflective code loading | T1620 | Decrypted PE executed from RWX memory without touching disk |
| Process injection via RWX allocation | T1055 | VirtualAlloc with PAGE_EXECUTE_READWRITE + memcpy + transfer of control |
| Native API loading | T1106 | LoadLibraryW + GetProcAddress via syscall._LazyProc_ |
| Code signing | T1553.002 | Authenticode signature (GoDaddy DV, CN=maybe.us) to evade ML-based and trust-based defenses |
| Data obfuscation: custom payload encryption | T1027.002 | Four-pass custom stream cipher over embedded .rdata payload |
| Runtime API resolution | T1106 | GetProcAddress for VirtualProtect and other Win32 APIs |
| Timestamp manipulation | T1070.006 | TimeDateStamp=0x0 in PE header |
References
- unclassified-go-pe64 — Parent cluster entity page (siblings
589af0f8,cc4aa789). - golang-stealer-build-pattern — Shared build artefacts across this cluster.
- raw/analyses/589af0f87f4087f34750995ce679024df4e04acd0d096fe49e7f1223cb5905ae — First sibling with identical certificate.
Provenance
Artifacts consumed: file.txt, exiftool.json, pefile.txt, strings.txt, ssdeep.txt, tlsh.txt, yara.txt, metadata.json, triage.json, rabin2-info.txt, binwalk.txt, dynamic-analysis.md.
Tools: radare2 (analysis level 3, aang Go recovery), openssl (PKCS #7 cert extraction), Python 3 (string scraping, buildinfo parsing), custom scripts.
Capa and floss failed: capa signatures path missing; floss CLI parse error on arguments.