b4cc27e365f44dd18593d7ca2b4a2d9df95268079beff47940f48cce21bfc979coinminer: b4cc27e3 — Smallest PyInstaller bootloader sibling, 630 KB, Python 2.7 payload
Executive Summary
PyInstaller single-file PE32 bootloader (MSVC 14.0, compiled Sep 4 2018 14:43:33 UTC) — the smallest observed sibling in the cluster at 630,707 bytes. The ~381 KB zlib-compressed overlay (60.5% of file) contains a Python 2.7 payload (python27.dll, libgcc_s_dw2-1.dll) rather than the Python 3.x runtime seen in the larger siblings. No mining pool URLs or wallet addresses are visible in the outer binary; actual coinminer logic lives inside the compressed overlay. CAPE skipped (no Windows guest).
What It Is
- File: PE32 executable (GUI) Intel 80386, 6 sections ^[file.txt]
- Size: 630,707 bytes (616 KB) — smallest sibling in the cluster ^[rabin2-info.txt]
- Compiled: Tue Sep 4 14:43:33 2018 UTC — identical timestamp to siblings 801fbba1, 39b67a79, 5047235c, 640ed5b5, 359fcf01 ^[pefile.txt:34] ^[rabin2-info.txt]
- Linker: MSVC 14.0 (Visual Studio 2015 RTM). Rich header not extracted in this triage run, but linker version and timestamp match the documented cluster. ^[pefile.txt:44-45] ^[exiftool.json]
- Signed: false; checksum
0x00000000^[rabin2-info.txt] - ASLR / DEP: enabled (
DllCharacteristics: 0x8140= DYNAMIC_BASE | NX_COMPAT | TERMINAL_SERVER_AWARE) ^[pefile.txt:74] - Subsystem: Windows GUI ^[file.txt]
- Overlay: 381,363 bytes starting at raw offset
0x3CE00, zlib-compressed PyInstaller CFFI archive ^[binwalk.txt] - Overlay ratio: 60.5% of total file size — lower than 39b67a79 (94%) but larger proportionally than 640ed5b5 (see delta notes). ^[binwalk.txt]
How It Works
Same stock PyInstaller single-file bootstrap as the rest of the cluster ^[r2:entry0]:
- CRT initialisation — MSVC
entry0(0x004079d3) →main()→ PyInstaller bootstrap ^[r2:entry0] - Archive resolution — reads the appended CFFI archive from the PE overlay (
0x3CE00) ^[binwalk.txt] - Extraction — inflates zlib streams and writes to
%TEMP%\_MEI<XXXX>^[strings.txt:79-84] ^[binwalk.txt] - Python runtime bootstrap — loads
python27.dlland resolves CPython API (Py_Initialize,PyMarshal_ReadObjectFromString, etc.) ^[strings.txt:119-212] - Script execution — unmarshals embedded
.pycand runs__main__.py^[strings.txt:104-111] - Cleanup — deletes temp directory on exit unless
_MEIPASS2environment variable is set. ^[strings.txt:115]
The overlay contains the actual coinminer payload. Mining pool URLs and wallet addresses are expected inside the compressed Python archive, not observable statically.
Decompiled Behaviour
entry0(0x004079d3): Standard MSVC CRT entry stub. Sets up exception filters, TLS, and callsmain(). No anti-debug or VM checks. ^[r2:entry0]main(0x00401000): Calls the PyInstaller bootstrap core. Identical control flow to sibling 801fbba1. ^[r2:entry0]- No notable functions beyond standard PyInstaller C runtime bootstrap. The decompiler shows only CRT boilerplate (
fcn.00408270,fcn.00407d1f, etc.) with no custom threat logic in the outer binary. ^[r2:entry0]
C2 Infrastructure
Not statically observable. No hardcoded IPs, domains, pool URLs, or wallet addresses in the PE sections or imports. Pool configuration lives inside the compressed Python payload. ^[strings.txt]
Interesting Tidbits
- Python 2.7 build environment: Strings reference
python27.dll,libgcc_s_dw2-1.dll, and a MinGW runtime path (C:/ming730/i686-730-posix-dwarf-rt_v5-rev0/mingw32), indicating the embedded interpreter was compiled with MinGW-w64 for Python 2.7. ^[strings.txt] - Smallest cluster sibling: At 630 KB, this is ~105 KB smaller than 640ed5b5 (735 KB) and ~188 KB smaller than 801fbba1 (819 KB). The size delta is entirely in the overlay (smaller Python payload / fewer bundled libraries). ^[rabin2-info.txt]
floss.txttriage bug: The triage script passed the sample path to--noinstead ofsample, yielding no decoded strings. No FLOSS recovery available. ^[floss.txt]capa.txtnon-functional: Default signature path missing on this station; no capa ATT&CK mapping. ^[capa.txt]- No obfuscation in bootloader: No API hashing, no PEB walking, no anti-debug (
IsDebuggerPresentis imported by the CRT but not used for evasion). The outer binary is entirely benign infrastructure. ^[pefile.txt:249-363] - Overlay stream count:
binwalk.txtidentified 15 zlib-compressed blocks and a PNG icon in.rsrc, consistent with a multi-member CFFI archive. ^[binwalk.txt]
How To Mess With It (Homelab Replication)
- Toolchain: Install Python 2.7 and PyInstaller 3.x on a Windows research VM. Build the onefile executable:
pyinstaller --onefile --windowed your_miner_script.py - Extraction: Use
pyinstxtractor.pyagainst the PE to dump the embedded CFFI archive, then inspect withuncompyle6ordecompyle3. - Differentiator: This sibling's smaller size suggests fewer bundled dependencies (no
numpy, norequests, etc.). Compare overlay entropy and member count across siblings.
Deployable Signatures
YARA rule
rule PyInstaller_Coinminer_2018_Sibling {
meta:
description = "PyInstaller single-file bootloader sibling (Sep 2018 MSVC, coinminer cluster)"
author = "Titus"
date = "2026-06-08"
sha256 = "b4cc27e365f44dd18593d7ca2b4a2d9df95268079beff47940f48cce21bfc979"
strings:
$pyi1 = "PyInstaller: FormatMessageW failed." ascii wide
$pyi2 = "_MEIPASS2" ascii wide
$pyi3 = "pyi-runtime-tmpdir" ascii wide
$pyi4 = "Failed to execute script %s" ascii wide
$pyi5 = "Cannot open self %s or archive %s" ascii wide
$inflate = "inflate 1.2.8 Copyright 1995-2013 Mark Adler" ascii wide
$python27 = "python27.dll" ascii wide
$libgcc = "libgcc_s_dw2-1.dll" ascii wide
condition:
uint16(0) == 0x5a4d and
3 of ($pyi*) and
$inflate and
any of ($python27, $libgcc) and
filesize > 400KB and filesize < 800KB
}
Sigma rule
Not suitable for the outer binary alone. Target the child process: python.exe or a renamed miner spawned from %TEMP%\_MEI* within seconds of parent launch.
IOC list
- SHA-256:
b4cc27e365f44dd18593d7ca2b4a2d9df95268079beff47940f48cce21bfc979 - Temp path pattern:
%TEMP%\_MEI*\*(PyInstaller extraction directory) - Embedded DLL names:
python27.dll,libgcc_s_dw2-1.dll - Build timestamp:
0x5B8E9A15(Tue Sep 4 14:43:33 2018 UTC)
Behavioural fingerprint
PE32 GUI executable compiled with MSVC 2015, containing a ~381 KB zlib-compressed overlay (60.5% of file). At runtime extracts payload to a _MEI-prefixed temp directory, loads python27.dll, and executes embedded marshalled Python bytecode. No suspicious imports in parent process; threat behaviour manifests in child Python/miner processes. Part of a cluster of at least six siblings sharing the identical Sep 2018 build timestamp.
Detection Signatures
- MITRE ATT&CK
- T1059.003 (Windows Command Shell) — possible batch/powershell launcher in embedded payload; not confirmed statically
- T1059.006 (Python) — execution via embedded Python interpreter
- T1074.001 (Data Staged: Local Data Staging) — extraction to temp directory
- T1105 (Ingress Tool Transfer) — self-contained payload delivery
- T1574.002 (DLL Side-Loading) — loading Python DLL from
_MEIpath
- Capa: non-functional (missing signatures). No ATT&CK mapping available.
References
- Artifact ID:
eeb4ec7a-0a46-4b9f-be46-ab890b58b772^[metadata.json] - OpenCTI labels:
coinminer,exe,urlhaus^[triage.json] - Related wiki: coinminer | pyinstaller-bootloader | python-packed-payload
- Sibling reports: 801fbba1 | 39b67a79 | 5047235c | 640ed5b5 | 359fcf01
Provenance
file.txt—filecommand (PE32 executable)strings.txt— strings (1468 lines)rabin2-info.txt— radare2rabin2 -I(binary metadata)pefile.txt—pefilePython module (sections, imports, resources)binwalk.txt—binwalk(embedded artifacts / zlib blocks)exiftool.json— ExifTool PE metadatafloss.txt— flare-floss (tool argument error, no decoded output)capa.txt— flare-capa (signature path error, no output)triage.json— triage tier assignmentmetadata.json— artifact metadata from OpenCTIdynamic-analysis.md— CAPE skipped (no Windows guest available)- R2 decompilation — radare2 via MCP (
entry0at0x004079d3)