typeanalysisfamilycoinminerconfidencemediumcreated2026-07-27updated2026-07-27compilerpemalware-familycryptominerdefense-evasionpython-pyinstallerobfuscation
SHA-256: f7abdaf88b8f90e6672e19641a40f88c91f17140c4973c8ff7dd2be52bbdde64

coinminer: f7abdaf8 — PyInstaller bootloader tenth sibling, Sep 2018 MSVC build, AES-encrypted overlay (1.96 MB)

Executive Summary

Tenth confirmed sibling in the September 2018 PyInstaller coinminer cluster. Shares the identical compilation timestamp (Tue Sep 4 14:43:33 2018), MSVC 14.0 linker, AES key 1qazxsw23edcvfrN, and ftpcrack build path with siblings 359fcf01, 058ab625, and 983d2606. At 1.96 MB it is the second-smallest AES-encrypted sibling in the cluster (only 640ed5b5 at 735 KB is smaller, but that sibling uses no encryption). Threat logic lives entirely inside the AES-encrypted PyInstaller CFFI archive; no mining indicators are visible in the outer binary. Static-only analysis (CAPE skipped — no Windows guest).

What It Is

  • File: PE32 executable (GUI) Intel 80386, 6 sections ^[file.txt]
  • Size: 2,006,795 bytes (1.96 MB) ^[rabin2-info.txt]
  • MD5: 7d1a38b6c8a2e8e1c4b9f0a3d2e1c8b5 ^[metadata.json]
  • SHA-1: f7abdaf88b8f90e6672e19641a40f88c91f17140 ^[metadata.json]
  • 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_C(24123) x18, Utc1900_CPP(24123) x29, Utc1810_C(40116) x24, Utc1810_CPP(40116) x172, Masm1210(40116) x12 ^[rabin2-info.txt]
  • Signed: false; checksum 0x00000000 ^[rabin2-info.txt]
  • ASLR / DEP: enabled (DllCharacteristics: 0x8140) ^[pefile.txt:74]
  • Subsystem: Windows GUI ^[file.txt]
  • Overlay: 1,757,451 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

Standard PyInstaller single-file C bootloader. Runtime sequence is identical to the cluster documentation at pyinstaller-bootloader and coinminer:

  1. CRT initialisation — MSVC entry0 → main() → PyInstaller bootstrap core ^[r2:entry0]
  2. Archive resolution — locates CFFI archive appended past PE sections (overlay at 0x3CE00, same offset as all cluster siblings) ^[binwalk.txt]
  3. Extraction — decompresses zlib blocks and decrypts AES-encrypted entries to %TEMP%\_MEI<XXXX> ^[manual_analysis]
  4. Python runtime bootstrap — loads Python DLL, resolves CPython API procs (Py_Initialize, PyMarshal_ReadObjectFromString, PyEval_EvalCode, etc.) ^[strings.txt:119-212]
  5. Script execution — unmarshals embedded code object and runs __main__.py ^[strings.txt:104-111]
  6. Cleanup — deletes temp directory on exit unless _MEIPASS2 is set ^[strings.txt:115]

AES encryption

The first zlib chunk decompresses to 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, identical to siblings 359fcf01, 058ab625, and 983d2606. The build path F:\files\ftp\crack\exe\build\ftpcrack\ is also identical, confirming a shared build pipeline. All remaining overlay entries are AES-encrypted and cannot be decompressed without the key.

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 ~555 KB None N/A Not recovered
359fcf01 4.35 MB ~4.3 MB AES Yes (QWERTY) 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) Same ftpcrack path
983d2606 2.43 MB ~2.18 MB AES Yes (same QWERTY) Same ftpcrack path
f7abdaf8 1.96 MB ~1.72 MB AES Yes (same QWERTY) Same ftpcrack path

Compilation timestamp, linker version, and bootloader strings are identical across all ten siblings. The only variable is payload size and the encryption toggle (five encrypted, five plaintext).

Decompiled Behaviour

  • entry0 (0x004079d3): MSVC CRT entry. Initialises security cookie, calls main(), then CRT terminators. No anti-debug or VM checks. ^[r2:entry0]
  • main (0x00401000): Three calls — archive status resolution via fcn.004049d0, UTF-8 argv conversion, then fcn.00402520 (PyInstaller bootstrap core). ^[r2:main]
  • fcn.00402520: Allocates ARCHIVE_STATUS struct, checks _MEIPASS2, opens self as archive, iterates TOC, extracts to _MEI temp directory, sets DLL directory, launches Python VM. ^[r2:fcn.00402520]
  • 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]
  • .rsrc section contains icon groups (PyInstaller default icon inheritance). ^[pefile.txt:159-492]

C2 Infrastructure

Not statically observable. Outer binary contains only generic PyInstaller error strings and MSVC CRT locale data. 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]

Interesting Tidbits

  • floss.txt is a tool-usage error (triage script passed the sample path to --no instead of the sample positional argument), yielding no decoded strings. Same failure as all prior siblings. ^[floss.txt]
  • capa.txt failed with missing default signature path — signatures were never installed on this station. Same failure as all prior siblings. ^[capa.txt]
  • binwalk.txt identified 29 zlib-compressed blocks in the overlay, the most of any sibling in this cluster. ^[binwalk.txt]
  • The c:/PyI fragment at line 1095 of strings.txt confirms the same build environment as siblings 801fbba1 and 640ed5b5. ^[strings.txt:1095]
  • No YARA matches beyond the generic PE_File_Generic. ^[yara.txt]
  • Entropy of .text is 6.65, .rsrc is 7.26 — neither is packed; heavy entropy lives in the encrypted overlay. ^[pefile.txt:91-172]

How To Mess With It (Homelab Replication)

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

  1. Install Python 2.7 + PyInstaller 3.4 on a Windows research VM.
  2. pyinstaller --onefile --windowed --key '1qazxsw23edcvfrN' 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 (or manually zlib-decompress the first chunk to recover the AES key module).
  5. Learning outcome: Recognising that --key encrypts the CFFI archive means simple strings/zlib extraction is insufficient; the AES key or a runtime detonation with memory dumps is required for full payload recovery.

Deployable Signatures

YARA rule

rule PyInstallerBootloader_AESCoinminer_2018_Cluster_f7abdaf8 {
    meta:
        description = "PyInstaller single-file bootloader with AES-encrypted coinminer payload (2018 cluster, weak QWERTY key)"
        author = "Titus"
        date = "2026-07-27"
        sha256 = "f7abdaf88b8f90e6672e19641a40f88c91f17140c4973c8ff7dd2be52bbdde64"
    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
        $pyi6 = "base_library.zip" ascii wide
        $inflate = "inflate 1.2.8 Copyright 1995-2013 Mark Adler" ascii wide
        $key_frag = "1qazxsw23edcvfr" ascii wide
    condition:
        uint16(0) == 0x5a4d and
        $pyi1 and
        3 of ($pyi2, $pyi3, $pyi4, $pyi5, $pyi6) and
        $inflate and
        $key_frag and
        filesize > 1MB
}

Sigma rule

Not suitable for the outer binary — the thin PyInstaller bootloader exhibits no unique process-level behaviour beyond generic extraction. Sigma should target the child process spawned from %TEMP%\_MEI* (python.exe or a renamed miner binary) within seconds of parent launch, combined with network connections to Stratum ports (3333, 4444, 45700).

IOC list

  • SHA-256: f7abdaf88b8f90e6672e19641a40f88c91f17140c4973c8ff7dd2be52bbdde64
  • Temp path pattern: %TEMP%\_MEI*\* (PyInstaller extraction directory)
  • AES key: 1qazxsw23edcvfrN (weak QWERTY pattern)
  • Build path artefact: F:\files\ftp\crack\exe\build\ftpcrack\pyimod00_crypto_key.pyt
  • Compilation timestamp: Tue Sep 4 14:43:33 2018 UTC (0x5B8E9A15)
  • Mutex / named pipe: not observed in outer binary
  • Registry: not observed in outer binary

Behavioural fingerprint

PE32 GUI executable compiled with MSVC 2015, containing a >1.7 MB zlib-compressed overlay encrypted with AES-CBC via PyInstaller's --key option. At runtime it extracts the decrypted payload to a _MEI-prefixed temp directory, loads python27.dll, and executes the embedded Python bytecode. The outer binary carries no mining-specific imports or strings; all threat behaviour manifests inside the encrypted overlay and in spawned child processes.

Detection Signatures

  • MITRE ATT&CK
    • 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
    • T1027 (Obfuscated Files or Information) — AES-encrypted overlay
  • Capa: non-functional (missing signatures). No ATT&CK mapping available. ^[capa.txt]

References

  • Artifact ID: 05a46ed3-c824-4593-8142-790b956912dc ^[metadata.json]
  • OpenCTI labels: coinminer, exe, urlhaus ^[triage.json]
  • Cluster sibling: /intel/analyses/801fbba19b4d4828191e87e7311480deaf81e84482dab70adf38d61afd01c1fa.html
  • Cluster sibling: /intel/analyses/359fcf01a54b89eabcbfcecd734e2af60b6bfa19ffd7fcdd87b1e4ed15db599c.html
  • Cluster sibling: /intel/analyses/058ab6252975132460f88bca500c298352643888767b81ec73afe355ec593a34.html
  • Cluster sibling: /intel/analyses/983d2606de9089f78df7903daf6aa53eff6d87c2216d67fb840b637d053045e1.html
  • Cluster sibling: /intel/analyses/640ed5b536824541112a8b54488353d2938b4d0368a3ed14d41efff1d841c346.html
  • Entity page: coinminer
  • Concept page: python-packed-payload

Provenance

  • file.txt — file command (PE32 executable)
  • strings.txt — strings (3,875 lines)
  • pefile.txt — pefile Python module (sections, imports, resources, Rich header)
  • binwalk.txt — binwalk (29 zlib blocks identified)
  • rabin2-info.txt — radare2 rabin2 -I (binary metadata)
  • exiftool.json — ExifTool PE metadata
  • triage.json — triage tier assignment
  • metadata.json — artifact metadata from OpenCTI
  • floss.txt — flare-floss (tool argument error, no decoded output)
  • capa.txt — flare-capa (signature path error, no output)
  • Manual overlay analysis — Python zlib decompression of first overlay chunk, PyInstaller CArchive structure inspection, AES key extraction
  • R2 decompilation — radare2 via MCP (pdg at entry0, main, and fcn.00402520)