4b1d954729c4aa3dcbb9e81ec47c4ae1950af995d39f7855dcbce49b989ad456unclassified-go-pe64: 4b1d9547 — Go 1.18.5 x64, 90 randomized main.* names, unsigned, no static C2
Executive Summary
PE32+ x64 GUI executable compiled with Go 1.18.5 (gc) and bearing 90 randomized main.* function names in its symbol table. No Authenticode signature, no .rsrc section, and no static C2 strings recovered. The depumped OpenCTI label is a false positive; this is a Go-compiled binary, not an AutoIt dropper. Static-only analysis (CAPE skipped — no Windows guest). Likely an infostealer or stage-1 loader based on build-pattern overlap with confirmed Go stealer families.
What It Is
| Field | Value |
|---|---|
| SHA-256 | 4b1d954729c4aa3dcbb9e81ec47c4ae1950af995d39f7855dcbce49b989ad456 |
| MD5 | 86f7a221db1a0bdba38d02503821dedb ^[file.txt] |
| SHA-1 | 19e64b3f359c2e351111aeb5ef50a34228c80549 ^[file.txt] |
| Size | 1,540,096 bytes (1.47 MB) ^[file.txt] |
| Type | PE32+ executable (GUI) x86-64, 6 sections ^[file.txt] |
| Compiler | Go 1.18.5 (gc) ^[strings.txt:1154] |
| Build ID | 5iTfgA1dcnv8pnUzwtcr/GgEe9TiMth8vkXq5kzKA/po-z3pOJqGTKHRxbucad/XTqLLA4376xKW1KcpTNc ^[strings.txt:7] |
| Entry Point | 0x5AB40 ^[pefile.txt] |
| Base Address | 0x400000 ^[rabin2-info.txt] |
| Stripped | Yes (to external PDB) ^[file.txt] |
| Signed | No ^[rabin2-info.txt:28] |
| Subsystem | Windows GUI ^[rabin2-info.txt:33] |
| IAT | kernel32.dll only (38 imports) ^[pefile.txt] |
.rsrc |
Absent ^[pefile.txt] |
How It Works
Build / RE
The binary is a standard Go 1.18.5 gc-compiled Windows amd64 executable. ^[strings.txt:1154] Go build artefacts are intact: go.buildid, go1.18.5, runtime strings (runtime.mallocgc, runtime.schedule, syscall.DLL), and the full Go type system metadata. ^[strings.txt:1652–3867]
Function name randomization: 90 main.* functions with 8–20 character randomized alphanumeric names (e.g. main.rgfuyvdydccipxe, main.Mblgnxgxvtebd, main.toibnsjgranj). ^[strings.txt:3489–3531] This is the anti-static technique documented at go-function-name-randomization — the builder renames every main package function before compilation to break string-based clustering.
Build path: Source file pmtdGjyUvflyDpg/main.go embedded in the pclntab. ^[strings.txt:3744] No vendor paths or third-party module names recovered — the malware is either a single-module project or modules are stripped by -trimpath.
Imports: The IAT is minimal — only kernel32.dll with 38 imports covering memory, thread, process, console, and exception APIs. ^[pefile.txt] No wininet, winhttp, ws2_32, or crypt32 in the IAT. Go's runtime resolves all additional APIs internally via syscall.LoadDLL + syscall.GetProcAddress.
No packing / no obfuscation beyond Go standard: Section names are standard .text, .rdata, .data, .idata, .reloc, .symtab. ^[pefile.txt] No UPX, Themida, or custom packer signatures. Entropy is moderate (6.2–6.4 in .text/.rdata). ^[pefile.txt]
No anti-debug / no anti-VM: No IsDebuggerPresent, CheckRemoteDebuggerPresent, CPUID hypervisor-bit checks, or registry disk enum queries found in strings.
Deploy / ATT&CK
All TTPs below are inferred from static build patterns unless noted. No CAPE detonation available (no Windows guest).
| Technique | ID | Evidence |
|---|---|---|
| Compile after code sign | - | Unsigned; no certificate table ^[rabin2-info.txt:28] |
| Obfuscated files or information | T1027.002 | 90 randomized main.* function names ^[strings.txt:3489] |
| Native API | T1106 | Go runtime uses syscall.DLL + GetProcAddress for all non-kernel32 APIs ^[strings.txt] |
| Application layer protocol | T1071 | net/http and crypto/tls package strings present (197 total), indicating HTTP/HTTPS client capability ^[strings.txt] |
| Data encoding | T1132 | encoding/base64, encoding/hex, crypto/md5, crypto/sha256 in standard library strings ^[strings.txt] |
No static C2: No hardcoded IPs, domains, URLs, Discord webhooks, Telegram bot tokens, or paste-site references recovered. The net/http and crypto/tls imports suggest C2 is runtime-resolved — likely decoded from an embedded blob or generated via PRNG at launch, consistent with the acrstealer / lummastealer PRNG-seeded C2 decoding pattern.
No persistence strings: No Run, RunOnce, schtasks, Startup, Userinit, or service-related strings recovered.
No credential-theft strings: No browser paths (AppData\Local\Google\Chrome), wallet names (metamask, exodus), or DPAPI/CryptUnprotect references found. However, the 197 standard-library strings include os/user, os/exec, io/ioutil, bytes.Buffer, and strings.Builder — all common in Go infostealers for file traversal and data buffering.
Decompiled Behavior
Ghidra was not invoked for this sample due to Go binary decompilation limitations (radare2 used instead). Radare2 analysis (aaa) discovered 1,498 functions. ^[r2:aaa] The entry point (0x45ab40) is the standard Go runtime entry (runtime.main), which initializes the garbage collector, goroutine scheduler, and then calls main.main. ^[rabin2-info.txt]
main.main and the 89 other randomized main.* functions are dispersed across the .text section. Without Go-specific decompilation support (e.g. redress or golang_loader), pseudocode from radare2 is largely unreadable due to Go's ABI (stack-based arguments, defer frames, runtime checks).
Key observations from radare2:
main.qwmavtofis referenced with a.func1closure, suggesting goroutine or callback usage. ^[r2:strings]main.toibnsjgranj.func1also present, reinforcing concurrent goroutine patterns. ^[r2:strings]- No
main.initbeyond the standard Go module initializer. - No obvious reflective loader, process hollowing, or shellcode injection patterns in the first 100 functions from entry.
C2 Infrastructure
None recovered statically. C2 is presumed runtime-resolved based on:
- Absence of hardcoded network strings ^[strings.txt]
- Presence of
net/http+crypto/tlsstandard library components ^[strings.txt] - Build-pattern overlap with confirmed Go infostealer families that use PRNG-seeded C2 URL decoding ^[golang-stealer-build-pattern]
Interesting Tidbits
- False-positive family label: OpenCTI tagged this sample
de-pumped/depumped. That label is an umbrella covering AutoIt-compiled droppers in this corpus. This sample is Go-compiled, not AutoIt — the label should be treated as a false positive. ^[triage.json] - Unsigned, no icon: Unlike Cluster A siblings (
589af0f8,a5520aba) which carry GoDaddy DV certificates, this sample is completely unsigned and has no.rsrcsection — the builder either skipped signing or this is an earlier/later variant from a different pipeline. ^[rabin2-info.txt:28] - Go 1.18.5 is old: Released Aug 2022. Most Go malware in this corpus uses 1.25.x (2025). This may indicate a reused builder, a maintained legacy codebase, or a deliberately old toolchain to avoid newer Go anti-debug features. ^[strings.txt:1154]
- Filename is Cyrillic: Original MalwareBazaar filename
\u0412\u043e\u043etsexecs64.exe(displayed asВооtsexecs64.exe— "bootsexecs64" with Cyrillic В and о). Masquerades as a system boot utility. ^[triage.json] - Standard library surface is huge: 197 Go standard-library API strings span networking, crypto, encoding, IO, and OS packages. A Go binary this small (1.47 MB) with this much stdlib surface is typical of a single-purpose tool compiled with all dependencies statically linked.
How To Mess With It (Homelab Replication)
Goal: Produce a Go PE64+ with comparable randomized-function-name anti-static fingerprint.
- Install Go 1.18.5 (or any 1.x):
https://go.dev/dl/go1.18.5.windows-amd64.zip - Write
main.gowith trivial HTTP client and file traversal:package main import ("net/http"; "os"; "io/ioutil") func main() { resp, _ := http.Get("https://example.com") ioutil.ReadAll(resp.Body) os.MkdirAll("C:\\Temp\\test", 0755) } - Randomize function names with a pre-build script:
# Rename every function in main.go to random strings sed -i 's/func doWork/func qwmavtof/g' main.go sed -i 's/func helper/func toibnsjgranj/g' - Build:
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-s -w -H=windowsgui" -o test.exe - Verify:
strings test.exe | grep -c '^main\.' # Should show randomized names, not semantic ones
Verification: Run strings test.exe | grep -E '^main\.[a-z]{10,20}$' — should output 5–10 randomized names. Compare to this sample's strings.txt line 3489+.
Deployable Signatures
YARA Rule
rule go_pe64_randomized_names_unsigned {
meta:
description = "Go PE64+ with randomized main.* function names, unsigned, no .rsrc"
author = "PacketPursuit SOC"
date = "2026-08-04"
sha256 = "4b1d954729c4aa3dcbb9e81ec47c4ae1950af995d39f7855dcbce49b989ad456"
strings:
$go_ver = "go1.18.5" ascii wide
$go_buildid = "go.buildid" ascii wide
$main_rnd = /main\.[a-zA-Z]{10,20}/ ascii
condition:
uint16(0) == 0x5A4D and
uint32(uint32(0x3C)+0x18) == 0x8664 and // PE32+
$go_ver and
$go_buildid and
#main_rnd >= 50 and
// No .rsrc section — check section names
not for any i in (0..pe.number_of_sections-1): (
pe.sections[i].name == ".rsrc"
)
}
Behavioral Hunt Query (Sigma-style, EQL)
title: Go PE64+ with randomized main functions
logsource:
product: windows
category: process_creation
detection:
selection:
Image|endswith: '.exe'
CommandLine|contains:
- 'go1.18'
condition: selection
IOC List
| Type | Value | Note |
|---|---|---|
| SHA-256 | 4b1d954729c4aa3dcbb9e81ec47c4ae1950af995d39f7855dcbce49b989ad456 |
Primary |
| MD5 | 86f7a221db1a0bdba38d02503821dedb |
^[file.txt] |
| SHA-1 | 19e64b3f359c2e351111aeb5ef50a34228c80549 |
^[file.txt] |
| ssdeep | 24576:tEGnBEX3GiF4unOy1MgL4QtolAz7HgjQ6OgLP8jWF4ZurOsD1:2+BG3GiiupuQtoGzXgLPQsD1 |
^[ssdeep.txt] |
| TLSH | D8654947BCD064B9D5EA923288B5A2917735F8490B3167C32F11B7BA2E373D04E753A8 |
^[tlsh.txt] |
| Build ID | 5iTfgA1dcnv8pnUzwtcr/GgEe9TiMth8vkXq5kzKA/po-z3pOJqGTKHRxbucad/XTqLLA4376xKW1KcpTNc |
^[strings.txt:7] |
| Source path | pmtdGjyUvflyDpg/main.go |
^[strings.txt:3744] |
Behavioral Fingerprint
This binary is a Go 1.18.5-compiled PE64+ GUI executable with 90+ randomized main.* function names in its symbol table, a minimal IAT restricted to kernel32.dll (38 imports), no .rsrc section, no Authenticode signature, and no hardcoded C2 strings. At runtime it likely resolves network APIs through Go's internal syscall.DLL mechanism and connects to attacker infrastructure via HTTP/HTTPS with TLS, with C2 parameters decoded from an embedded blob or generated via PRNG. The combination of heavy function-name randomization, Go 1.18.5 toolchain, and absence of .rsrc distinguishes it from signed GoDaddy-cert variants in the same umbrella cluster.
Detection Signatures
capa failed to run (default signature path missing, OSError). ^[capa.txt] No capability mapping available.
References
- Artifact ID:
343275dc-21d9-452d-a7d0-d7bb6710a077^[triage.json] - MalwareBazaar: https://bazaar.abuse.ch/sample/4b1d954729c4aa3dcbb9e81ec47c4ae1950af995d39f7855dcbce49b989ad456/ (if available)
- Family entity: unclassified-go-pe64
- Build pattern concept: golang-stealer-build-pattern
- Technique: go-function-name-randomization
Provenance
Analysis based on static artifacts: file.txt, strings.txt, floss.txt (errored — no decoded strings), capa.txt (errored — signatures missing), binwalk.txt, rabin2-info.txt, pefile.txt, exiftool.json, yara.txt, metadata.json, triage.json, ssdeep.txt, tlsh.txt. Dynamic analysis skipped (no CAPE Windows guest). Radare2 analysis at level 2 (aaa) executed; 1,498 functions identified. Decompilation unavailable due to Go ABI complexity.