typeanalysisfamilycoinminerconfidencemediumcreated2026-06-02updated2026-06-02compilerpemalware-familycryptominerdefense-evasionpython-pyinstaller
SHA-256: 640ed5b536824541112a8b54488353d2938b4d0368a3ed14d41efff1d841c346

coinminer: 640ed5b5 — PyInstaller bootloader sibling, 735 KB, September 2018 cluster

Executive Summary

Fourth confirmed sibling in the Sep 2018 PyInstaller coinminer cluster (see /intel/analyses/801fbba19b4d4828191e87e7311480deaf81e84482dab70adf38d61afd01c1fa.html, /intel/analyses/39b67a790b89fc8170703baaa98b29e1453a63416f0320bb3ae0f2936306f184.html, /intel/analyses/5047235c1d599c8a4e39a073c8c71e6ac6579da3f03606f51cae9b17fe971858.html). Same MSVC 14.0 build fingerprint, same compilation second, same bootloader — only the overlay size (and thus the embedded Python payload) differs. No mining indicators or C2 artefacts are visible in the outer binary.

What It Is

  • File: PE32 executable (GUI) Intel 80386, 6 sections ^[file.txt]
  • Size: 753,572 bytes (735.9 KB) ^[rabin2-info.txt]
  • Compiled: Tue Sep 4 14:43:33 2018 UTC ^[pefile.txt:34] ^[rabin2-info.txt]
  • Linker: MSVC 14.0. Rich header: Linker1400 x1, Cvtres1400 x1, Utc1900_C(24210) x17, Utc1900_CPP(24123) x29, Utc1810_CPP(40116) x172, Masm1210(40116) x12 ^[rabin2-info.txt]
  • Signed: false; header checksum 0x00000000 ^[rabin2-info.txt]
  • ASLR / DEP: enabled (DllCharacteristics: 0x8140) ^[pefile.txt:74]
  • Subsystem: Windows GUI
  • Overlay: ~555 KB starting at raw offset 0x3CE00, zlib-compressed PyInstaller CFFI archive ^[binwalk.txt]
  • Cluster: same compilation timestamp and Rich-header fingerprint as siblings 801fbba1, 39b67a79, and 5047235c

How It Works

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

  1. CRT initialisationentry0 sets up security cookie and SEH, then calls main() ^[r2:entry0]
  2. Archive resolutionmain() calls fcn.004049d0 to resolve the executable path, then hands control to fcn.00402520 ^[r2:main]
  3. Extractionfcn.00402520 allocates a 0x3008-byte 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]
  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]

Decompiled Behaviour

  • entry0 (0x004079d3): MSVC CRT entry. Initialises security cookie, calls main(). ^[r2:entry0]
  • main (0x00401000): Resolves archive status struct and argv via fcn.004049d0, then calls fcn.00402520. ^[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]

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

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 1090 of strings.txt confirms the same build environment as siblings 801fbba1 and 5047235c (^strings.txt:1090).
  • The .rsrc section contains 7 icon groups (typical PyInstaller default icon inheritance) ^[pefile.txt:159-492].
  • Overlay size of ~555 KB places this sample between the 800 KB sibling (801fbba1) and the 4.3 MB sibling (39b67a79), 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].

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_640ed5b5 {
    meta:
        description = "PyInstaller single-file bootloader (2018 MSVC 14.0 cluster) with embedded Python coinminer payload"
        author = "Titus"
        date = "2026-06-02"
        sha256 = "640ed5b536824541112a8b54488353d2938b4d0368a3ed14d41efff1d841c346"
    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
    condition:
        uint16(0) == 0x5a4d and
        4 of ($pyi*) and
        $inflate and
        filesize > 500KB and
        filesize < 5MB
}

Sigma rule

title: PyInstaller Coinminer Extraction Detected
logsource:
    product: windows
    category: process_creation
detection:
    selection:
        Image|startswith:
            - '%TEMP%\_MEI'
        ParentImage|endswith:
            - '.exe'
    condition: selection
falsepositives:
    - Legitimate PyInstaller applications
level: medium

IOC list

  • SHA-256: 640ed5b536824541112a8b54488353d2938b4d0368a3ed14d41efff1d841c346
  • Temp path pattern: %TEMP%\_MEI*\* (PyInstaller extraction directory)
  • Compilation timestamp: 2018-09-04 14:43:33 UTC (cluster indicator shared with siblings)

Behavioural fingerprint

PE32 GUI executable compiled with MSVC 14.0 in Sep 2018. Contains a ~555 KB zlib-compressed overlay (PyInstaller CFFI archive). At runtime extracts to a _MEI-prefixed temp directory, loads python*.dll, and executes embedded marshalled Python bytecode. Threat behaviour manifests in child processes spawned from the _MEI directory. No suspicious imports in the parent process itself. Near-identical bootloader to siblings 801fbba1, 39b67a79, and 5047235c.

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 _MEI path
  • Capa: non-functional (missing signatures). No ATT&CK mapping available.

References

  • Artifact ID: 9aa1585e-f44c-434e-a284-5b3b680170e2 ^[metadata.json]
  • OpenCTI labels: coinminer, exe, urlhaus ^[triage.json]
  • Related wiki: coinminer
  • Related concepts: pyinstaller-bootloader, python-packed-payload
  • Siblings:
    • /intel/analyses/801fbba19b4d4828191e87e7311480deaf81e84482dab70adf38d61afd01c1fa.html — 800 KB sibling (original cluster reference)
    • /intel/analyses/39b67a790b89fc8170703baaa98b29e1453a63416f0320bb3ae0f2936306f184.html — 4.3 MB sibling
    • /intel/analyses/5047235c1d599c8a4e39a073c8c71e6ac6579da3f03606f51cae9b17fe971858.html — 1.75 MB sibling with secondary PE append

Provenance

  • file.txtfile command (PE32 executable)
  • strings.txt — strings (1686 lines)
  • pefile.txtpefile Python module (sections, imports, resources)
  • rabin2-info.txt — radare2 rabin2 -I (binary metadata + rich header)
  • binwalk.txtbinwalk (embedded artifacts / zlib blocks)
  • exiftool.json — ExifTool PE metadata
  • floss.txt — flare-floss (tool argument error, no decoded output)
  • capa.txt — flare-capa (signature path error, no output)
  • triage.json — triage tier assignment
  • metadata.json — artifact metadata from OpenCTI
  • dynamic-analysis.md — CAPE status (skipped, no Windows guest)
  • R2 decompilation — radare2 via MCP (entry0, main, fcn.00402520, fcn.004049d0, fcn.00401bc0)