93857f301171f489e5ae835ed0eee1a8bbed0a8a99debb7170f47934f9c9ecd5unattributed: 93857f30 — Truncated Go PE64+ x64 (276 KB of claimed 2.1 MB image, third confirmed sibling)
Executive Summary
A Go-compiled PE64+ x64 GUI executable arriving truncated: 276,314 bytes on disk presenting a 2.1 MB PE header (7 sections, SizeOfImage=0x208000). Only the DOS/NT headers and the first ~270 KB of .text survived; .rdata, .data, .idata, .reloc, .symtab, and .rsrc are entirely absent. The upstream MalwareBazaar source serves the same 276 KB, confirming source-side corruption. This is the third confirmed sibling of a structural truncation pattern (138b53c5 first, 134a00b7 second) with identical section-count and null-timestamp build artefacts but a unique Go build ID and larger surviving stub. No family attribution, no payload extraction, and no behavioural characterisation possible from the surviving fragments. Static-only; CAPE skipped due to no Windows guest.
What It Is
- File:
SecuriteInfo.com.Trojan.GenericKDZ.118007.31809.23817(MalwareBazaar naming) ^[metadata.json] - SHA-256:
93857f301171f489e5ae835ed0eee1a8bbed0a8a99debb7170f47934f9c9ecd5 - Type: PE32+ executable (GUI) x86-64, 7 sections ^[file.txt]
- Size: 276,314 bytes on disk ^[metadata.json]
- Claimed image size: 2,162,688 bytes (
SizeOfImage=0x208000) ^[pefile.txt:100] - Build ID:
_oMqNP3wSJk2Uh2mjhqz/rRdLgpk0WxaOulDBpGig/5ffqjBI3md2aOHA0NkeJ/Z0Su0opNm3O1yCa7GJvk^[strings.txt:8] - Toolchain: Go gc (implied by Go build ID and
.symtabsection name);GOARCH=amd64,GOOS=windows^[strings.txt:8] ^[pefile.txt] - Subsystem: Windows GUI (
0x2) ^[pefile.txt:104] - PE timestamp: Null (
0x0, 1970-01-01) ^[pefile.txt:72] - Stripped: Yes (
IMAGE_FILE_DEBUG_STRIPPED) ^[pefile.txt:77] - ASLR / NX / High Entropy: Enabled (
DYNAMIC_BASE,HIGH_ENTROPY_VA,NX_COMPAT) ^[pefile.txt:111] - Signed: No (security directory at
0x1ADA00points past EOF) ^[rabin2-info.txt:34] - Family: unattributed (truncated singleton; third confirmed instance of this pattern after
138b53c5and134a00b7) ^[triage.json]
Section Layout (truncated reality vs. header claims)
| Section | VirtualSize | SizeOfRawData | PtrToRawData | On-disk entropy | Status |
|---|---|---|---|---|---|
| .text | 0x888D0 | 0x88A00 | 0x600 | 6.19 | Partially present (~275 KB valid code, then truncation) |
| .rdata | 0xCFD00 | 0xCFE00 | 0x89000 | 0.00 | Absent (pointer past EOF) |
| .data | 0x70AF0 | 0x19000 | 0x158E00 | 0.00 | Absent |
| .idata | 0x490 | 0x600 | 0x171E00 | 0.00 | Absent |
| .reloc | 0x2B60 | 0x2C00 | 0x172400 | 0.00 | Absent |
| .symtab | 0x18F91 | 0x19000 | 0x175000 | 0.00 | Absent |
| .rsrc | 0x1F990 | 0x1FA00 | 0x18E000 | 0.00 | Absent |
^[pefile.txt:115-253]
Every section after .text has PointerToRawData beyond the 276 KB file boundary. Even .text claims SizeOfRawData=0x88A00 (559,616 bytes) starting at 0x600, which would extend to 0x89000 — well past EOF. pefile accordingly reports: "Error parsing section N. SizeOfRawData is larger than file" and "AddressOfEntryPoint lies outside the file." ^[pefile.txt:1-36]
The Go build ID at offset 0x600 confirms .text begins there and contains Go runtime code. ^[strings.txt:8]
How It Works
The binary cannot run in its current state — the entry point (0x5E380) falls inside .text, but .rdata (read-only data, including the Go runtime's string tables, type descriptors, and import descriptors) is entirely missing. Even if the first 270 KB of .text were intact, execution would immediately fault when the Go runtime attempts to access data in .rdata.
The truncation pattern (headers + partial .text, nothing else) is consistent with an interrupted download, a failed unpack, or a truncated file upload to MalwareBazaar. No re-fetch was attempted for this sample, but siblings 138b53c5 and 134a00b7 both returned identical truncated sizes from MalwareBazaar on re-fetch, confirming the corruption exists upstream. ^[/intel/analyses/138b53c57ec807db6c5a9d5b2930d0909cf34b27b4ad8b72f5d74801fdc6c1cb.html] ^[/intel/analyses/134a00b7f369a8945c928c6956750dca49230d5fa384ff94403ab176e84fd061.html]
What we can infer from the surviving fragments:
- Go runtime version: The build ID format matches Go 1.18+ (four-slash build ID with module path hash, action ID, content ID, and pseudo-version). The
.symtabsection name and build ID structure place it in the Go 1.18–1.22 range. ^[strings.txt:8] - No static strings: No C2 URLs, no mutex names, no file paths, no registry keys survived in the 22 extracted strings. ^[strings.txt]
- No imports: The import directory RVA (
0x1CB000) points into the missing.idatasection. Zero imports recoverable statically. ^[rabin2-info.txt] - No capa / floss results: capa errored (missing signatures directory) and floss received incorrect arguments during triage; re-running would not change the outcome because the file is truncated. ^[capa.txt] ^[floss.txt]
Decompiled Behavior
radare2 analysis (level 3) found 13 functions in the .text stub: ^[r2:function-list]
| Address | Name | Size (bytes) | Notes |
|---|---|---|---|
0x00401000 |
entry0 |
2 | Minimal jump stub |
0x00401002 |
fcn.00401002 |
158 | Runtime init / stack setup |
0x004010a0 |
fcn.004010a0 |
32 | Small helper |
0x004010c0 |
fcn.004010c0 |
32 | Small helper |
0x004010e0 |
fcn.004010e0 |
576 | Larger function (likely fmt/print related) |
0x004016a0 |
fcn.004016a0 |
303 | Data access / table walk |
0x00401f60 to 0x00401fc0 |
stubs | 32 each | Alignment / padding functions |
The entry point is a two-byte JMP (FF 20) that immediately dereferences an uninitialized register (goto loc_qword [rax]), confirming the stub is not meant to execute in isolation. ^[r2:entry0]
The disassembly surface shows Go runtime prologue/epilogue patterns (PUSH RBP, MOV RBP,RSP, SUB RSP,0xN), stack-canary checks (__security_cookie XOR against RBP), and what appears to be early-runtime memory-layout initialisation before the first .rdata access would fault. ^[r2:fcn.00401002]
C2 Infrastructure
None recoverable. Static analysis yields zero network indicators, zero file-system indicators, and zero registry indicators. Any C2, persistence, or payload logic lives in the missing sections.
Interesting Tidbits
- Third sibling confirms a pattern, not a one-off:
138b53c5(30 KB, build ID8_SND_5Y3k0Aps...),134a00b7(262 KB, build IDlbdBnnyBahB8NB14...), and now93857f30(276 KB, build ID_oMqNP3wSJk2Uh2m...) share identical section counts, null timestamps,strippedflags, andSizeOfImagediscrepancies but have different build IDs and truncation depths. This is either a systematic upstream corruption in the MalwareBazaar ingestion pipeline or a deliberate evasion technique (unlikely, since the binary cannot execute). ^[/intel/analyses/138b53c57ec807db6c5a9d5b2930d0909cf34b27b4ad8b72f5d74801fdc6c1cb.html] ^[/intel/analyses/134a00b7f369a8945c928c6956750dca49230d5fa384ff94403ab176e84fd061.html] - Larger stub than prior siblings: At 276 KB, this is the largest surviving
.textfragment in the cluster (30 KB → 262 KB → 276 KB), suggesting either a slightly different build size or a less severe truncation point. - Section name
.symtabis a Go giveaway: Standard MSVC/Delphi binaries use.pdataor no debug section;.symtabis the Go compiler's symbol table section name, a strong toolchain fingerprint even when the section itself is absent on disk. - Windows GUI subsystem with no window logic: The
subsystem=GUIflag is standard for Go-H=windowsguibuilds, but without.rsrcwe cannot confirm whether this was a console tool masquerading as GUI or vice versa. - No overlay: binwalk reports only the PE header with no appended data, overlay, or additional archive content. ^[binwalk.txt]
How To Mess With It (Homelab Replication)
Not applicable — the binary is non-functional. What is replicable is the detection of this pattern.
Detection recipe
import pefile
import sys
pe = pefile.PE(sys.argv[1])
file_size = open(sys.argv[1], 'rb').seek(0, 2)
# Check for truncated sections
for section in pe.sections:
ptr = section.PointerToRawData
size = section.SizeOfRawData
if ptr + size > file_size:
print(f"TRUNCATED: {section.Name.decode().strip(chr(0))} "
f"claims ptr={ptr}+size={size} > file={file_size}")
# Check entry point outside file
ep_raw = pe.OPTIONAL_HEADER.AddressOfEntryPoint + pe.OPTIONAL_HEADER.ImageBase
if ep_raw > file_size + pe.OPTIONAL_HEADER.ImageBase:
print(f"Entry point {hex(ep_raw)} outside file bounds")
Expected result on this sample: All sections after .text flag as truncated, and the entry point flags as out-of-bounds.
Deployable Signatures
YARA rule — Truncated Go PE64+ detection
rule TruncatedGoPE64 {
meta:
description = "Detects Go-compiled PE64+ binaries with truncated sections (headers + partial .text only)"
author = "PacketPursuit"
date = "2026-08-26"
sha256_1 = "138b53c57ec807db6c5a9d5b2930d0909cf34b27b4ad8b72f5d74801fdc6c1cb"
sha256_2 = "134a00b7f369a8945c928c6956750dca49230d5fa384ff94403ab176e84fd061"
sha256_3 = "93857f301171f489e5ae835ed0eee1a8bbed0a8a99debb7170f47934f9c9ecd5"
strings:
$go_build_id = "Go build ID: \""
$mz = { 4D 5A }
$go_runtime = "runtime."
condition:
$mz at 0 and
uint16(uint32(0x3C)+4) == 0x8664 and // PE64
$go_build_id and
// Entry point RVAs that would fall inside a truncated .text
uint32(uint32(0x3C)+0x28) >= 0x5E000 and
uint32(uint32(0x3C)+0x28) <= 0x5F000 and
// Number of sections = 7 (Go standard)
uint16(uint32(0x3C)+6) == 7 and
// Null timestamp (common but not universal in Go builds)
uint32(uint32(0x3C)+8) == 0 and
filesize < 300000 and filesize > 20000
}
Sigma rule — Not applicable
No runtime behaviour to target.
IOC list
| Indicator | Value | Note |
|---|---|---|
| SHA-256 | 93857f301171f489e5ae835ed0eee1a8bbed0a8a99debb7170f47934f9c9ecd5 |
Truncated Go PE64+ |
| SHA-256 | 138b53c57ec807db6c5a9d5b2930d0909cf34b27b4ad8b72f5d74801fdc6c1cb |
First sibling (30 KB) |
| SHA-256 | 134a00b7f369a8945c928c6956750dca49230d5fa384ff94403ab176e84fd061 |
Second sibling (262 KB) |
| Build ID | _oMqNP3wSJk2Uh2mjhqz/rRdLgpk0WxaOulDBpGig/5ffqjBI3md2aOHA0NkeJ/Z0Su0opNm3O1yCa7GJvk |
Unique to this sample |
| Filename | SecuriteInfo.com.Trojan.GenericKDZ.118007.31809.23817 |
MalwareBazaar naming |
Behavioural fingerprint statement
This binary is a Go-compiled PE64+ x64 executable whose on-disk image is severely truncated: only the DOS/NT headers and the first ~270 KB of the .text section are present. All remaining sections (.rdata, .data, .idata, .reloc, .symtab, .rsrc) are entirely absent — their PointerToRawData and SizeOfRawData values point past the end of the file. The entry point RVA (0x5E380) lies inside the claimed .text bounds but the binary cannot execute because .rdata (Go runtime string tables, type descriptors, import data) is missing. The Go build ID string at offset 0x600 confirms the .text fragment contains legitimate Go runtime code. No C2, persistence, or behavioural indicators are recoverable from the surviving stub.
Detection Signatures
No capa results available (tool errored during triage). ^[capa.txt]
No ATT&CK mapping possible from static data alone — the binary is non-executable in its current form.
References
- Sibling analysis: /intel/analyses/138b53c57ec807db6c5a9d5b2930d0909cf34b27b4ad8b72f5d74801fdc6c1cb.html
- Sibling analysis: /intel/analyses/134a00b7f369a8945c928c6956750dca49230d5fa384ff94403ab176e84fd061.html
- Entity: unattributed
- Concept: golang-stealer-build-pattern — shared Go build artefacts (null timestamp, stripped, ASLR+NX)
- Family: unclassified-go-pe64 — related Go PE64+ cluster with functional binaries
Provenance
Analysis based on:
file.txt— file(1) 5.44pefile.txt— pefile 2023.2.7rabin2-info.txt— radare2 5.9.0strings.txt— GNU strings 2.40binwalk.txt— binwalk v2.3.4exiftool.json— ExifTool 12.76metadata.json— triage pipeline artefacttriage.json— triage classification output- radare2 level-3 analysis with
aa+afl+pdgon entry point and nearby functions
Tools run: 2026-08-26. Static-only; CAPE skipped (no Windows guest available for PE32+ x64).