5d9fe2735d4399d98e6e6a792b1feb26d6f2d9a5d77944ecacb4b4837e5e5fcacoinminer: 5d9fe273 — PyInstaller bootloader sibling, Sep 2018 MSVC build, plain-zlib overlay with embedded xmrig.exe
Executive Summary
PyInstaller single-file PE32 dropper, twenty-second confirmed sibling in the September 2018 MSVC 2015 cluster. Unlike the AES-encrypted sub-cluster (359fcf01, 058ab625, etc.), this 5.98 MB sample uses a plain-zlib overlay with no PyInstaller --key encryption, enabling direct recovery of embedded payload names including xmrig.exe — confirming the coinminer attribution. 96% overlay ratio, 47 zlib streams, same Sep 2018 compilation fingerprint. No anti-debug or VM detection in the outer bootloader. Static-only (CAPE skipped — no Windows guest).
What It Is
- File: PE32 executable (GUI) Intel 80386, 6 sections ^[file.txt]
- Size: 6,271,268 bytes (5.98 MB) ^[triage.json]
- Compiled: Tue Sep 4 14:43:33 2018 UTC ^[pefile.txt:34] ^[rabin2-info.txt:11]
- Linker: MSVC 14.0 (Visual Studio 2015) ^[pefile.txt:45-46]
- Signed: false ^[rabin2-info.txt:27]
- ASLR / DEP: enabled (
DllCharacteristics: 0x8140) ^[pefile.txt:74] - Subsystem: Windows GUI ^[file.txt]
- Overlay: 6,021,924 bytes starting at raw offset
0x3CE00(96.0% of file), plain-zlib CFFI archive ^[binwalk.txt] ^[manual_analysis] - Family: coinminer (OpenCTI label) ^[triage.json]
How It Works
Standard PyInstaller single-file bootloader runtime sequence (documented at pyinstaller-bootloader and coinminer):
- CRT initialisation — MSVC
entry0→main()→ PyInstaller bootstrap core ^[r2:entry0] - Archive resolution — locates the CFFI archive appended past the PE sections (overlay at
0x3CE00) ^[binwalk.txt] - Extraction — decompresses zlib blocks to
%TEMP%\_MEI<XXXX>^[strings.txt:115-116,236] - Python runtime bootstrap — loads
python27.dll, resolves CPython API procs (Py_Initialize,PyMarshal_ReadObjectFromString,PyEval_EvalCode, etc.) ^[strings.txt:119-212] - Script execution — unmarshals the embedded
__main__.pyand runs the Python scriptftpcrack^[strings.txt:104-111, 11629] - Binary drop — extracts
xmrig.exe(typexCFFI entry) to the temp directory and spawns it ^[strings.txt:11661] - Cleanup — deletes the temp directory on exit unless
_MEIPASS2is set ^[strings.txt:115]
Plain-zlib vs AES-encrypted sub-cluster
| Sibling | Size | Overlay Ratio | Encryption | Key visible? | Embedded miner? |
|---|---|---|---|---|---|
| 359fcf01 | 4.35 MB | ~94% | AES | Yes (1qazxsw23edcvfrN) |
Presumed (encrypted) |
| 058ab625 | 2.76 MB | ~91% | AES | Yes (1qazxsw23edcvfrN) |
Presumed (encrypted) |
| 5d9fe273 | 5.98 MB | 96.0% | None | N/A | Confirmed (xmrig.exe) |
| 325776ec | 3.61 MB | ~93% | None | N/A | Not confirmed (payload distinct from ftpcrack) |
The compilation timestamp, linker version, and bootloader strings are identical across all siblings — this is the same build campaign. The plain-zlib variant enables static recovery of payload names; the AES-encrypted variant requires key recovery or runtime detonation.
Payload composition (from TOC string recovery)
sftpcrack— Python script/module entry (types) ^[strings.txt:11629]xxmrig.exe— Embedded executable binary (typex), the actual XMRig miner ^[strings.txt:11661]bCrypto.Cipher._AES.pyd— PyCrypto AES extension module ^[strings.txt:11630]bpython27.dll— Python 2.7 runtime DLL ^[strings.txt:11646]bftpcrack.exe.manifest— Windows manifest for the spawned process ^[strings.txt:11638]opyi-windows-manifest-filename ftpcrack.exe.manifest— Manifest filename directive ^[strings.txt:11655]PYZ-00.pyz— Compiled Python zip archive ^[manual_analysis]
The presence of Crypto.Cipher._AES.pyd in the archive suggests the inner Python script may perform AES operations (e.g., decrypting a miner config or additional payload), but the outer bootloader itself does not use PyInstaller --key encryption.
Decompiled Behaviour
entry0(0x004079d3): MSVC CRT entry. Calls initialisers, thenmain(). No anti-debug or VM checks. Cyclomatic complexity 11, 21 basic blocks — standard CRT bootstrap. ^[r2:entry0]- Imports are limited to standard Win32 +
WS2_32.dll.ntohl(CRT-pulled, not actively used by the thin bootloader) ^[pefile.txt:249-373] - The
.rsrcsection contains 7 icon groups (PyInstaller default icon inheritance) ^[pefile.txt:159-492] - Entropy of
.textis 6.65,.rsrcis 7.26 — neither is packed; the heavy entropy lives in the zlib-compressed overlay. ^[pefile.txt:91-172]
C2 Infrastructure
Mining pool / wallet configuration is not statically observable in the outer bootloader. The xmrig.exe binary and any Python-side pool configs are inside the zlib-compressed CFFI archive; decompression of the full archive would be required to recover Stratum pool URLs or wallet addresses. ^[strings.txt]
Known overlay artefacts (pre-decompression):
xxmrig.exe— Confirmed XMRig miner executable (typexCFFI entry) ^[strings.txt:11661]Crypto.Cipher._AES.pyd— AES crypto module present in archive ^[strings.txt:11630]python27.dll— Python 2.7 runtime ^[strings.txt:11646]
Interesting Tidbits
xmrig.execonfirmation — Unlike previous siblings where the miner was presumed but not proven (AES encryption blocked static recovery), this plain-zlib variant exposesxxmrig.exedirectly in the CFFI TOC strings, confirming the coinminer attribution beyond the OpenCTI label. ^[strings.txt:11661]ftpcrackscript name reuse — The inner script is namedftpcrack(same as the build path seen in AES-encrypted siblings:F:\files\ftp\crack\exe\build\ftpcrack\). This suggests the actor reuses the same build directory and script name across coinminer and FTP cracker variants, or theftpcracklabel is a generic project name. ^[strings.txt:11629]- Python 2.7 runtime — All TOC entries reference
python27.dll, placing the build in the Python 2.x / PyInstaller 3.x era (consistent with Sep 2018). ^[strings.txt:11646] - No
pyimod00_crypto_keypayload — Thepyimod00_crypto_keyTOC entry exists but carries null key data (no AES key string), confirming--keywas NOT used. The entry is present because PyInstaller's bootloader always reserves it; in plain builds it is empty. ^[manual_analysis] - Largest sibling in cluster — At 5.98 MB, this is the largest PyInstaller sibling observed, with a 96% overlay ratio (6.02 MB of zlib archive). Only the divergent .NET crypter/loader
a80c26e2(7.45 MB) is larger, but that is a different build stack entirely. ^[manual_analysis] floss.txtwas a tool mis-invocation — triage script passed the binary path to--noinstead of thesamplepositional argument. ^[floss.txt]capa.txtfailed — default signature path missing on station. ^[capa.txt]- No YARA matches beyond generic PE — confirms no known mining-family signatures cover the outer bootloader shell. ^[triage.json]
How To Mess With It (Homelab Replication)
- Toolchain: Install Python 2.7 + PyInstaller 3.4 on a Windows research VM.
- Build a plain onefile payload:
pyinstaller --onefile --windowed your_script.py - Verify:
stringson the output EXE should show CFFI TOC entries (xxmrig.exe, etc.) in plaintext.binwalkshould show zlib blocks with no AES key module content. - Extract: Use
pyinstxtractor.pyor manually parse the CFFI cookie at the end of the file; the zlib entries decompress directly without key material. - Learning outcome: Understanding the difference between
--keyand plain PyInstaller builds enables faster triage: ifpyimod00_crypto_keyhas null payload, extraction is immediate.
Deployable Signatures
YARA rule
rule PyInstaller_Coinminer_Sep2018_Cluster {
meta:
description = "PyInstaller single-file coinminer cluster, Sep 2018 MSVC 14.0 build"
author = "PacketPursuit"
date = "2026-08-09"
sha256 = "5d9fe2735d4399d98e6e6a792b1feb26d6f2d9a5d77944ecacb4b4837e5e5fca"
strings:
$mz = { 4D 5A }
$pyi_boot = "PyInstaller: FormatMessageW failed" ascii
$pyi_boot2 = "Cannot open self %s or archive %s" ascii
$pyi_err = "Error detected starting Python VM." ascii
$pyimod = "pyimod00_crypto_key" ascii
$xmrig = "xmrig.exe" ascii
$ftpcrack = "ftpcrack" ascii
$python27 = "python27.dll" ascii
$mei = "MEI" ascii
condition:
$mz at 0 and
filesize > 400KB and
4 of ($pyi_boot, $pyi_boot2, $pyi_err, $pyimod) and
any of ($xmrig, $ftpcrack) and
$python27
}
IOC list
| Indicator | Value | Type |
|---|---|---|
| SHA-256 | 5d9fe2735d4399d98e6e6a792b1feb26d6f2d9a5d77944ecacb4b4837e5e5fca |
Hash |
| SHA-1 | 9f3359d3b34e1878c41f5ea1b1d0c7539df68061 |
Hash |
| MD5 | b890e400d99968920e1c17687e7ac67e |
Hash |
| Compilation timestamp | 2018-09-04 14:43:33 UTC |
Timestamp |
| Embedded binary | xmrig.exe |
Filename |
| Inner script | ftpcrack |
Module name |
| Runtime DLL | python27.dll |
Dependency |
| Temp directory | %TEMP%\_MEI<XXXX> |
Staging path |
| Overlay start | 0x3CE00 |
Raw offset |
| Overlay ratio | 96.0% | Percentage |
Behavioral fingerprint statement
This binary is a PyInstaller single-file PE32 GUI executable compiled with MSVC 14.0 on 2018-09-04. At runtime it extracts a zlib-compressed CFFI archive from its overlay (96% of file size) to %TEMP%\_MEI<XXXX>, loads python27.dll, and executes an embedded Python script named ftpcrack which spawns xmrig.exe from the same temp directory. No registry persistence or service installation is performed by the outer bootloader; persistence (if any) is handled by the inner Python payload. Network IOCs are not statically recoverable from the outer binary and require archive decompression or runtime detonation.
Detection Signatures
- MITRE ATT&CK: T1059.003 (Windows Command Shell — via Python script execution), T1074.001 (Data Staged — temp directory extraction), T1027.002 (Software Packing — PyInstaller compression)
- No capa results available (signature path missing on station) ^[capa.txt]
- No floss results available (tool mis-invocation) ^[floss.txt]
References
- Artifact ID:
f2815833-6374-4ee8-9fde-3c20605d82d7 - OpenCTI labels:
coinminer,exe,urlhaus - Related wiki pages: coinminer, pyinstaller-bootloader, python-packed-payload
Provenance
Analysis performed on pp-hermes (Lab1BU) using radare2, pefile, binwalk, and custom Python scripts. Static analysis only — no CAPE detonation available (no Windows guest). Tool versions: radare2 5.x, Python 3.12, binwalk 2.3.4. floss.txt and capa.txt were generated by the triage pipeline but contain tool errors, not malware data.