1985db0655bca27343a13d8607904c53a292459083daa8c92ae2f71a5408b40ablackmatter (blackmatter cluster): 1985db0655bc — 30th sibling, .text hash matches majority group, PE checksum 0x2e30c
Executive Summary
Thirtieth confirmed sibling in the MSVC 14.12 PEB-walking reflective-loader cluster distributed via Phorpiex spam infrastructure. Same compilation timestamp (0x631A9665), same linker (MSVC 14.12), same XOR-NOT alphabet cipher key (0x10035fff), and same .text hash (000a9a8b...) as the majority-group siblings. Per-sample deltas are limited to the individualized .data payload and PE checksum (0x2e30c). Bears both blackmatter and dropped-by-phorpiex OpenCTI labels. Static-only analysis (CAPE skipped — no Windows guest).
What It Is
- File type: PE32 executable (GUI) Intel 80386, 6 sections ^[file.txt]
- Size: 149,504 bytes (146 KB) ^[triage.json]
- Compilation: Fri Sep 9 01:27:01 2022 UTC (
0x631A9665) ^[pefile.txt:34] - Linker: MSVC 14.12 (VS 2017 15.5+) —
MajorLinkerVersion=0xE,MinorLinkerVersion=0xC^[pefile.txt:45] - Subsystem: Windows GUI ^[pefile.txt:66]
- Mitigations: ASLR (
DYNAMIC_BASE), DEP/NX (NX_COMPAT), stack canary (canary=true) ^[pefile.txt:74],^[rabin2-info.txt:6] - Signing: Unsigned (
signed: false) ^[rabin2-info.txt:27] - POGO:
IMAGE_DEBUG_TYPE_POGOdebug directory present ^[pefile.txt:313] - PE checksum:
0x2e30c(unique per-sample) ^[terminal:python hash] - OpenCTI labels:
blackmatter,dropped-by-phorpiex,exe,malware-bazaar^[triage.json] - Family: blackmatter cluster sibling (contested label — actual payload family is unattributed reflective loader) ^[entities/blackmatter.md]
How It Works
Builder-pipeline twin: shared MSVC 14.12 reflective-loader stub template with a per-sample encrypted payload injected into .data. The stub decrypts the payload, maps it reflectively into RWX memory, and transfers execution. No disk write of the inner payload.
Shared behavior (identical across all 30 siblings) is documented at blackmatter and peb-walking-api-resolution. Per-sample deltas are limited to:
.datasection contents (individualized encrypted payload).pdatasection contents (exception-table update for payload)- PE checksum (builder-computed, unique per sample)
Decompiled Behavior
Radare2 analysis recovered the same three core functions seen in every sibling:
fcn.00419479 — Entry-point orchestrator
^[r2:fcn.00419479]
Calls fcn.00419000 (init), fcn.0040639c (decryption setup), then resolves and calls the facade imports (GDI32, USER32, KERNEL32) with obfuscated string arguments before falling through to the reflective mapper. Identical control flow to all prior siblings.
fcn.00401564 — PEB-walking API resolver
^[r2:fcn.00401564]
Traverses InMemoryOrderModuleList to find kernel32.dll / ntdll.dll, hashes export names, and caches pointers in .data slots. Same function in every sibling with identical control flow.
Payload decryption / reflective mapper
The payload decryption loop and reflective PE mapper are identical to all prior siblings and are fully documented in the 27th-sibling report (raw/analyses/0cd5240c6961.../report.md) and the 28th-sibling report (raw/analyses/92fc7f45d496.../report.md).
C2 Infrastructure
No hardcoded C2 strings recovered statically. The LCG PRNG C2 URL generation routine (0x19660d / 0x3c6ef35f seeds) is present in the stub but produces runtime-only URLs. No domains, IPs, or URLs in strings.
Interesting Tidbits
.textSHA-256000a9a8b1440e44cde00fd7acc5bdda6efc34f09e404de77cff1f5298e0af369matches the majority-group siblings exactly, confirming identical compiler flags and source. ^[terminal:python hash of .text].dataSHA-256f6188dd1d61fd846cf283f506a143495f40fd966a6c2999b80c004829987c867is unique to this sample — the individualized payload. ^[terminal:python hash of .data]- Both
blackmatteranddropped-by-phorpiexOpenCTI labels present. ^[triage.json] capaandflossboth errored during triage (missing signatures and bad CLI invocation), so analysis relies on radare2 + manual PE inspection. ^[capa.txt],^[floss.txt].itextsection (0x600 bytes, entropy 2.93) contains the decompression/thunk stub, low-entropy confirming fixed template. ^[pefile.txt:112]- LCG constants
0x19660dand0x3c6ef35ffound at file offsets0x518and0x522respectively. ^[terminal:python pattern search] - XOR key
0x10035ffffound at file offset0x64e. ^[terminal:python pattern search] - CPUID instruction found at file offset
0x4c1. ^[terminal:python pattern search]
How To Mess With It (Homelab Replication)
See primary cluster analysis at /intel/analyses/136b57507a3cfe1fc39cf6973869dca7e871e91d63f283c77380fc33298d6d51.html for full reproduction pipeline.
Deployable Signatures
YARA rule
rule BlackmatterCluster_ReflectiveLoader
{
meta:
description = "MSVC 14.12 PEB-walking reflective-loader cluster (blackmatter siblings)"
author = "Titus"
reference = "/intel/analyses/1985db0655bca27343a13d8607904c53a292459083daa8c92ae2f71a5408b40a.html"
strings:
$peb_walk_sig = { 64 A1 30 00 00 00 } // mov eax, fs:[0x30] ; PEB access
$decrypt_a = { 0F C8 66 C1 C8 0D F7 D0 } // bswap, ror 0xd, not
$decrypt_b = { C1 C0 0B 0F C8 33 D0 } // rol 0xb, bswap, xor
$decrypt_c = { C1 C0 09 0F C8 F7 D0 } // rol 9, bswap, not
$decrypt_d = { C1 C0 07 0F C8 33 D0 } // rol 7, bswap, xor
$xor_key = { FF 5F 03 10 } // XOR-NOT key fragment 0x10035fff
$pogo = "POGO" ascii
$linker_14_12 = { 0E 0C } // MajorLinker=14, MinorLinker=12
condition:
uint16(0) == 0x5A4D and
uint32(uint32(0x3C)) == 0x00004550 and
#linker_14_12 >= 1 and
#pogo >= 1 and
any of ($decrypt_a, $decrypt_b, $decrypt_c, $decrypt_d) and
filesize < 200KB
}
IOC list
| Indicator | Value | Notes |
|---|---|---|
| SHA-256 | 1985db0655bca27343a13d8607904c53a292459083daa8c92ae2f71a5408b40a |
This sample |
| MD5 | f78401ac75c92cb7b2ee618480a9fe30 |
Full file |
| SHA-1 | 1d7263ba3db0536b5162d041fd1f75f7e0091d4f |
Full file |
| .text SHA-256 | 000a9a8b1440e44cde00fd7acc5bdda6efc34f09e404de77cff1f5298e0af369 |
Majority-group fingerprint |
| .data SHA-256 | f6188dd1d61fd846cf283f506a143495f40fd966a6c2999b80c004829987c867 |
Unique individualized payload |
| PE checksum | 0x2e30c |
Unique per sample |
| Compilation | Fri Sep 9 01:27:01 2022 UTC |
Shared across all 30 siblings |
| XOR key | 0x10035fff |
Alphabet-cipher key (same across cluster) |
| LCG seeds | 0x19660d / 0x3c6ef35f |
C2 URL PRNG (same across cluster) |
| Import facade | GDI32 (6), USER32 (11), KERNEL32 (8) | Minimal IAT, no threat APIs |
| Distribution | dropped-by-phorpiex |
Phorpiex spam infrastructure |
Behavioral fingerprint statement
This binary is a 150 KB PE32 GUI executable compiled with MSVC 14.12 and POGO optimization. Its import table contains only 25 benign GUI/system APIs (GDI32, USER32, KERNEL32). At runtime it resolves threat APIs via PEB-walking export hashing, decrypts a ~40 KB payload in
.datausing a 6-round bswap/ror/rol/not cipher, maps the decrypted image into RWX memory, and transfers execution without writing to disk. It performs CPUID hypervisor-bit checks and RDTSC timing gates before decryption. No hardcoded C2 — URLs are generated at runtime via an LCG PRNG seeded with0x19660d/0x3c6ef35f.
Detection Signatures
| ATT&CK Technique | Evidence | Source |
|---|---|---|
| T1055 — Process Injection | RWX VirtualAlloc + reflective PE mapping into self process |
^[r2:fcn.00419479] |
| T1027 — Obfuscated Files or Information | 6-round custom cipher on .data payload |
^[blackmatter] |
| T1027.002 — Software Packing | Runtime decryption + in-memory mapping; no payload on disk | ^[blackmatter] |
| T1620 — Reflective Code Loading | Manual PE mapping, relocation patching, import resolution | ^[blackmatter] |
| T1497.001 — Virtualization/Sandbox Evasion: System Checks | CPUID hypervisor-bit check + RDTSC timing gate | ^[peb-walking-api-resolution] |
| T1106 — Native API | PEB-walking to resolve Nt* / Zw* APIs without imports |
^[r2:fcn.00401564] |
References
- Primary cluster analysis:
/intel/analyses/136b57507a3cfe1fc39cf6973869dca7e871e91d63f283c77380fc33298d6d51.html - Entity pages: blackmatter, peb-walking-api-resolution, unattributed
- Delivery: phorpiex
- Prior sibling reports:
raw/analyses/92fc7f45d496.../report.md(28th),raw/analyses/0cd5240c6961.../report.md(27th),raw/analyses/93da3f615d04.../report.md(26th),raw/analyses/a397bea4c70b.../report.md(25th),raw/analyses/f016df16d0f3.../report.md(24th),raw/analyses/044539a2eacf.../report.md(23rd),raw/analyses/65844473d39b.../report.md(22nd),raw/analyses/91e39f6bb60a.../report.md(21st),raw/analyses/8655b3b9b2.../report.md(20th),raw/analyses/89dc341bbd.../report.md(19th),raw/analyses/2ac8295381.../report.md(18th),raw/analyses/e67dbabcd.../report.md(17th),raw/analyses/877f1047.../report.md(16th),raw/analyses/7e9bbc5c.../report.md(15th),raw/analyses/ae02bd22.../report.md(14th),raw/analyses/21b12514.../report.md(3rd)
Provenance
file.txt— file-type identification (file v5.44)exiftool.json— PE metadata (ExifTool 12.76)pefile.txt— DOS/NT headers, sections, imports, relocations, debug directory (pefile)rabin2-info.txt— radare2 binary summary (r2)strings.txt— ASCII/Unicode strings extraction (strings)triage.json— triage pipeline metadata (custom)metadata.json— OpenCTI connector artifact metadatacapa.txt— Mandiant capa (errored: missing signatures)floss.txt— FireEye FLOSS (errored: bad CLI invocation)dynamic-analysis.md— CAPE sandbox (skipped: no Windows guest available)- radare2 static analysis:
mcp_radare2with analysis level 3, 519 functions recovered, decompilation offcn.00419479andfcn.00401564