983d2606de9089f78df7903daf6aa53eff6d87c2216d67fb840b637d053045e1coinminer: 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:
- 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
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, thenmain(). No anti-debug or VM checks. ^[r2:entry0]main(0x00401000): Three calls — archive status resolution, UTF-8 argv conversion, thenfcn.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
.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 module (hardcoded key1qazxsw23edcvfrN)pyimod01_os_path— PyInstaller runtime path shimpyiboot01_bootstrap— PyInstaller bootstrap entry point ^[manual_analysis]
Interesting Tidbits
- 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]
- Same weak AES key across three siblings —
359fcf01,058ab625, and983d2606all share1qazxsw23edcvfrN. 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] - 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 nameftpcrackand theexe\\buildsubdirectory structure match PyInstaller's default--onefileoutput. ^[manual_analysis] - 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] - 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] floss.txttool error — The triage script passed the sample path to--noinstead of the positionalsampleargument, yielding no decoded strings. ^[floss.txt]capa.txtfailed — Default signature path missing on station. ^[capa.txt]- 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:
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_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_Genericmatch; 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).