359fcf01a54b89eabcbfcecd734e2af60b6bfa19ffd7fcdd87b1e4ed15db599ccoinminer: 359fcf01 — PyInstaller bootloader sibling, Sep 2018 MSVC build, AES-encrypted overlay with weak QWERTY key
Executive Summary
PyInstaller single-file PE32 dropper, fifth observed sibling in the September 2018 MSVC 2015 cluster. Shares an identical compilation timestamp, linker version, and bootloader behaviour with 801fbba1, 39b67a79, 5047235c, and 640ed5b5. The ~4.3 MB overlay is a zlib-compressed PyInstaller CFFI archive with an AES-encrypted payload (PyInstaller --key option), using the hardcoded key 1qazxsw23edcvfrN — a QWERTY-keyboard walking pattern with a trailing N. Build metadata reveals the author's local project path: F:\files\ftp\crack\exe\build\ftpcrack\. No mining pool strings are recoverable from the outer binary; threat logic is entirely contained inside the encrypted overlay.
What It Is
- File: PE32 executable (GUI) Intel 80386, 6 sections ^[file.txt]
- Size: 4,570,578 bytes (4.35 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) ^[exiftool.json:18]
- Signed: false ^[rabin2-info.txt]
- ASLR / DEP: enabled (
DllCharacteristics: 0x8140) ^[pefile.txt:74] - Subsystem: Windows GUI ^[file.txt]
- Overlay: 4,321,234 bytes starting at raw offset
0x3CE00, zlib-compressed CFFI archive with AES encryption ^[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:
- CRT initialisation — MSVC
entry0→main()→ PyInstaller bootstrap core ^[r2:entry0] - Archive resolution — locates the CFFI archive appended past the PE sections (overlay at
0x3CE00) ^[binwalk.txt] - Extraction — decompresses zlib blocks and decrypts AES-encrypted entries to
%TEMP%\_MEI<XXXX>^[manual_analysis] - Python runtime bootstrap — loads the Python DLL, resolves CPython API procs (
Py_Initialize,PyMarshal_ReadObjectFromString,PyEval_EvalCode, etc.) ^[strings.txt:119-212] - Script execution — unmarshals the embedded code object and runs
__main__.py^[strings.txt:104-111] - Cleanup — deletes the temp directory on exit unless
_MEIPASS2is set ^[strings.txt:115]
AES encryption
Unlike the earlier 801fbba1 sibling (no encryption), this sample was built with the PyInstaller --key option. The first overlay zlib chunk decompresses to reveal a pyimod00_crypto_key module containing a hardcoded AES key: ^[manual_analysis]
`1qazxsw23edcvfrN(
F:\files\ftp\crack\exe\build\ftpcrack\pyimod00_crypto_key.pyt
<module>
The key 1qazxsw23edcvfrN follows a QWERTY-keyboard diagonal walking pattern (1qazxsw23edcvfr) with a trailing N, a textbook example of weak, predictable key material. Because the archive is AES-encrypted, the remaining overlay entries cannot be decompressed statically without re-implementing PyInstaller's AES decryption loop, which is why no pool or miner strings are visible.
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\ |
The compilation timestamp, linker version, and bootloader strings are identical across all five siblings — this is the same build campaign, merely varying payload size and (in this case) adding AES encryption.
Decompiled Behaviour
entry0(0x004079d3): MSVC CRT entry. Calls initialisers, thenmain(). No anti-debug or VM checks. ^[r2:entry0]- Imports are limited to standard Win32 +
WS2_32.dll.ntohl(likely pulled in by the CRT, not actively used by the thin bootloader) ^[pefile.txt:249-373] - The
.rsrcsection contains 7 icon groups (PyInstaller default icon inheritance) ^[pefile.txt:159-492] - Entropy of
.textis 6.65,.rsrcis 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 modulepyimod01_os_path— PyInstaller runtime path shim (Python 2.7 path:C:\Python27\Lib\site-packages\PyInstaller\loader\) ^[manual_analysis]pyiboot01_bootstrap— PyInstaller bootstrap entry point ^[manual_analysis]
Interesting Tidbits
- Weak AES key —
1qazxsw23edcvfrNis a left-hand QWERTY zig-zag (1qaz,xsw2,3edc,vfr) plus a trailingN. Any analyst who recovers the key from this sample can decrypt all other payloads built with the same key by the same actor. ^[manual_analysis] - Author opsec failure — The build path
F:\files\ftp\crack\exe\build\ftpcrack\exposes the project nameftpcrack, suggesting this actor either masquerades as an FTP cracker tool or uses that as a working directory name. Theexe\build\ftpcracksubdirectory structure matches PyInstaller's default--onefilebuild output. ^[manual_analysis] - Python 2.7 runtime — 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] pyinstxtractorfailure — Both classic andngextractors failed because they read the CArchive cookie from the firstMEImagic occurrence (at0x1f330, inside a decompressed entry name) rather than the actual cookie near the end of the file. This is a known limitation when the overlay contains the stringMEIby chance. Manual zlib-decompression of the overlay was required. ^[manual_analysis]floss.txtwas a tool mis-invocation — the triage script passed the binary path to--noinstead of thesamplepositional argument. ^[floss.txt]capa.txtfailed — default signature path missing on station. ^[capa.txt]- No YARA matches beyond 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:
stringson the output EXE should showpyimod00_crypto_key.pyt. The overlay zlib chunks will decompress to AES key modules rather than plaintext Python. - Decrypt: Patch
pyi-archive_viewerto use the recovered key, or modify PyInstaller'sarchive.pyto skip the decryption loop and dump decrypted entries. - Learning outcome: Understanding the
--keyoption 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 {
meta:
description = "PyInstaller single-file bootloader with AES-encrypted coinminer payload (2018 cluster, weak QWERTY key)"
author = "Titus"
date = "2026-06-06"
sha256 = "359fcf01a54b89eabcbfcecd734e2af60b6bfa19ffd7fcdd87b1e4ed15db599c"
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
condition:
uint16(0) == 0x5a4d and
$pyi1 and
3 of ($pyi2, $pyi3, $pyi4, $pyi5) and
$inflate and
filesize > 2MB
}
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:
359fcf01a54b89eabcbfcecd734e2af60b6bfa19ffd7fcdd87b1e4ed15db599c - 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 - 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 >4 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
_MEIpath - T1027 (Obfuscated Files or Information) — AES-encrypted overlay
- Capa: non-functional (missing signatures). No ATT&CK mapping available. ^[capa.txt]
References
- Artifact ID:
4b4cf3bd-e051-456f-baf7-b8f5674ebf92^[metadata.json] - OpenCTI labels:
coinminer,exe,urlhaus^[triage.json] - Cluster sibling: /intel/analyses/801fbba19b4d4828191e87e7311480deaf81e84482dab70adf38d61afd01c1fa.html
- Cluster sibling: /intel/analyses/39b67a790b89fc8170703baaa98b29e1453a63416f0320bb3ae0f2936306f184.html
- Cluster sibling: /intel/analyses/5047235c1d599c8a4e39a073c8c71e6ac6579da3f03606f51cae9b17fe971858.html
- Cluster sibling: /intel/analyses/640ed5b536824541112a8b54488353d2938b4d0368a3ed14d41efff1d841c346.html
- Entity page: coinminer
- Concept page: python-packed-payload
Provenance
file.txt—filecommand (PE32 executable)strings.txt— strings (8,402 lines)pefile.txt—pefilePython module (sections, imports, resources)binwalk.txt—binwalk(embedded artefacts / zlib blocks)rabin2-info.txt— radare2rabin2 -I(binary metadata)exiftool.json— ExifTool PE metadatatriage.json— triage tier assignmentmetadata.json— artifact metadata from OpenCTIfloss.txt— flare-floss (tool argument error, no decoded output)capa.txt— flare-capa (signature path error, no output)- Manual overlay analysis — Python zlib decompression, PyInstaller CArchive structure inspection, AES key extraction
- R2 decompilation — radare2 via MCP (
pdgatentry0)