typeanalysisfamilycoinminerconfidencemediumcreated2026-08-09updated2026-08-09compilerpemalware-familycryptominerdefense-evasionpython-pyinstaller
SHA-256: 325776ec147f0e9087a068ea6aae7815c0081bb0df2cac23a80db82f1cd6ed59

coinminer: 325776ec — PyInstaller bootloader sibling, 3.6 MB, second-largest plain-zlib overlay in cluster

Executive Summary

Confirmed twenty-first sibling in the Sep 2018 PyInstaller coinminer cluster. Same MSVC 14.0 build fingerprint, same compilation second, same bootloader — only the overlay size differs (3.53 MB, 93.4% overlay ratio, second-largest plain-zlib variant after da02fd07). No AES encryption layer; plain zlib-compressed CFFI archive. No python27.dll or ftpcrack.py strings in the overlay, distinguishing it from the ftpcrack mislabel sub-cluster. Threat logic lives entirely in the embedded Python payload.

What It Is

  • File: PE32 executable (GUI) Intel 80386, 6 sections ^[file.txt]
  • Size: 3,784,242 bytes (3.61 MB) ^[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: 3,534,898 bytes starting at raw offset 0x3CE00, zlib-compressed (header 78 da) PyInstaller CFFI archive ^[binwalk.txt:5-48]
  • No AES encryption: no pyimod00_crypto_key marker anywhere in overlay or strings ^[strings.txt]
  • No python27.dll: not present in overlay; indicates Python 3.x runtime or a different dependency set from the ftpcrack sub-cluster ^[overlay scan]
  • Cluster: identical compilation timestamp and build path fragment (c:/PyI) to siblings 801fbba1, 39b67a79, 5047235c, 640ed5b5, d90f5359, and nineteen other confirmed PyInstaller cluster members ^[pefile.txt:34] ^[strings.txt:1095]

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:81] ^[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, 5047235c, and d90f5359 ^[strings.txt:1095].
  • The .rsrc section contains 7 icon groups (typical PyInstaller default icon inheritance) ^[pefile.txt:159-492].
  • Overlay ratio of 93.4% is the highest in the plain-zlib sub-cluster and second-highest overall (after AES-encrypted sibling f284c9aa at 95.9%).
  • 47 distinct zlib streams identified by binwalk in the overlay ^[binwalk.txt] — the most fragmented plain-zlib overlay observed in this cluster.
  • 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_325776ec {
    meta:
        description = "PyInstaller single-file bootloader (2018 MSVC 14.0 cluster) with large plain-zlib overlay — no AES"
        author = "Titus"
        date = "2026-08-09"
        sha256 = "325776ec147f0e9087a068ea6aae7815c0081bb0df2cac23a80db82f1cd6ed59"
    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-3MB..filesize) and
        filesize > 3MB and
        filesize < 5MB
}

Sigma rule

title: PyInstaller Coinminer Large Overlay 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 325776ec147f0e9087a068ea6aae7815c0081bb0df2cac23a80db82f1cd6ed59 Sample
SSDeep 49152:R3XTWsTBDNQ2iselXOfTITJR0nrtFPpXmfiSLI+VxBSTkqY3yZYIL4XKIF:RLVSThOfTCiFBXmfFs+JMHpo Cluster-shared PyInstaller fingerprint
TLSH 1D251211B4C1D0B2D036243509F5C6B5693EBD724B2686DBA3A83B755F303D1237AAEE Sample (same as d90f5359 — cluster-shared TLSH prefix)
File type PE32 executable (GUI) Intel 80386 Standard cluster format
Compilation 2018-09-04 14:43:33 UTC Identical across 21+ cluster members
Temp path %TEMP%\_MEI<XXXX> PyInstaller extraction directory
Overlay start 0x3CE00 Raw file offset
Overlay header 78 DA zlib best-compression
Build path fragment c:/PyI Confirmed in strings at line 1095

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 (3.53 MB, 93.4% of file) 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. The overlay does not contain python27.dll or ftpcrack.py, distinguishing this sample from the ftpcrack mislabel sub-cluster.

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: adc58c69-3a15-4abe-a9e5-bbc09ecac2c6 ^[triage.json]
  • OpenCTI labels: coinminer, exe, urlhaus ^[metadata.json]
  • Related analyses: /intel/analyses/801fbba19b4d4828191e87e7311480deaf81e84482dab70adf38d61afd01c1fa.html, /intel/analyses/d90f5359a9c56265374bc44cfb1d29de2af9fa2b4f3a80e8cad7342a7dfc48d3.html, /intel/analyses/da02fd0723caacead4f056ddcb30995785e52f60dbd5c5c00828de5b54a0aad9.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)