typeanalysisfamilyunattributedconfidencelowgolangpecompilerevasion
SHA-256: 93857f301171f489e5ae835ed0eee1a8bbed0a8a99debb7170f47934f9c9ecd5

unattributed: 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 .symtab section 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 0x1ADA00 points past EOF) ^[rabin2-info.txt:34]
  • Family: unattributed (truncated singleton; third confirmed instance of this pattern after 138b53c5 and 134a00b7) ^[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 .symtab section 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 .idata section. 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 ID 8_SND_5Y3k0Aps...), 134a00b7 (262 KB, build ID lbdBnnyBahB8NB14...), and now 93857f30 (276 KB, build ID _oMqNP3wSJk2Uh2m...) share identical section counts, null timestamps, stripped flags, and SizeOfImage discrepancies 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 .text fragment in the cluster (30 KB → 262 KB → 276 KB), suggesting either a slightly different build size or a less severe truncation point.
  • Section name .symtab is a Go giveaway: Standard MSVC/Delphi binaries use .pdata or no debug section; .symtab is 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=GUI flag is standard for Go -H=windowsgui builds, but without .rsrc we 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.44
  • pefile.txt — pefile 2023.2.7
  • rabin2-info.txt — radare2 5.9.0
  • strings.txt — GNU strings 2.40
  • binwalk.txt — binwalk v2.3.4
  • exiftool.json — ExifTool 12.76
  • metadata.json — triage pipeline artefact
  • triage.json — triage classification output
  • radare2 level-3 analysis with aa + afl + pdg on entry point and nearby functions

Tools run: 2026-08-26. Static-only; CAPE skipped (no Windows guest available for PE32+ x64).