da02fd0723caacead4f056ddcb30995785e52f60dbd5c5c00828de5b54a0aad9coinminer: da02fd07 — 5.82 MB plain-zlib PyInstaller sibling, thirty-ninth block cluster
Executive Summary
PyInstaller single-file PE32 (5.82 MB) built with MSVC 14.0 on 2018-09-04 14:43:33 UTC. The outer binary is the standard C bootloader stub (~319 KB); the actual payload is a 5.32 MB zlib-compressed overlay (91.4% of file) containing 39 distinct zlib streams. No AES encryption layer is present — unlike the majority of this cluster, there is no pyimod00_crypto_key module and no weak QWERTY-derived key 1qazxsw23edcvfrN. No mining-specific strings are recoverable from the outer binary or overlay. Static-only analysis; CAPE skipped due to no Windows guest. Treated as a probable coinminer sibling by build fingerprint, but inner payload identity is unconfirmed.
What It Is
| Field | Value |
|---|---|
| SHA-256 | da02fd0723caacead4f056ddcb30995785e52f60dbd5c5c00828de5b54a0aad9 |
| Size | 5,823,801 bytes (5.82 MB) ^[file.txt] |
| Type | PE32 executable (GUI) Intel 80386, 6 sections ^[file.txt] |
| Compiler | MSVC 14.0 (Visual Studio 2015) ^[exiftool.json] ^[rabin2-info.txt] |
| Timestamp | 2018-09-04 14:43:33 UTC ^[pefile.txt] ^[rabin2-info.txt] |
| Linker | 14.0 / 14.16 ( MajorLinkerVersion=0xE, Minor=0x0 ) ^[pefile.txt] |
| Build path hint | _MEIPASS2, pyi-runtime-tmpdir, PyInstaller: pyi_win32_utils_to_utf8 failed ^[strings.txt:115] ^[strings.txt:235] ^[strings.txt:243] |
| Family | coinminer (pipeline label; medium confidence) |
The binary is a standard PyInstaller v3.x single-file executable for Python 2.7. The PE header is minimal: six sections (.text, .rdata, .data, .gfids, .rsrc, .reloc), no export table, no security directory, no COM descriptor, no delay imports. ^[pefile.txt] Import surface is thin: KERNEL32.dll (heap/CRT/process APIs), USER32.dll (MessageBoxA/W), and WS2_32.dll (ntohl by ordinal). ^[pefile.txt] The .rsrc section contains seven RT_ICON entries (~66 KB total) with no VS_VERSIONINFO or manifest. ^[pefile.txt]
How It Works
Bootloader stub
On execution, the PyInstaller C stub:
- Resolves its own path via
GetModuleFileNameW. ^[strings.txt:118] - Creates a temporary directory (default
%TEMP%/_MEIxxxxxx) controlled by_MEIPASS2orpyi-runtime-tmpdirenvironment variables. ^[strings.txt:115] ^[strings.txt:235] - Extracts the embedded CArchive from the file overlay into the temp directory.
- Loads
python27.dll(or equivalent) and bootstraps the Python runtime. - Executes the embedded
__main__.pyscript. ^[strings.txt:105]
The stub contains standard PyInstaller error strings: Cannot open self %s or archive %s, Error allocating decompression buffer, Archive path exceeds PATH_MAX, Failed to execute script %s. ^[strings.txt:116] ^[strings.txt:78] ^[strings.txt:95] ^[strings.txt:111]
Overlay analysis
The PE proper ends at raw offset 0x3CE00 (≈ 248 KB). Everything after is the PyInstaller CArchive overlay:
- Overlay size: 5,574,457 bytes (5.32 MB, 91.4% of total file) ^[binwalk.txt]
- Zlib streams: 39 distinct zlib-compressed blocks detected by binwalk ^[binwalk.txt]
- AES encryption: Absent. No
pyimod00_crypto_keymodule name, no1qazxsw23edcvfrNkey string, nocrypto_keyreference anywhere in the binary. ^[strings.txt] (verified by full-text search) - Python runtime: No
python27.dllorpython3x.dllstring found in the outer binary; the runtime DLL is likely one of the zlib-compressed entries inside the overlay. ^[strings.txt]
Payload content (inferred)
No plaintext mining indicators (stratum, xmrig, pool, monero, wallet, miner) are present in the outer binary or recoverable from the overlay without decompression. ^[strings.txt] The sample is structurally identical to the confirmed PyInstaller coinminer cluster (same MSVC 14.0 build timestamp, same bootloader version, same zlib overlay pattern). The most parsimonious attribution is that the inner payload is a Python-based miner or downloader, but this is inference — the actual payload is concealed inside 39 zlib blocks.
Compared to AES-encrypted siblings (e.g., 359fcf01, 058ab625, f7abdaf8), this sample drops the encryption layer entirely. The builder appears to have toggled AES on/off while keeping the same PyInstaller version and build pipeline.
Decompiled Behavior
Ghidra was not run for this sample; static analysis relied on radare2 and tool outputs. Radare2 analysis (level 3) recovered 930 functions. The entry point entry0 at 0x004079d3 delegates to main at 0x00401000, which implements the standard PyInstaller C bootloader flow: archive open → TOC read → zlib decompress → temp directory write → Python DLL load → script execution. ^[r2:entry0] ^[r2:main]
Notable functions (radare2 symbol names recovered from string xrefs):
Py_Initialize/Py_Finalize/PyRun_SimpleString— Python runtime bootstrap ^[strings.txt:145] ^[strings.txt:141] ^[strings.txt:181]PyMarshal_ReadObjectFromString— loads compiled.pycfrom the CArchive ^[strings.txt:198]PyImport_ExecCodeModule— executes the unmarshalled code object ^[strings.txt:165]CreateProcessW— spawns the extracted payload process ^[strings.txt:239]
No anti-debug, anti-VM, or sandbox-evasion logic is present in the bootloader stub. The stub is the stock PyInstaller runtime with no modifications.
C2 Infrastructure
No C2 indicators recoverable statically. The payload is a 5.32 MB zlib-compressed overlay; network indicators (Stratum pool URLs, wallet addresses, HTTP downloaders) would only be visible after full extraction and decompression of the inner Python payload. OpenCTI label is coinminer/exe/urlhaus with no additional IOCs. ^[triage.json]
Interesting Tidbits
- No AES layer — This is the largest plain-zlib sibling in the cluster (5.82 MB). Most siblings in the 2–6 MB range use AES-256-CBC with the weak key
1qazxsw23edcvfrNderived from the top-left QWERTY row. This sample omits encryption entirely, making the overlay directly decompressible with standard zlib. ^[/intel/analyses/359fcf01a54b89eabcbfcecd734e2af60b6bfa19ffd7fcdd87b1e4ed15db599c.html] - Python 2.7 era — The bootloader strings reference
PyString_FromStringandPyString_FromFormat, which are Python 2.x APIs removed in Python 3. This confirms the build target is Python 2.7. ^[strings.txt:183] ^[strings.txt:185] - MSVC 14.0 CRT bloat — The
.rdatasection contains full Visual C++ 2015 CRT error strings, vtable descriptors, and C++ exception handling metadata. ^[strings.txt:358] ^[strings.txt:300-354] - WS2_32 import — Only
ntohlis imported by ordinal from WS2_32.dll. This is a minimal networking stub; the actual socket code lives in the Python overlay (likely viasocketorurllibmodules). ^[pefile.txt] - No signing — Security directory is zeroed.
signed: falsein rabin2. ^[pefile.txt] ^[rabin2-info.txt]
How To Mess With It (Homelab Replication)
Toolchain: Visual Studio 2015 (MSVC 14.0), Python 2.7.18, PyInstaller 3.x
Steps:
- Install Python 2.7.18 on a Windows research VM.
pip install pyinstaller==3.6- Write a trivial Python script (e.g., prints
_MEIPASSand sleeps):import sys, os, time print("_MEIPASS:", getattr(sys, '_MEIPASS', os.getcwd())) time.sleep(30) - Build:
pyinstaller --onefile test.py - Verify with
binwalk -e dist/test.exe— should show zlib streams in the overlay. - Compare capa fingerprint (if capa signatures are installed) to cluster siblings.
What you'll learn: PyInstaller single-file PE structure, CArchive overlay layout, and how the bootloader delegates to the Python runtime. The --onefile flag is the key toggle that produces this overlay pattern.
Deployable Signatures
YARA rule
rule PyInstaller_Coinminer_Sep2018_Cluster
{
meta:
description = "PyInstaller single-file PE32 from Sep 2018 MSVC 14.0 coinminer cluster"
author = "PacketPursuit"
date = "2026-08-04"
sha256 = "da02fd0723caacead4f056ddcb30995785e52f60dbd5c5c00828de5b54a0aad9"
strings:
$pyi1 = "Cannot open self %s or archive %s" ascii
$pyi2 = "Failed to execute script %s" ascii
$pyi3 = "pyi-runtime-tmpdir" ascii
$pyi4 = "_MEIPASS2" ascii
$pyi5 = "PyInstaller: pyi_win32_utils_to_utf8 failed." ascii
$msvc_ts = { 15 9A 8E 5B } // TimeDateStamp 0x5B8E9A15 = Sep 4 2018 14:43:33 UTC
condition:
uint16(0) == 0x5A4D and
uint32(uint32(0x3C)) == 0x4550 and
filesize > 1MB and filesize < 10MB and
3 of ($pyi*) and
$msvc_ts
}
Behavioral hunt query (Sigma-like)
title: PyInstaller Coinminer Extraction and Execution
logsource:
product: windows
category: process_creation
detection:
selection:
CommandLine|contains:
- '_MEI'
- 'pyi-runtime-tmpdir'
ParentImage|endswith:
- '.exe'
temp_path:
CommandLine|contains:
- '\Temp\_MEI'
condition: selection and temp_path
IOC list
| Indicator | Value | Note |
|---|---|---|
| SHA-256 | da02fd0723caacead4f056ddcb30995785e52f60dbd5c5c00828de5b54a0aad9 |
Sample hash |
| Build timestamp | 0x5B8E9A15 (2018-09-04 14:43:33 UTC) |
Cluster fingerprint |
| Temp path pattern | %TEMP%\_MEIxxxxxx |
PyInstaller extraction directory |
| Environment variable | _MEIPASS2 |
Controls extraction path |
| Overlay signature | 39+ zlib streams, no AES layer | Plain-zlib variant |
Behavioral fingerprint
This binary is a PyInstaller single-file executable built with MSVC 14.0 in September 2018. On launch it creates a _MEI-prefixed temporary directory under %TEMP%, extracts a Python 2.7 runtime and embedded script from a large zlib-compressed file overlay (typically 1–6 MB, >85% of file size), then loads python27.dll and executes the extracted __main__.py. No registry persistence or elevation is attempted by the bootloader itself; persistence behavior, if any, is implemented in the inner Python payload. The overlay contains 30–60 zlib-compressed blocks. Some siblings encrypt the overlay with AES-256-CBC using the weak key 1qazxsw23edcvfrN; this specific sample omits encryption.
Detection Signatures
| Capability | ATT&CK ID | Evidence |
|---|---|---|
| Python script execution | T1059.006 | PyInstaller bootloader extracts and runs embedded Python bytecode ^[strings.txt:105] ^[strings.txt:165] |
| Data deobfuscation | T1027 | Zlib-compressed overlay (39 streams) ^[binwalk.txt] |
| File and directory discovery | T1083 | FindFirstFileExW, GetFileAttributesExW ^[pefile.txt] |
| Process creation | T1106 | CreateProcessW ^[pefile.txt] |
References
- Artifact ID:
14668ecc-aeef-4c0a-acad-fd280314f8d5^[triage.json] - OpenCTI labels:
coinminer,exe,urlhaus^[triage.json] - coinminer — Entity page for the family cluster
- pyinstaller-bootloader — Concept page for PyInstaller PE structure
- python-packed-payload — Concept page for Python-packed malware
- Sibling analysis:
801fbba1(first confirmed sibling) ^[/intel/analyses/801fbba19b4d4828191e87e7311480deaf81e84482dab70adf38d61afd01c1fa.html] - Sibling analysis:
1fed143e(plain-zlib sibling, 4.14 MB) ^[/intel/analyses/1fed143e0f95ce0e7e6070d89745c74b6a086df0387a2e091720be20a27774b4.html]
Provenance
file.txt—file(1)outputexiftool.json— ExifTool 12.76 PE metadatapefile.txt— pefile.py full PE dumpstrings.txt—strings -a -n 6(10,640 lines)floss.txt— FireEye flare-floss (failed due to CLI argument error)capa.txt— Mandiant capa (failed: default signature path missing)binwalk.txt—binwalk -eembedded artifact scan (39 zlib streams)rabin2-info.txt— radare2rabin2 -Iheader summarytriage.json— OpenCTI-derived labels and artifact metadatadynamic-analysis.md— CAPE skipped (no Windows guest)- Radare2 analysis: level 3, 930 functions recovered, entry0 at 0x004079d3