typeanalysisfamilycoinminerconfidencemediumcreated2026-06-11updated2026-06-11compilerpemalware-familycryptominerdefense-evasionpython-pyinstaller
SHA-256: fbfd2d94d8ee85145fc7bdc8e6c119f4c72018c06d8a9f3ebb4771a2fbd37a50

coinminer: fbfd2d94 — 2.37 MB PyInstaller sibling, Sep 2018 cluster, 89% zlib overlay

Executive Summary

Seventh confirmed sibling in the Sep 2018 PyInstaller coinminer cluster (see coinminer). Same MSVC 14.0 build fingerprint and compilation second as siblings 801fbba1, 39b67a79, 5047235c, 640ed5b5, 359fcf01, and b4cc27e3. At 2.37 MB it is the second-largest in the cluster, with a 2.12 MB zlib-compressed CFFI overlay containing 30+ compressed blocks. No mining indicators are visible in the outer binary; threat logic is entirely inside the extracted Python payload. Static-only analysis — CAPE skipped because no Windows guest is available.

What It Is

  • File: PE32 executable (GUI) Intel 80386, 6 sections ^[file.txt]
  • Size: 2,375,390 bytes (2.27 MB) ^[rabin2-info.txt]
  • Compiled: Tue Sep 4 14:43:33 2018 UTC ^[pefile.txt:34] ^[rabin2-info.txt]
  • Linker: MSVC 14.0 (Visual Studio 2015 RTM). Rich header: Linker1400 x1, Cvtres1400 x1, Utc1900_C(24210) x17, Utc1900_CPP(24123) x29, Utc1810_CPP(40116) x172, Masm1210(40116) x12, plus additional Import0 x73, Implib1100 x7, Utc1900_C x18, Utc1900_CPP x29, Masm1400 x18, Utc1810_C x24 ^[rabin2-info.txt] ^[rabin2 -H output]
  • Signed: false; header checksum 0x00000000 ^[rabin2-info.txt]
  • ASLR / DEP: enabled (DllCharacteristics: 0x8140 = DYNAMIC_BASE | NX_COMPAT | TERMINAL_SERVER_AWARE) ^[pefile.txt:74]
  • Subsystem: Windows GUI ^[file.txt]
  • Overlay: 2,126,046 bytes (89.4% of file) starting at raw offset 0x3CE00, zlib-compressed PyInstaller CFFI archive ^[binwalk.txt]
  • Cluster: same compilation timestamp and Rich-header fingerprint as the six prior siblings documented at coinminer

How It Works

Standard PyInstaller single-file C bootloader flow ^[r2:entry0] ^[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: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]

Per-sample delta: the 2.12 MB overlay is larger than siblings 801fbba1 (~570 KB), 640ed5b5 (~555 KB), and 5047235c (~1.15 MB), but smaller than 39b67a79 (3.8 MB) and 359fcf01 (4.35 MB). binwalk.txt identifies 30+ zlib-compressed blocks — the most fragmented overlay in the cluster — suggesting a very large CFFI archive with many individual members (Python .pyc modules, DLLs, data files). ^[binwalk.txt] There is no secondary PE append (unlike 5047235c) and no AES encryption wrapper (unlike 359fcf01). ^[/intel/analyses/5047235c1d599c8a4e39a073c8c71e6ac6579da3f03606f51cae9b17fe971858.html] ^[/intel/analyses/359fcf01a54b89eabcbfcecd734e2af60b6bfa19ffd7fcdd87b1e4ed15db599c.html]

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

  • The c:/PyI fragment at line 1095 of strings.txt confirms the same build environment as all prior siblings in this cluster. ^[strings.txt:1095]
  • The .rsrc section contains 7 icon groups (typical PyInstaller default Python icon inheritance) ^[pefile.txt:159-492].
  • Overlay fragmentation (30+ zlib blocks) is the highest observed in this cluster, implying the embedded payload includes many small files or a large base_library.zip with numerous modules. ^[binwalk.txt]
  • floss.txt and capa.txt are both non-functional (tool argument error and missing signatures respectively, same as prior siblings). ^[floss.txt] ^[capa.txt]
  • No YARA matches beyond the generic PE_File_Generic ^[yara.txt].
  • The Rich header's additional Import0 x73 and Implib1100 x7 counts suggest more import library objects were linked compared to the smallest siblings, consistent with a larger embedded Python runtime or more extensions. ^[rabin2 -H]

How To Mess With It (Homelab Replication)

Follow the recipe at pyinstaller-bootloader:

  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.
  5. To reproduce the large multi-block overlay, bundle many Python modules or a large base_library.zip inside the onefile build.

Deployable Signatures

YARA rule

rule PyInstallerBootloader_Coinminer_2018_Cluster_fbfd2d94 {
    meta:
        description = "PyInstaller single-file bootloader (2018 MSVC 14.0 cluster) with embedded Python coinminer payload"
        author = "Titus"
        date = "2026-06-11"
        sha256 = "fbfd2d94d8ee85145fc7bdc8e6c119f4c72018c06d8a9f3ebb4771a2fbd37a50"
    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
status: experimental
description: Detects child process execution from a PyInstaller _MEI temp directory, indicative of extracted coinminer payload
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: fbfd2d94d8ee85145fc7bdc8e6c119f4c72018c06d8a9f3ebb4771a2fbd37a50
  • Temp path pattern: %TEMP%\_MEI*\* (PyInstaller extraction directory)
  • Compilation timestamp: 2018-09-04 14:43:33 UTC (cluster indicator shared with seven siblings)
  • Overlay start: raw offset 0x3CE00 (249,344)
  • Overlay size: ~2.12 MB (89.4% of file)

Behavioural fingerprint

PE32 GUI executable compiled with MSVC 14.0 in Sep 2018. Contains a 2.12 MB zlib-compressed overlay (PyInstaller CFFI archive) with 30+ compressed blocks. 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. Identical bootloader to siblings 801fbba1, 39b67a79, 5047235c, 640ed5b5, 359fcf01, and b4cc27e3.

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: e64f2da9-94fa-4a8e-baa1-709f3b2d5a0c ^[metadata.json]
  • OpenCTI labels: coinminer, exe, urlhaus ^[triage.json]
  • Related wiki: coinminer
  • Related concept: pyinstaller-bootloader
  • 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
    • /intel/analyses/640ed5b536824541112a8b54488353d2938b4d0368a3ed14d41efff1d841c346.html — 735 KB sibling
    • /intel/analyses/359fcf01a54b89eabcbfcecd734e2af60b6bfa19ffd7fcdd87b1e4ed15db599c.html — 4.35 MB sibling with AES-encrypted overlay
    • /intel/analyses/b4cc27e365f44dd18593d7ca2b4a2d9df95268079beff47940f48cce21bfc979.html — 630 KB sibling with Python 2.7 runtime

Provenance

  • file.txtfile command (PE32 executable)
  • strings.txtstrings (4,505 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)
  • rabin2 -H — rich header dump (imported object counts)