typeanalysisfamilycoinminerconfidencemediumcreated2026-08-06updated2026-08-06compilerpemalware-familycryptominerdefense-evasionpython-pyinstaller
SHA-256: d90f5359a9c56265374bc44cfb1d29de2af9fa2b4f3a80e8cad7342a7dfc48d3

coinminer: d90f5359 — PyInstaller bootloader sibling, 984 KB, plain-zlib overlay (no AES)

Executive Summary

Confirmed sibling in the Sep 2018 PyInstaller coinminer cluster (see coinminer entity page for full cluster catalogue). Same MSVC 14.0 build fingerprint, same compilation second, same bootloader — only the overlay size differs (984 KB, 75.3% overlay ratio). No AES encryption layer; plain zlib-compressed CFFI archive. No mining indicators visible in the outer binary; threat logic lives in the embedded Python payload.

What It Is

  • File: PE32 executable (GUI) Intel 80386, 6 sections ^[file.txt]
  • Size: 1,007,493 bytes (983.9 KB) ^[triage.json]
  • Compiled: Tue Sep 4 14:43:33 2018 UTC ^[pefile.txt:34] ^[rabin2-info.txt:11]
  • Linker: MSVC 14.0 (MajorLinkerVersion 0xE, MinorLinkerVersion 0x0) ^[pefile.txt:45-46] ^[exiftool.json:18]
  • Signed: false; header checksum 0x00000000 ^[rabin2-info.txt:15]
  • ASLR / DEP: enabled (DllCharacteristics: 0x8140) ^[pefile.txt:74]
  • Subsystem: Windows GUI ^[rabin2-info.txt:32]
  • Overlay: ~758 KB starting at raw offset 0x3CE00, zlib-compressed (header 78 da) PyInstaller CFFI archive ^[binwalk.txt:11-22]
  • No AES encryption: no pyimod00_crypto_key marker anywhere in overlay or strings ^[strings.txt]
  • Cluster: identical compilation timestamp and Rich-header fingerprint to siblings 801fbba1, 39b67a79, 5047235c, 640ed5b5, and nineteen other confirmed PyInstaller cluster members ^[pefile.txt:34]

How It Works

Standard PyInstaller single-file C bootloader flow ^[r2:entry0] ^[r2:main] ^[r2:fcn.00402520]:

  1. CRT initialisation — entry0 (0x004079d3) sets up security cookie and SEH, then calls main() ^[r2:entry0]
  2. Archive resolution — main (0x00401000) resolves the executable path via fcn.004049d0, then hands control to fcn.00402520 ^[r2:main]
  3. Extraction — fcn.00402520 allocates an ARCHIVE_STATUS struct, checks the _MEIPASS2 environment variable, opens its own image as an archive, and decompresses the CFFI overlay to %TEMP%\_MEI<XXXX> using zlib/inflate 1.2.8 ^[r2:fcn.00402520] ^[strings.txt:79] ^[strings.txt:115] ^[strings.txt:292]
  4. Python runtime bootstrap — calls SetDllDirectoryW to the _MEI folder, loads python*.dll, resolves CPython C-API functions (Py_Initialize, PyMarshal_ReadObjectFromString, PyEval_EvalCode, etc.) via GetProcAddress, then unmarshals and executes __main__.py ^[strings.txt:119-212]
  5. Cleanup — removes the temp directory on exit unless _MEIPASS2 is set ^[strings.txt:115]

No anti-debug, no VM detection, no API hashing — stock PyInstaller circa 2018.

Decompiled Behaviour

  • entry0 (0x004079d3): MSVC CRT entry. Initialises security cookie, calls main(). ^[r2:entry0]
  • main (0x00401000): Resolves archive status struct and argv, then calls extraction routine. ^[r2:main]
  • fcn.00402520: PyInstaller bootstrap core. Allocates ARCHIVE_STATUS, checks _MEIPASS2, opens self as archive, iterates TOC, extracts to _MEI temp directory, sets DLL directory, then launches Python VM. ^[r2:fcn.00402520]

C2 Infrastructure

Not statically observable. The outer binary contains only PyInstaller bootloader strings and MSVC CRT locale data. Mining pool URLs, wallet addresses, and stratum configuration live inside the zlib-compressed overlay and are not recoverable without extracting the embedded Python payload. ^[strings.txt]

Interesting Tidbits

  • c:/PyI fragment at line 1095 of strings.txt confirms the same build environment as siblings 801fbba1, 640ed5b5, and 5047235c (^strings.txt:1095).
  • The .rsrc section contains 7 icon groups (typical PyInstaller default icon inheritance) ^[pefile.txt:159-492].
  • Overlay size of ~758 KB (75.3% ratio) places this sample between the 735 KB sibling (640ed5b5, 73.6% ratio) and the 1.5 MB sibling (135b3b8d, ~90% ratio), indicating the same build pipeline with variable payload sizes.
  • floss.txt and capa.txt are both non-functional (tool argument error and missing signatures respectively, same as prior siblings).
  • No YARA matches beyond the generic PE_File_Generic ^[yara.txt].
  • Import table includes WS2_32.dll.ntohl by ordinal ^[pefile.txt:372] ^[r2:imports] — minimal network surface in the bootloader itself.

How To Mess With It (Homelab Replication)

Follow the recipe at pyinstaller-bootloader and python-packed-payload:

  1. Install PyInstaller 3.4 on Windows with Python 2.7/3.6.
  2. pyinstaller --onefile --windowed --name=miner_stub your_script.py
  3. The resulting EXE will match this cluster's MSVC 14.0 linker fingerprint, _MEIPASS strings, and zlib overlay structure.
  4. Extract the payload with pyinstxtractor.py to inspect the embedded .pyc modules and mining configuration.

Deployable Signatures

YARA rule

rule PyInstallerBootloader_Coinminer_2018_Cluster_d90f5359 {
    meta:
        description = "PyInstaller single-file bootloader (2018 MSVC 14.0 cluster) with plain-zlib overlay — no AES"
        author = "Titus"
        date = "2026-08-06"
        sha256 = "d90f5359a9c56265374bc44cfb1d29de2af9fa2b4f3a80e8cad7342a7dfc48d3"
    strings:
        $pyi1 = "PyInstaller: FormatMessageW failed." ascii wide
        $pyi2 = "_MEIPASS2" ascii wide
        $pyi3 = "pyi-runtime-tmpdir" ascii wide
        $pyi4 = "Installing PYZ: Could not get sys.path" ascii wide
        $pyi5 = "Failed to execute script %s" ascii wide
        $pyi6 = "base_library.zip" ascii wide
        $inflate = "inflate 1.2.8 Copyright 1995-2013 Mark Adler " ascii wide
        $zlib_hdr = { 78 DA }
    condition:
        uint16(0) == 0x5a4d and
        4 of ($pyi*) and
        $inflate and
        $zlib_hdr in (filesize-800KB..filesize) and
        filesize > 700KB and
        filesize < 2MB
}

Sigma rule

title: PyInstaller Coinminer Extraction Detected
logsource:
    product: windows
    category: file_event
detection:
    selection:
        TargetFilename|contains: '_MEI'
        TargetFilename|endswith:
            - '.dll'
            - '.pyd'
            - '.py'
            - '.zip'
    condition: selection
falsepositives:
    - Legitimate PyInstaller applications
level: medium

IOC list

Type Value Notes
SHA256 d90f5359a9c56265374bc44cfb1d29de2af9fa2b4f3a80e8cad7342a7dfc48d3 Sample
SSDeep 24576:R3oCTWeZTfxnW9yFdNM+lu8n5bpGLIe1hdp1YdGrksfC30:R3XTWsTBDNQ2iselXO0 Cluster-shared PyInstaller fingerprint
TLSH 1D251211B4C1D0B2D036243509F5C6B5693EBD724B2686DBA3A83B755F303D1237AAEE Sample
File type PE32 executable (GUI) Intel 80386 Standard cluster format
Compilation 2018-09-04 14:43:33 UTC Identical across 20+ cluster members
Temp path %TEMP%\_MEI<XXXX> PyInstaller extraction directory
Overlay start 0x3CE00 Raw file offset
Overlay header 78 DA zlib best-compression

Behavioral fingerprint

This binary is a PyInstaller single-file PE32 GUI executable compiled with MSVC 14.0 on 4 September 2018. At runtime it extracts a zlib-compressed CFFI archive from its own overlay to a %TEMP%\_MEI<XXXX> directory, loads python*.dll from that directory, resolves CPython C-API functions via GetProcAddress, and executes embedded Python bytecode. No AES encryption layer is present. No anti-debug, VM detection, or API hashing. Network indicators are not statically recoverable from the outer binary.

Detection Signatures

ATT&CK Technique Evidence
T1059.003 — Windows Command Shell CreateProcessW spawned by PyInstaller bootstrap ^[strings.txt:239]
T1074.001 — Local Data Staging _MEI temp directory extraction ^[strings.txt:115]
T1106 — Execution through API CPython API resolution and PyEval_EvalCode invocation ^[strings.txt:197]
T1027.002 — Software Packing PyInstaller single-file bootloader with zlib-compressed overlay ^[binwalk.txt]
T1055 — Process Injection Potential in-memory Python payload execution (inferred from PyInstaller pattern)

References

  • Artifact ID: 49efeea8-bf4f-47e2-bcd4-30ede4d7b629 ^[triage.json]
  • OpenCTI labels: coinminer, exe, urlhaus ^[metadata.json]
  • Related analyses: /intel/analyses/801fbba19b4d4828191e87e7311480deaf81e84482dab70adf38d61afd01c1fa.html, /intel/analyses/640ed5b536824541112a8b54488353d2938b4d0368a3ed14d41efff1d841c346.html, /intel/analyses/e019096c77e4954d114365a7d77ae34c828e4bf5ab30e51c4be38dbc4b066612.html
  • Entity page: coinminer

Provenance

  • file.txt — file v5.44
  • exiftool.json — ExifTool v12.76
  • pefile.txt — pefile v2024.8.26
  • rabin2-info.txt — radare2 v5.9.8
  • strings.txt — strings from binutils
  • binwalk.txt — Binwalk v2.3.4
  • yara.txt — YARA v4.5.2 (rule PE_File_Generic)
  • ssdeep.txt — ssdeep
  • tlsh.txt — TLSH
  • triage.json — internal triage pipeline
  • r2:entry0, r2:main, r2:fcn.00402520, r2:imports — radare2 analysis (level 2)