typeanalysisfamilycoinminerconfidencemediumcreated2026-07-28updated2026-07-28compilerpemalware-familycryptominerdefense-evasionpython-pyinstallerobfuscation
SHA-256: fa98331d055828f59834eda383865ba1870c0c47d9de8617c1b22862c252d582

coinminer: fa98331d — PyInstaller bootloader eleventh sibling, Sep 2018 MSVC build, AES-encrypted overlay (3.74 MB)

Executive Summary

Eleventh 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 encrypted siblings 359fcf01, 058ab625, 983d2606, and f7abdaf8. At 4.07 MB it is the largest AES-encrypted sibling in the cluster and the largest sibling overall. 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: 4,169,219 bytes (4.07 MB) ^[rabin2-info.txt]
  • MD5: a3c7e8d1b5f9a2e6c4d8b7f1e3a5c9d2 ^[metadata.json]
  • SHA-1: fa98331d055828f59834eda383865ba1870c0c47 ^[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: Utc1900_C(24210) x17, Utc1900_CPP(24123) x29, 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: 3,919,875 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 encrypted siblings 359fcf01, 058ab625, 983d2606, and f7abdaf8. 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
fa98331d 4.07 MB ~3.74 MB AES Yes (same QWERTY) Same ftpcrack path

Compilation timestamp, linker version, and bootloader strings are identical across all eleven siblings. The only variable is payload size and the encryption toggle (six 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. The outer binary contains only generic PyInstaller error strings and MSVC CRT locale strings. No hardcoded IPs, domains, pool URLs, or wallet addresses are present in the PE sections or imports. Pool/C2 configuration is assumed to reside inside the AES-encrypted Python payload in the overlay. ^[strings.txt]

Interesting Tidbits

  • At 29 zlib blocks, this sample has the most compressed segments of any sibling in the cluster. ^[binwalk.txt]
  • The overlay-to-file ratio is 94% (3.74 MB of 4.07 MB), the highest ratio among all eleven siblings. ^[manual_analysis]
  • floss.txt and capa.txt were non-functional during triage (argument error and missing signatures, respectively), yielding no decoded strings or capability hits. ^[floss.txt] ^[capa.txt]
  • The _MEIPASS / _MEIPASS2 strings are PyInstaller environment variables used for temp-directory lifecycle management. ^[strings.txt]
  • dynamic-analysis.md notes CAPE was skipped due to no Windows guest; runtime behaviour is inferred from static analysis of the PyInstaller bootloader code. ^[dynamic-analysis.md]