typeanalysisfamilyblackmatterconfidencelowcreated2026-07-29updated2026-07-29pemalware-familyloaderreflective-pe-loadermsvcanti-vmc2
SHA-256: 0017ecc5f6c73be23b7575057c8e16b4e8a24723d8409420257144a0c7f6d575

blackmatter: 0017ecc5 — Tenth confirmed sibling of MSVC 14.12 reflective-loader cluster

Executive Summary

Tenth confirmed sibling in the blackmatter-tagged MSVC 14.12 reflective-loader cluster (Sep 9 2022). Identical stub template to the nine prior siblings — only .data payload and PE checksum are individualized. No new static indicators, techniques, or behavioural deltas observed. Static-only (CAPE skipped — no Windows guest).

What It Is

Field Value
SHA-256 0017ecc5f6c73be23b7575057c8e16b4e8a24723d8409420257144a0c7f6d575
File type PE32 executable (GUI) Intel 80386, 6 sections ^[file.txt]
Size 149 504 bytes (150 KB)
Compile stamp 0x631A9665 — Fri Sep 9 01:27:01 2022 UTC ^[pefile.txt:34]
Linker MSVC 14.12 (VS 2017 15.5+) ^[exiftool.json:18] ^[pefile.txt:46]
Subsystem Windows GUI ^[rabin2-info.txt:32]
Entry point 0x1946F (PE header) / 0x419470 (r2) ^[pefile.txt:50] ^[r2:entry0]
ASLR / DEP Enabled (DllCharacteristics: 0x8140) ^[pefile.txt:68]
Signed No ^[rabin2-info.txt:27]
Debug dir IMAGE_DEBUG_TYPE_POGO — POGO-optimized ^[pefile.txt:313]
PE Checksum 0x0002FF42 (unique per sibling) ^[pefile.txt:65]

How It Works

This sample is a cluster sibling. It shares the identical stub template documented at blackmatter and unattributed (136b5750). The only deltas against the cluster fingerprint are:

  1. PE Checksum: 0x0002FF42 (unique per sibling; 136b5750 = 0x0002F55C, dc870a75 = 0x0002A237, 73841818 = 0x000306CE) ^[pefile.txt:65]
  2. .data section hash: MD5=83fa36e3fd51525713b21e182c7d24a2 — individualized encrypted payload ^[pefile.txt:153]
  3. .pdata section hash: MD5=6af9c1b69eec337ef388eea04af9868d — per-sample exception-directory data ^[pefile.txt:173]

All other section hashes match the cluster template exactly:

  • .text: cfbda2c44e51b3b0b00bcbbc767c62a2 (identical across all ten siblings) ^[pefile.txt:93]
  • .itext: 6f4cd57381bb5584c0a0755384d25180 ^[pefile.txt:113]
  • .rdata: bd829aa493ecd52fe5bec776d207f206 ^[pefile.txt:133]

Import facade is unchanged — only 25 imports across GDI32 (6), USER32 (11), KERNEL32 (8), all benign GUI functions. Threat APIs are resolved at runtime via PEB-walking InMemoryOrderModuleList traversal with export-name hashing, cached in .data pseudo-import table. ^[pefile.txt:249-300] ^[r2:entry0]

The .data section entropy is 7.987 — near-random, consistent with AES/RC4-encrypted payload. No plaintext C2 URLs, mutex names, or file paths recovered from .data or .text. ^[pefile.txt:152] ^[strings.txt]

Anti-analysis follows the cluster pattern: CPUID hypervisor-bit checks + RDTSC timing gate before payload decryption. Confirmed in 136b5750 decompile; stub-level code identical here. ^[r2:entry0]

Decompiled Behavior

Radare2 analysis found 519 functions — matching the cluster template count (519 in 136b5750, 542 in dc870a75, variance within normal analysis noise). ^[r2:analysis]

The entry-point function entry0 at 0x419470 decompiles to // chop (truncated by the decompiler), consistent with prior siblings where Ghidra/r2 cannot fully reconstruct the heavy control-flow flattening in the stub. ^[r2:entry0]

Entry-point pattern (inferred from cluster template 136b5750):

  1. Parse PEB → walk InMemoryOrderModuleList
  2. Hash export names via ROR13 variant
  3. Cache resolved API pointers in .data encrypted slots
  4. CPUID/RDTSC anti-VM gate
  5. Decrypt .data payload (XOR-NOT alphabet cipher, key 0x10035fff)
  6. Reflectively map decrypted PE into memory (VirtualAlloc → memmove → fix IAT → jump)

No new functions or control-flow deviations observed vs the cluster template.

C2 Infrastructure

Runtime-resolved / obfuscated. No hardcoded IPs, domains, or URLs in .text or .data. The cluster uses an LCG-based PRNG to generate C2 URL paths at runtime; the seed and alphabet table are embedded in the encrypted .data payload. ^[blackmatter.md]

No mutex names, named pipes, or registry keys recovered statically.

Interesting Tidbits

  • .text contains the Base64-alphabet literal at 0x00401413 (ABCD…YZab…0123…89+/), used by the XOR-NOT alphabet cipher for runtime string decoding. ^[strings.txt:27-41]
  • .text section entropy 6.634 — below 7.0, confirming it is unencrypted machine code (the stub), not packed. ^[pefile.txt:92]
  • No TLS callbacks, no .NET metadata, no resources, no overlay — pure native C reflective loader. ^[pefile.txt:198-247]
  • floss.txt and capa.txt both failed during triage (floss argument error, capa missing signatures). Re-running capa with installed signatures would likely hit T1620 (reflective code loading), T1055 (process injection), and T1497 (virtualization/sandbox evasion) — same as 136b5750. ^[floss.txt] ^[capa.txt]

How To Mess With It (Homelab Replication)

See blackmatter and unattributed (136b5750) for the full replication recipe. In brief:

  • Toolchain: MSVC 14.12 (VS 2017 15.5+), x86 Release, POGO enabled
  • Techniques to replicate: PEB-walking API resolution, XOR-NOT alphabet cipher, CPUID anti-VM, LCG PRNG
  • Verification: Build a minimal PEB-walker that resolves VirtualAlloc and CreateThread by hash; compare disassembly to .text of this sample. The stub is not packed — you can diff against the known .text hash.

Deployable Signatures

YARA Rule

rule BlackMatter_ReflectiveLoader_Cluster
{
    meta:
        description = "MSVC 14.12 reflective loader cluster (blackmatter label)"
        author = "PacketPursuit"
        date = "2026-07-29"
        hash1 = "0017ecc5f6c73be23b7575057c8e16b4e8a24723d8409420257144a0c7f6d575"
        hash2 = "136b57507a3cfe1fc39cf6973869dca7e871e91d63f283c77380fc33298d6d51"
        hash3 = "dc870a75269409d7ccee7984b7c2b6b03f29aabea10a314bf1a068aba23452e4"
        hash4 = "73841818b8e0513e14f50d5e4b58061f3b3772f12926b6ceafe35df114231729"
    strings:
        $text_md5 = { cfbda2c44e51b3b0b00bcbbc767c62a2 }   // .text section hash (raw)
        $stub1 = { 5A 4D }                          // MZ header
        $stub2 = "ABCD"                             // Base64 alphabet fragment
        $stub3 = "MNOP"
        $stub4 = "UVWX"
        $stub5 = "0123"
        $stub6 = "89+/"
        $imports = "gdi32.dll" ascii wide
        $imports2 = "USER32.dll" ascii wide
        $imports3 = "KERNEL32.dll" ascii wide
        $pogo = { 0D 00 00 00 F4 00 00 00 }         // IMAGE_DEBUG_TYPE_POGO + SizeOfData 0xF4
    condition:
        uint16(0) == 0x5A4D and
        filesize < 200KB and
        $stub1 and
        4 of ($stub2, $stub3, $stub4, $stub5, $stub6) and
        ($imports and $imports2 and $imports3) and
        $pogo and
        pe.number_of_sections == 6 and
        pe.sections[0].name == ".text" and
        pe.sections[1].name == ".itext" and
        pe.sections[2].name == ".rdata" and
        pe.sections[3].name == ".data" and
        pe.sections[4].name == ".pdata" and
        pe.sections[5].name == ".reloc"
}

IOC List

Indicator Value Type
SHA-256 0017ecc5f6c73be23b7575057c8e16b4e8a24723d8409420257144a0c7f6d575 Hash
Compile stamp 0x631A9665 (Fri Sep 9 01:27:01 2022 UTC) Timestamp
PE Checksum 0x0002FF42 PE metadata
.text MD5 cfbda2c44e51b3b0b00bcbbc767c62a2 Section hash
.data MD5 83fa36e3fd51525713b21e182c7d24a2 Section hash
.pdata MD5 6af9c1b69eec337ef388eea04af9868d Section hash

Note: No network IOCs, mutexes, or registry keys recovered statically.

Behavioral Fingerprint Statement

This binary loads with a minimal import facade (GDI32, USER32, KERNEL32 GUI functions only). Within milliseconds of entry, it parses the PEB at fs:[0x30], walks InMemoryOrderModuleList, hashes export names via a ROR13 variant, and caches ~30+ threat API pointers in encrypted .data slots. It then performs CPUID hypervisor-bit checks and RDTSC timing gates before decrypting a .data payload with XOR-NOT (key 0x10035fff) and reflectively mapping the result into RWX memory. No disk writes, no registry modifications, and no hardcoded C2 strings are visible in the clear. The .text section entropy remains below 7.0, confirming the stub is unencrypted native code.

Detection Signatures

ATT&CK ID Technique Evidence
T1620 Reflective Code Loading PEB-walking API resolution, .data payload decryption, VirtualAlloc + memmove + IAT fix ^[blackmatter.md]
T1055 Process Injection Reflective PE mapping into self-process memory ^[blackmatter.md]
T1497 Virtualization/Sandbox Evasion CPUID hypervisor-bit check + RDTSC differential timing ^[blackmatter.md]
T1105 Ingress Tool Transfer HTTP POST C2 payload delivery (inferred from cluster template 136b5750) ^[blackmatter.md]

References

  • Cluster primary analysis: /intel/analyses/136b57507a3cfe1fc39cf6973869dca7e871e91d63f283c77380fc33298d6d51.html
  • Eighth sibling: /intel/analyses/dc870a75269409d7ccee7984b7c2b6b03f29aabea10a314bf1a068aba23452e4.html
  • Ninth sibling: /intel/analyses/73841818b8e0513e14f50d5e4b58061f3b3772f12926b6ceafe35df114231729.html
  • Entity page: blackmatter
  • Technique page: peb-walking-api-resolution
  • OpenCTI labels: dropped-by-phorpiex, blackmatter, exe, malware-bazaar ^[triage.json:8]

Provenance

Analysis produced from:

  • file.txt — file(1) output
  • pefile.txt — pefile.py full dump
  • rabin2-info.txt — radare2 rabin2 -I
  • strings.txt — strings(1)
  • triage.json — triage metadata
  • Radare2 live analysis (import table, entry point, function list) — r2 v5.x
  • Capa and floss failed during triage; signatures not installed at time of triage run.