typeanalysisfamilycoinminerconfidencemediumcreated2026-07-16updated2026-07-16compilerpemalware-familycryptominerdefense-evasionpython-pyinstallerobfuscation
SHA-256: 983d2606de9089f78df7903daf6aa53eff6d87c2216d67fb840b637d053045e1

coinminer: 983d2606 — PyInstaller bootloader ninth sibling, Sep 2018 MSVC build, AES-encrypted overlay (2.43 MB)

Executive Summary

PyInstaller single-file PE32 dropper, ninth confirmed sibling in the September 2018 MSVC 2015 cluster. Shares the identical compilation timestamp, linker version, AES key (1qazxsw23edcvfrN), and build path (F:\\files\\ftp\\crack\\exe\\build\\ftpcrack\\) with siblings 359fcf01 and 058ab625. At 2.43 MB it is smaller than the 4.35 MB 359fcf01 twin but larger than the 2.76 MB 058ab625 sibling, confirming this is a variable-payload-size build campaign rather than a one-off. No mining pool strings are recoverable from the outer binary; threat logic is entirely inside the AES-encrypted PyInstaller CFFI archive. Static-only analysis (CAPE skipped — no Windows guest).

What It Is

  • File: PE32 executable (GUI) Intel 80386, 6 sections ^[file.txt]
  • Size: 2,432,727 bytes (2.43 MB) ^[rabin2-info.txt]
  • MD5: 706c4c903602526dc5dd98718d5ed146
  • SHA-1: c90a4a156e5f023a659826c116577474807c8849
  • Compiled: Tue Sep 4 14:43:33 2018 UTC ^[pefile.txt:34] ^[rabin2-info.txt]
  • Linker: MSVC 14.0 (Visual Studio 2015) ^[exiftool.json:18]
  • Signed: false; checksum 0x00000000 ^[rabin2-info.txt]
  • ASLR / DEP: enabled (DllCharacteristics: 0x8140) ^[pefile.txt:74]
  • Subsystem: Windows GUI ^[file.txt]
  • Overlay: 2,183,383 bytes starting at raw offset 0x3CE00, zlib-compressed CFFI archive with AES-encrypted entries ^[binwalk.txt] ^[manual_analysis]
  • Family: coinminer (OpenCTI label) ^[triage.json]

How It Works

This binary is a PyInstaller single-file bootloader that performs the same runtime sequence documented at pyinstaller-bootloader and in the cluster page coinminer:

  1. CRT initialisation — MSVC entry0main() → 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 and decrypts AES-encrypted entries to %TEMP%\_MEI<XXXX> ^[manual_analysis]
  4. Python runtime bootstrap — loads the Python DLL, resolves CPython API procs (Py_Initialize, PyMarshal_ReadObjectFromString, PyEval_EvalCode, etc.) ^[strings.txt:119-212]
  5. Script execution — unmarshals the embedded code object and runs __main__.py ^[strings.txt:104-111]
  6. Cleanup — deletes the temp directory on exit unless _MEIPASS2 is set ^[strings.txt:115]

AES encryption

The first overlay zlib chunk decompresses to reveal a pyimod00_crypto_key module containing the hardcoded AES key: ^[manual_analysis]

`1qazxsw23edcvfrN(
F:\\files\\ftp\\crack\\exe\\build\\ftpcrack\\pyimod00_crypto_key.pyt
<module>

The key 1qazxsw23edcvfrN is a left-hand QWERTY diagonal walking pattern. All remaining overlay entries are AES-encrypted; no further zlib chunks decompress independently without the key. ^[manual_analysis]

Cluster delta

Sibling Size Overlay Encryption Key visible? Build path
801fbba1 799 KB ~570 KB None N/A Not recovered
39b67a79 4.3 MB ~4.2 MB None N/A Not recovered
5047235c 1.75 MB ~1.6 MB None N/A Not recovered
640ed5b5 735 KB ~640 KB None N/A Not recovered
359fcf01 4.35 MB ~4.3 MB AES Yes (QWERTY key) F:\\files\\ftp\\crack\\exe\\build\\ftpcrack\\
b4cc27e3 630 KB ~540 KB None N/A Not recovered
fbfd2d94 2.37 MB ~2.2 MB None N/A Not recovered
058ab625 2.76 MB ~2.6 MB AES Yes (same QWERTY key) Same ftpcrack path
983d2606 2.43 MB ~2.18 MB AES Yes (same QWERTY key) Same ftpcrack path

The compilation timestamp, linker version, and bootloader strings are identical across all nine siblings — same build campaign, varying payload size and encryption toggle.

Decompiled Behaviour

  • entry0 (0x004079d3): MSVC CRT entry. Calls initialisers, then main(). No anti-debug or VM checks. ^[r2:entry0]
  • main (0x00401000): Three calls — archive status resolution, UTF-8 argv conversion, then fcn.00402520 (PyInstaller bootstrap core). ^[r2:main]
  • Imports are limited to standard Win32 + WS2_32.dll.ntohl (pulled in by CRT, 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 encrypted overlay. ^[pefile.txt:91-172]

C2 Infrastructure

Not statically observable. The outer binary contains only generic PyInstaller error strings and MSVC CRT locale strings. No hardcoded IPs, domains, pool URLs, or wallet addresses are recoverable without decrypting the overlay. Pool/C2 configuration is presumed to reside inside the AES-encrypted Python payload. ^[strings.txt]

Known overlay artefacts (pre-decryption):

  • pyimod00_crypto_key — AES key provider module (hardcoded key 1qazxsw23edcvfrN)
  • pyimod01_os_path — PyInstaller runtime path shim
  • pyiboot01_bootstrap — PyInstaller bootstrap entry point ^[manual_analysis]

Interesting Tidbits

  1. Ninth confirmed sibling — This sample confirms the Sep 2018 PyInstaller coinminer cluster now spans at least nine builds with sizes from 630 KB to 4.35 MB. The payload size varies by a factor of 7×, suggesting different miner versions, bundled runtimes, or secondary payloads. ^[manual_analysis]
  2. Same weak AES key across three siblings359fcf01, 058ab625, and 983d2606 all share 1qazxsw23edcvfrN. A single recovered key decrypts all three overlays, indicating either a single actor reusing key material or a builder kit with a hardcoded default. ^[manual_analysis]
  3. Author opsec failure — The build path F:\\files\\ftp\\crack\\exe\\build\\ftpcrack\\ is exposed in the first overlay entry of every AES-encrypted sibling. The project name ftpcrack and the exe\\build subdirectory structure match PyInstaller's default --onefile output. ^[manual_analysis]
  4. Python 2.7 era — Loader paths reference C:\\Python27\\Lib\\site-packages\\PyInstaller\\loader\\, placing the build in the Python 2.x / PyInstaller 3.x era (consistent with Sep 2018). ^[manual_analysis]
  5. No independent zlib decompression beyond first chunk — Unlike the unencrypted siblings (801fbba1, 39b67a79), where multiple zlib blocks decompress to plaintext Python, this sample's remaining overlay entries are AES-encrypted and fail zlib decompression. ^[manual_analysis]
  6. floss.txt tool error — The triage script passed the sample path to --no instead of the positional sample argument, yielding no decoded strings. ^[floss.txt]
  7. capa.txt failed — Default signature path missing on station. ^[capa.txt]
  8. YARA match only 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 an AES-encrypted onefile payload: pyinstaller --onefile --windowed --key '1qazxsw23edcvfrN' your_script.py
  • Verify: strings on the output EXE should show pyimod00_crypto_key.pyt. The overlay zlib chunks will decompress to AES key modules rather than plaintext Python.
  • Decrypt: Patch pyi-archive_viewer to use the recovered key, or modify PyInstaller's archive.py to skip the decryption loop and dump decrypted entries.
  • Learning outcome: Understanding the --key option means analysts cannot rely on simple zlib decompression; extraction requires the AES key or a runtime detonation with process-memory dumps.

Deployable Signatures

YARA rule

rule PyInstallerBootloader_AESCoinminer_2018_QwertyKey {
    meta:
        description = "PyInstaller single-file bootloader with AES-encrypted coinminer payload (2018 cluster, weak QWERTY-derived key)"
        author = "Titus"
        date = "2026-07-16"
        sha256 = "983d2606de9089f78df7903daf6aa53eff6d87c2216d67fb840b637d053045e1"
    strings:
        $pyi1 = "pyimod00_crypto_key" ascii wide
        $pyi2 = "PyInstaller: FormatMessageW failed." ascii wide
        $pyi3 = "_MEIPASS2" ascii wide
        $pyi4 = "Failed to execute script %s" ascii wide
        $pyi5 = "pyi-runtime-tmpdir" ascii wide
        $inflate = "inflate 1.2.8 Copyright 1995-2013 Mark Adler" ascii wide
        $key = "1qazxsw23edcvfrN" ascii wide
    condition:
        uint16(0) == 0x5a4d and
        $pyi1 and
        $key and
        3 of ($pyi2, $pyi3, $pyi4, $pyi5) and
        $inflate
}

Behavioral hunt query (KQL/SPL)

Target the child process spawned from %TEMP%\_MEI* within seconds of parent launch, combined with network connections to Stratum ports:

(process_name=*.exe AND parent_command_line LIKE "%_MEI%") 
AND (network_dest_port IN (3333, 4444, 45700, 45701, 5555, 7777) 
     OR network_dest_domain LIKE "%pool%" 
     OR network_dest_domain LIKE "%xmr%")

IOC list

Indicator Value Type
SHA-256 983d2606de9089f78df7903daf6aa53eff6d87c2216d67fb840b637d053045e1 Hash
MD5 706c4c903602526dc5dd98718d5ed146 Hash
SHA-1 c90a4a156e5f023a659826c116577474807c8849 Hash
AES key 1qazxsw23edcvfrN Decryption key
Build path F:\\files\\ftp\\crack\\exe\\build\\ftpcrack\\pyimod00_crypto_key.pyt Build artefact
Overlay start 0x3CE00 (raw) File offset
Overlay size 2,183,383 bytes File offset
Temp staging %TEMP%\\_MEI<XXXX> File path
Environment gate _MEIPASS2 Environment variable

Behavioral fingerprint

This binary is a stock PyInstaller single-file bootloader (MSVC 14.0, Sep 2018) that extracts an AES-encrypted Python payload to a _MEI-prefixed temp directory, bootstraps an embedded Python 2.7 runtime, and executes the marshalled script. No anti-analysis, no packing, no suspicious imports. Threat activity manifests entirely in child processes spawned from the temp directory, typically communicating with cryptocurrency mining pools over Stratum TCP ports (3333, 4444, 45700). The outer PE is benign infrastructure; the actual miner lives in the AES-encrypted overlay protected by a weak QWERTY-derived key.

Detection Signatures

  • capa — Not available; signature path missing on analysis station. ^[capa.txt]
  • YARA — Only generic PE_File_Generic match; no family-specific rule triggered on outer binary. ^[triage.json]

References

  • coinminer — Cluster entity page with full sibling list
  • pyinstaller-bootloader — Concept page for PyInstaller C bootloader behaviour
  • python-packed-payload — Concept page for Python-packed malware patterns
  • OpenCTI artifact: d6ca70d3-0072-4fee-a0d0-cb7aaab2943c
  • Sibling reports: 801fbba1, 39b67a79, 5047235c, 640ed5b5, 359fcf01, b4cc27e3, fbfd2d94, 058ab625

Provenance

Analysis derived from static triage artefacts (file.txt, pefile.txt, rabin2-info.txt, strings.txt, binwalk.txt, exiftool.json, floss.txt, capa.txt, yara.txt, triage.json) and manual radare2 decompilation of entry0 and main. Overlay analysis performed via direct Python zlib decompression of the raw binary at <sample 983d2606de90.bin>. No dynamic execution was performed (CAPE skipped — no Windows guest available).