typeanalysisfamilycoinminerconfidencemediumcreated2026-08-09updated2026-08-09compilerpemalware-familycryptominerpython-pyinstallerpython-packed-payload
SHA-256: 5d9fe2735d4399d98e6e6a792b1feb26d6f2d9a5d77944ecacb4b4837e5e5fca

coinminer: 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):

  1. CRT initialisation — MSVC entry0 → main() → PyInstaller bootstrap core ^[r2:entry0]
  2. Archive resolution — locates the CFFI archive appended past the PE sections (overlay at 0x3CE00) ^[binwalk.txt]
  3. Extraction — decompresses zlib blocks to %TEMP%\_MEI<XXXX> ^[strings.txt:115-116,236]
  4. Python runtime bootstrap — loads python27.dll, resolves CPython API procs (Py_Initialize, PyMarshal_ReadObjectFromString, PyEval_EvalCode, etc.) ^[strings.txt:119-212]
  5. Script execution — unmarshals the embedded __main__.py and runs the Python script ftpcrack ^[strings.txt:104-111, 11629]
  6. Binary drop — extracts xmrig.exe (type x CFFI entry) to the temp directory and spawns it ^[strings.txt:11661]
  7. Cleanup — deletes the temp directory on exit unless _MEIPASS2 is 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 (type s) ^[strings.txt:11629]
  • xxmrig.exe — Embedded executable binary (type x), 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, then main(). 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 .rsrc section contains 7 icon groups (PyInstaller default icon inheritance) ^[pefile.txt:159-492]
  • Entropy of .text is 6.65, .rsrc is 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 (type x CFFI 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

  1. xmrig.exe confirmation — Unlike previous siblings where the miner was presumed but not proven (AES encryption blocked static recovery), this plain-zlib variant exposes xxmrig.exe directly in the CFFI TOC strings, confirming the coinminer attribution beyond the OpenCTI label. ^[strings.txt:11661]
  2. ftpcrack script name reuse — The inner script is named ftpcrack (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 the ftpcrack label is a generic project name. ^[strings.txt:11629]
  3. 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]
  4. No pyimod00_crypto_key payload — The pyimod00_crypto_key TOC entry exists but carries null key data (no AES key string), confirming --key was NOT used. The entry is present because PyInstaller's bootloader always reserves it; in plain builds it is empty. ^[manual_analysis]
  5. 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]
  6. floss.txt was a tool mis-invocation — triage script passed the binary path to --no instead of the sample positional argument. ^[floss.txt]
  7. capa.txt failed — default signature path missing on station. ^[capa.txt]
  8. 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: strings on the output EXE should show CFFI TOC entries (xxmrig.exe, etc.) in plaintext. binwalk should show zlib blocks with no AES key module content.
  • Extract: Use pyinstxtractor.py or 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 --key and plain PyInstaller builds enables faster triage: if pyimod00_crypto_key has 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

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.