0017ecc5f6c73be23b7575057c8e16b4e8a24723d8409420257144a0c7f6d575blackmatter: 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:
- PE Checksum:
0x0002FF42(unique per sibling;136b5750=0x0002F55C,dc870a75=0x0002A237,73841818=0x000306CE) ^[pefile.txt:65] .datasection hash:MD5=83fa36e3fd51525713b21e182c7d24a2— individualized encrypted payload ^[pefile.txt:153].pdatasection 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):
- Parse PEB → walk
InMemoryOrderModuleList - Hash export names via ROR13 variant
- Cache resolved API pointers in
.dataencrypted slots - CPUID/RDTSC anti-VM gate
- Decrypt
.datapayload (XOR-NOT alphabet cipher, key0x10035fff) - 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
.textcontains the Base64-alphabet literal at0x00401413(ABCD…YZab…0123…89+/), used by the XOR-NOT alphabet cipher for runtime string decoding. ^[strings.txt:27-41].textsection 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.txtandcapa.txtboth failed during triage (floss argument error, capa missing signatures). Re-running capa with installed signatures would likely hitT1620(reflective code loading),T1055(process injection), andT1497(virtualization/sandbox evasion) — same as136b5750. ^[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
VirtualAllocandCreateThreadby hash; compare disassembly to.textof this sample. The stub is not packed — you can diff against the known.texthash.
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) outputpefile.txt— pefile.py full dumprabin2-info.txt— radare2rabin2 -Istrings.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.