typeanalysisfamilycoinminerconfidencemediumcreated2026-08-14updated2026-08-14compilerpemalware-familycryptominerdefense-evasionpython-pyinstallerobfuscation
SHA-256: 6c321d46aa87d2b3d282042c886b3459b57caca76029c2d6c2f8f8e9a7e5f468

coinminer: 6c321d46 — smallest PyInstaller sibling yet, 320 KB, AES-encrypted hybrid ftpcrack+xmrig

Executive Summary

Twenty-sixth confirmed sibling in the September 2018 PyInstaller coinminer/ftpcrack cluster. At 320 KB it is the smallest sibling ever observed in this cluster — a stripped-down build with only 10 zlib streams and a 23.9% overlay ratio. It carries the same weak AES key (1qazxsw23edcvfrN), the same build path (F:\files\ftp\crack\exe\build\ftpcrack\), and the same compilation timestamp as all 25 prior siblings. Decompressed overlay confirms a hybrid ftpcrack+xmrig payload: FTP brute-force credential dictionaries (USER_DIC, PASSWORD_DIC, RANDOM_IP_POOL) coexist with XMRig miner deployment artefacts (taskkill /F /IM xmrig.exe, config.json, link.txt, stratum pool). Static-only; CAPE skipped — no Windows guest.

What It Is

  • File: PE32 executable (GUI) Intel 80386, 6 sections ^[file.txt]
  • Size: 327,640 bytes (320 KB) ^[triage.json] ^[exiftool.json]
  • SHA-256: 6c321d46aa87d2b3d282042c886b3459b57caca76029c2d6c2f8f8e9a7e5f468 ^[metadata.json]
  • Compiled: Tue Sep 4 14:43:33 2018 UTC ^[pefile.txt:34] ^[rabin2-info.txt:11]
  • Linker: MSVC 14.0 (Visual Studio 2015 RTM) ^[exiftool.json:18]
  • Signed: false; header checksum 0x00000000 ^[rabin2-info.txt:15]
  • ASLR / DEP: enabled (DllCharacteristics: 0x8140) ^[pefile.txt:74]
  • Subsystem: Windows GUI ^[file.txt]
  • Overlay: 78,296 bytes starting at raw offset 0x3CE00, 23.9% of file, AES-encrypted PyInstaller CFFI archive, 10 zlib streams ^[binwalk.txt:4-20] ^[terminal:overlay-analysis]
  • AES key: 1qazxsw23edcvfrN (left-hand QWERTY diagonal, identical to all AES-encrypted siblings) ^[terminal:stream0-decompress]
  • Build path: F:\files\ftp\crack\exe\build\ftpcrack\pyimod00_crypto_key.pyt ^[terminal:stream0-decompress]
  • Family: coinminer (OpenCTI label) ^[triage.json]

How It Works

Standard PyInstaller single-file C bootloader flow 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 every cluster sibling) ^[binwalk.txt]
  3. Decryption — first zlib chunk decompresses to pyimod00_crypto_key.pyt containing the AES key 1qazxsw23edcvfrN ^[terminal:stream0-decompress]
  4. Extraction — decrypts and decompresses remaining overlay entries to %TEMP%\_MEI<XXXX> using zlib/inflate 1.2.8 ^[strings.txt:113] ^[strings.txt:115]
  5. Python runtime bootstrap — loads python*.dll, resolves CPython API procs (Py_Initialize, PyMarshal_ReadObjectFromString, PyEval_EvalCode, etc.) ^[strings.txt:119-212]
  6. Script execution — unmarshals embedded ftpcrack.py code object and runs __main__.py ^[strings.txt:104-111]
  7. Cleanup — deletes temp directory on exit unless _MEIPASS2 is set ^[strings.txt:115]

Hybrid payload confirmed

Decompressed overlay stream 6 (offset 0x3b3e within overlay, 32,741 bytes) contains both:

  • FTP brute-force scanner: RANDOM_IP_POOL, USER_DIC, PASSWORD_DIC, ftplib.FTP, ICMP host-discovery (SendPingThr, __icmpPacket), multi-threaded queue_task dispatch. Built-in credential templates include {user}, {user}123, admin, root, test, www-data, password, 123456, P@ssw0rd!!, 1qaz2wsx, qwerty123456. ^[terminal:stream6-decompress]
  • XMRig miner deployment: taskkill /F /IM xmrig.exe, xmrig.exe staging, config.json, \link.txt, stratum, tcp://, miner, pool. ^[terminal:stream6-decompress]

Stream 7 (offset 0x6fc5 within overlay) decompresses to a UPX-packed PE32 DLL (16,384 bytes → 29,184 bytes unpacked) with Crypto.Cipher._AES import — the PyCryptoDome AES native extension required by PyInstaller's crypto layer. ^[terminal:stream7-decompress]

No anti-debug, no VM detection, no API hashing — stock PyInstaller circa 2018.

Cluster delta

Sibling Size Overlay Zlib blocks Encryption Hybrid? Key
801fbba1 799 KB ~570 KB — None No N/A
359fcf01 4.35 MB ~4.3 MB — AES No 1qazxsw23edcvfrN
2727eb40 387 KB 138 KB 10 None Yes N/A
c0bc0bff 2.27 MB ~2.13 MB 155 AES Yes 1qazxsw23edcvfrN
bc206453 4.7 MB ~4.68 MB 37 None Yes N/A
e019096c 1.18 MB ~963 KB 8 AES No 1qazxsw23edcvfrN
6c321d46 320 KB 78 KB 10 AES Yes 1qazxsw23edcvfrN

This sample is unique in the cluster for being simultaneously the smallest overall sibling, an AES-encrypted variant, and a confirmed hybrid ftpcrack+xmrig payload. Prior hybrid siblings were either plain-zlib (2727eb40, bc206453) or large AES-encrypted (c0bc0bff). This proves the builder pipeline can produce compact AES-encrypted hybrids.

Decompiled Behaviour

  • entry0 (0x004079d3): MSVC CRT entry. Initialises security cookie and SEH, calls main(), then CRT terminators. No anti-debug or VM checks. ^[r2:entry0]
  • main (0x00401000): Three calls — archive status resolution, UTF-8 argv conversion, then 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]
  • .rsrc section contains icon groups (PyInstaller default icon inheritance). ^[pefile.txt:159-534]
  • .gfids section (Guard CF IAT) present, confirming CFG-aware compilation. ^[pefile.txt:139-156]

C2 Infrastructure

Partially observable. Mining pool configuration is not hardcoded in the outer binary; link.txt is referenced as a runtime config file (likely fetched or bundled inside the _MEI extract). The outer binary contains only generic PyInstaller error strings and MSVC CRT locale data. Stratum/TCP pool URLs and wallet addresses live inside the AES-encrypted Python payload. ^[strings.txt]

Static recovery from decompressed overlay reveals:

  • stratum, tcp://, miner, pool — confirms Stratum protocol mining ^[terminal:stream6-decompress]
  • 127.0.0.1 — local interface reference for miner bind or test ^[terminal:stream6-decompress]
  • link.txt — external C2/pool config file reference ^[terminal:stream6-decompress]
  • No hardcoded attacker IP addresses or domains recovered from overlay.

Interesting Tidbits

  • Smallest sibling in cluster: At 320 KB with only 78 KB overlay, this is the most compact build observed. The builder pipeline clearly supports size-tuned outputs. ^[terminal:overlay-analysis]
  • AES-encrypted hybrid in a small package: Prior small siblings (2727eb40 at 387 KB) were plain-zlib. This sample shows AES encryption is not tied to large payloads. ^[terminal:stream0-decompress]
  • 10 zlib streams: More than e019096c (8 streams) but fewer than most siblings. The stream count does not correlate cleanly with file size — payload compression efficiency varies. ^[terminal:overlay-analysis]
  • Stream 7 = UPX-packed Crypto.Cipher._AES DLL: A 16 KB UPX-compressed PE32 DLL providing AES in CBC mode via PyCryptoDome. Unpacked size 29,184 bytes. This is a standard PyInstaller crypto dependency, not unique to this sample. ^[terminal:stream7-decompress]
  • Same QWERTY key and build path: The 1qazxsw23edcvfrN key and F:\files\ftp\crack\exe\build\ftpcrack\ path have now been observed across 14+ siblings spanning 2018–2026, confirming a long-lived, minimally maintained build pipeline. ^[terminal:stream0-decompress]
  • floss.txt is a tool-usage error (triage script passed the sample path to --no instead of the sample positional argument). ^[floss.txt]
  • capa.txt failed with missing default signature path — signatures were never installed on this station. ^[capa.txt]
  • No YARA matches beyond 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)

Toolchain: Visual Studio 2015 (MSVC 14.0) + PyInstaller 3.x + Python 2.7.15

  1. Install Python 2.7.15 and PyInstaller 3.4 on a Windows VM.
  2. Write ftpcrack.py combining ftplib.FTP brute-force scanning with subprocess.Popen to deploy xmrig.exe and a config.json.
  3. Build with AES: pyinstaller --onefile --windowed --key=1qazxsw23edcvfrN ftpcrack.py
  4. Verify: the resulting PE should show MSVC 14.0 linker, Sep 2018 timestamp (if backdated), 6 sections, overlay at 0x3CE00, and the AES key visible in the first decrypted zlib block.

Deployable Signatures

YARA rule

rule PyInstaller_Coinminer_Ftpcrack_2018_Cluster_AES_Hybrid {
    meta:
        description = "PyInstaller coinminer/ftpcrack Sep 2018 cluster — AES-encrypted overlay, weak QWERTY key, hybrid ftpcrack+xmrig"
        author = "PacketPursuit SOC"
        date = "2026-08-14"
        sha256 = "6c321d46aa87d2b3d282042c886b3459b57caca76029c2d6c2f8f8e9a7e5f468"
    strings:
        $pyi1 = "PyInstaller: FormatMessageW failed." ascii
        $pyi2 = "_MEIPASS" ascii
        $pyi3 = "ARCHIVE_STATUS" ascii
        $pyi4 = "Py_SetPythonHome" ascii
        $pyi5 = "Installing PYZ: Could not get sys.path" ascii
        $pyi6 = "pyi-windows-manifest-filename" ascii
        $pyi7 = "pyi-runtime-tmpdir" ascii
        $aes_key = "1qazxsw23edcvfrN" ascii
        $build_path = "F:\\files\\ftp\\crack\\exe\\build\\ftpcrack\\" ascii
        $ftpcrack1 = "RANDOM_IP_POOL" ascii
        $ftpcrack2 = "USER_DIC" ascii
        $ftpcrack3 = "PASSWORD_DIC" ascii
        $xmrig1 = "taskkill /F /IM xmrig.exe" ascii
        $xmrig2 = "config.json" ascii
        $xmrig3 = "link.txt" ascii
        $xmrig4 = "stratum" ascii
    condition:
        uint16(0) == 0x5A4D and
        ($pyi1 or $pyi2 or $pyi3) and
        ($aes_key or $build_path or ($ftpcrack1 and $ftpcrack2) or $xmrig1)
}

Sigma rule

title: PyInstaller Coinminer/Ftpcrack Sep 2018 Cluster Execution
logsource:
  product: windows
  category: process_creation
detection:
  selection:
    CommandLine|contains:
      - '_MEI'
      - 'pyi-runtime-tmpdir'
  selection_miner:
    CommandLine|contains:
      - 'xmrig.exe'
      - 'config.json'
      - 'link.txt'
  selection_ftp:
    CommandLine|contains:
      - 'ftpcrack'
      - 'RANDOM_IP_POOL'
      - 'USER_DIC'
      - 'PASSWORD_DIC'
  condition: selection and (selection_miner or selection_ftp)
falsepositives:
  - Legitimate PyInstaller applications (rare with these specific strings)
level: high

IOC list

Type Value Source
SHA-256 6c321d46aa87d2b3d282042c886b3459b57caca76029c2d6c2f8f8e9a7e5f468 metadata.json
SHA-256 (overlay stream 7, UPX-packed) e4b1ce31bd98e4e96e8e725fb9c26c02f1c8adbd3e2d2b2fe65491d6832d7540 pefile.txt:95
ssdeep 6144:MGXqfcjuI2GGMbNTBQkm5V0V3JXtiQNTKvrDXhrLU:RafcjuhaNTW5WVZdiCEfxnU ssdeep.txt
tlsh 3164D021B480C0B1D073143804F5C7B66D7DBD315B69D69BA3A87B790F702E1627AAEE tlsh.txt
File path %TEMP%\_MEI<XXXX> strings.txt:115
File path F:\files\ftp\crack\exe\build\ftpcrack\pyimod00_crypto_key.pyt terminal:stream0-decompress
Mutex/Resource pyi-windows-manifest-filename strings.txt:112
AES key 1qazxsw23edcvfrN terminal:stream0-decompress
Pool config link.txt (runtime) terminal:stream6-decompress
Pool config config.json (runtime) terminal:stream6-decompress
Stratum protocol stratum, tcp:// terminal:stream6-decompress
Miner binary xmrig.exe terminal:stream6-decompress
FTP target anonymous, admin, root, www-data, {user}, {user}123 terminal:stream6-decompress

Behavioral fingerprint statement

This binary is a 320 KB PE32 GUI executable compiled with MSVC 14.0 on 4 September 2018 at 14:43:33 UTC. It carries a 78 KB AES-encrypted overlay starting at raw offset 0x3CE00, containing 10 zlib-compressed streams. The first stream decrypts to reveal the AES key 1qazxsw23edcvfrN and build path F:\files\ftp\crack\exe\build\ftpcrack\. At runtime the PyInstaller C bootloader extracts the overlay to %TEMP%\_MEI<XXXX>, bootstraps Python 2.7, and executes an embedded ftpcrack.py module. The payload is dual-function: it brute-forces FTP credentials using built-in dictionaries (USER_DIC/PASSWORD_DIC) against randomly generated IP addresses, while simultaneously deploying an XMRig cryptocurrency miner (xmrig.exe) with Stratum pool configuration read from link.txt and config.json. No network indicators are hardcoded in the outer PE; all C2/pool config is runtime-resolved from the encrypted payload.

Detection Signatures

  • Mandiant capa: Not available (signature path missing on analysis station). ^[capa.txt]
  • Build fingerprint: MSVC 14.0 linker + Sep 4 2018 14:43:33 timestamp + 6 sections + 0x3CE00 overlay offset is a high-confidence cluster indicator across 26+ siblings. ^[pefile.txt:34] ^[rabin2-info.txt:11]
  • Entropy: .text 6.65, .rsrc 7.26, overlay high (AES-encrypted). ^[pefile.txt:91-172]

References

Provenance

  • file.txt — file(1) output, PE32 GUI Intel 80386
  • pefile.txt — pefile Python library full PE header dump (MSVC 14.0, 6 sections, overlay at 0x3CE00)
  • strings.txt — strings -a output (PyInstaller error strings, CRT locale data)
  • rabin2-info.txt — radare2 binary info (MSVC 14.0, Sep 4 2018, overlay=true)
  • binwalk.txt — binwalk entropy scan (zlib blocks, PNG icon, inflate 1.2.8 string)
  • exiftool.json — ExifTool PE metadata (LinkerVersion 14.0, Subsystem GUI)
  • metadata.json / triage.json — OpenCTI artefact metadata
  • floss.txt — flare-floss invocation error (triage script bug)
  • capa.txt — capa invocation error (missing signatures)
  • Manual overlay analysis via Python zlib decompression (10 streams, AES key recovery, ftpcrack+xmrig payload confirmation, UPX-packed DLL stream 7)

Tools: pefile 2023.x, radare2 5.x, binwalk 2.3.x, ExifTool 12.76, Python 3.11 zlib module, UPX 4.2.2