familycoinminerconfidencemediummalware-familycryptominercompilerpepython-pyinstallerdefense-evasion
SHA-256: 6b8812689ae1496ffc34a77c73e2569c6bd66422d1365ea41e46a7b67669b280

coinminer (mislabelled): 6b881268 — PyInstaller ftpcrack sibling, 488 KB, 10 zlib streams, AES-encrypted overlay

Executive Summary

PyInstaller single-file PE32 sharing the Sep 2018 ftpcrack build pipeline with the confirmed coinminer cluster and the two prior ftpcrack siblings (551d2b0e, 135b3b8d). Same MSVC 14.0 linker, same compilation timestamp Sep 4 14:43:33 UTC, same weak QWERTY-derived AES key 1qazxsw23edcvfrN. At 488 KB it is the smallest AES-encrypted sibling in the cluster. The embedded payload is ftpcrack.py, an FTP brute-force credential scanner — not a cryptocurrency miner. OpenCTI coinminer label is a pipeline-level misattribution. Static-only (CAPE skipped — no Windows guest).

What It Is

Field Value
SHA-256 6b8812689ae1496ffc34a77c73e2569c6bd66422d1365ea41e46a7b67669b280
File type PE32 executable (GUI) Intel 80386, for MS Windows, 6 sections ^[file.txt]
Size 499,651 bytes (488 KB)
Linker MSVC 14.0 (Visual Studio 2015) ^[exiftool.json] ^[pefile.txt:32-34]
PE timestamp Tue Sep 4 14:43:33 2018 UTC ^[rabin2-info.txt:11]
Overlay 250,307 bytes (50.1% of file), 10 zlib-compressed AES-encrypted streams ^[binwalk.txt] ^[manual-zlib-analysis]
Sections .text, .rdata, .data, .gfids, .rsrc, .reloc (6) ^[pefile.txt:78-196]
Signed No ^[rabin2-info.txt:27]
Entry point 0x004079d3 (PyInstaller bootloader) ^[pefile.txt:50]

The outer PE is a standard PyInstaller C bootloader that extracts an embedded CArchive of zlib-compressed Python modules to a temporary _MEIPASS2 directory and bootstraps the Python 2.7 runtime. ^[strings.txt:115-229]

How It Works

This sample is a sibling of the confirmed PyInstaller coinminer cluster (coinminer), sharing the exact same build pipeline but carrying the ftpcrack.py payload module (ftpcrack).

PyInstaller Bootloader → CArchive Extraction

The entry point at 0x004079d3 is the PyInstaller bootloader stub. It resolves Python API addresses dynamically via GetProcAddress against python27.dll ^[strings.txt:118-182], sets _MEIPASS2 environment variable ^[strings.txt:115], creates a temporary directory, and extracts the embedded CArchive streams.

CArchive Overlay Structure

The 250 KB overlay contains 10 zlib-compressed AES-encrypted streams, decompressed and analysed:

Stream Offset Compressed Decompressed Content
1 0x0 ~182 B 182 B pyimod00_crypto_key.pyc — AES key 1qazxsw23edcvfrN ^[stream1-hex]
2 0x92 ~234 B 234 B struct.pyc (Python stdlib)
3 0x13b ~2,480 B 2,480 B PyInstaller os.path bootstrap module
4 0x5a6 ~11,725 B 11,725 B pyimod02_archive.pyc — FilePos thread-local module
5 0x16c3 ~22,100 B 22,100 B pyimod03_importers.pyc — PEP-302/451 importer
6 0x3410 ~5,263 B 5,263 B pyiboot01_bootstrap.pyc — _MEIPASS runtime setup
7 0x3b3e ~32,761 B 32,761 B ftpcrack.py — FTP brute-force cracker
8 0x6fde ~16,384 B 16,384 B UPX-packed PE (_hashlib.pyd or similar)
9 0xa763 ~1,050 B 1,050 B VC90 CRT assembly manifest XML
10 0xa983 ~37,888 B 37,888 B UPX-packed python27.dll

Notable delta from sibling 551d2b0e: this sample has 10 streams instead of 11, lacking the second _hashlib.pyd variant. It is also the smallest AES-encrypted sibling in the cluster at 488 KB (vs 672 KB for 551d2b0e).

Stream 7: ftpcrack.py — The Real Payload

Stream 7 decompresses to 32,761 bytes of Python 2.7 bytecode for an FTP brute-force credential scanner. Recovered strings include:

  • FTP banner regex: ^220.*?ftp|^220-|^220|^220 Service|^220 FileZilla ^[stream7-strings]
  • Credential dictionaries: USER_DIC, PASSWORD_DIC, user_list ^[stream7-strings]
  • Password patterns: {user}, {user}123, {user}2016, password1, P@ssw0rd!!, pass1234, 123qwe!@#, r00t ^[stream7-strings]
  • IP generation: RANDOM_IP_POOL, get_random_ip, get_local_ipaddr, ip_addr_min, ip_addr_max ^[stream7-strings]
  • Threading: threading, Thread, StateftpService ^[stream7-strings]
  • Build path: F:\files\ftp\crack\exe\build\ftpcrack\ftpcrack.py ^[stream7-strings]
  • Output paths: /Photo.scr, /Video.scr, /AV.scr, /Photo.lnk, /Video.lnk, /AV.lnk ^[stream7-strings]

This module implements random IP generation, FTP banner detection, and multi-threaded credential spraying against discovered FTP services. It is NOT a cryptocurrency miner.

Cluster Relationship

This sample shares the exact same build fingerprint as the confirmed PyInstaller coinminer cluster:

  • Same compilation timestamp: Sep 4 2018 14:43:33 UTC ^[rabin2-info.txt:11]
  • Same MSVC 14.0 toolchain ^[exiftool.json]
  • Same weak AES key: 1qazxsw23edcvfrN ^[stream1-hex]
  • Same build path: F:\files\ftp\crack\exe\build\ftpcrack\ ^[stream7-strings]
  • Same python27.dll runtime dependency ^[stream10-pe]

No mining pool URLs, Stratum protocol strings, or wallet addresses were recovered from any stream.

Decompiled Behavior

Ghidra was not run on this sample; the outer PE is an unmodified PyInstaller C bootloader stub identical to every sibling in the cluster. The decompile at entry0 (0x004079d3) shows the standard PyInstaller bootstrap: GetProcAddress resolution of python27.dll exports, _MEIPASS2 temp directory creation, and CreateProcessW launch of the embedded Python runtime. ^[r2:entry0]

Static analysis of the overlay streams (via zlib decompression) is the primary source of behavioural evidence. No anti-debug, anti-VM, or sandbox evasion was observed in the outer PE.

C2 Infrastructure

None. The payload is a self-contained FTP brute-force scanner with no external C2, download URLs, or beaconing. It generates random IP addresses and scans the internet for FTP services to attack.

Interesting Tidbits

  • Smallest AES-encrypted sibling: At 488 KB, this is the most compact variant in the ftpcrack build pipeline. The reduced size comes from fewer runtime modules (10 streams vs 11–18 in larger siblings). ^[manual-zlib-analysis]
  • No mining indicators: Zero stratum, pool, XMR, wallet, or cryptomining strings anywhere in the binary or overlay. The OpenCTI coinminer label is a pure misattribution. ^[strings.txt]
  • File staging paths: The payload references /Photo.scr, /Video.scr, and /AV.lnk as remote or local output paths, suggesting the tool may be used to stage or exfiltrate data from compromised FTP servers. ^[stream7-strings]
  • UPX-packed DLLs: Stream 8 and Stream 10 are UPX-compressed PEs. Stream 10 imports KERNEL32.DLL, MSVCR90.dll, ole32.dll, OLEAUT32.dll, and python27.dll, confirming it is the main Python runtime DLL. ^[stream10-pe]

How To Mess With It (Homelab Replication)

  • Toolchain: Python 2.7.15 + PyInstaller 3.x on Windows, MSVC 14.0 (VS 2015) for the C bootloader
  • Build path: F:\files\ftp\crack\exe\build\ftpcrack\
  • Key: PyInstaller AES encryption with key 1qazxsw23edcvfrN (weak QWERTY-derived passphrase)
  • Verification: Build any Python script with pyinstaller --key 1qazxsw23edcvfrN script.py. The resulting PE will have the same PyInstaller bootloader fingerprint, zlib/AES overlay structure, and pyimod00_crypto_key.pyc in the first CArchive stream.
  • What you'll learn: How PyInstaller packages Python apps into single-file PEs, how the --key option works (AES-encrypts each zlib stream individually with the same key), and why weak keys derived from keyboard walks are trivial to recover.

Deployable Signatures

YARA Rule

rule PyInstaller_ftpcrack_sibling_2018 : malware {
    meta:
        description = "PyInstaller ftpcrack build pipeline sibling (Sep 2018, weak AES key)"
        author = "PacketPursuit"
        date = "2026-08-05"
        sha256 = "6b8812689ae1496ffc34a77c73e2569c6bd66422d1365ea41e46a7b67669b280"
    strings:
        $pyi_boot = "Cannot open self %s or archive %s" ascii wide
        $meipass = "_MEIPASS2" ascii wide
        $py27 = "python27.dll" ascii wide
        $build_path = "F:\\files\\ftp\\crack\\exe\\build\\ftpcrack\\" ascii wide
        $key = "1qazxsw23edcvfrN" ascii wide
        $banner = "220 FileZilla" ascii wide
        $userdic = "USER_DIC" ascii wide
        $passdic = "PASSWORD_DIC" ascii wide
    condition:
        uint16(0) == 0x5A4D and
        $pyi_boot and
        $meipass and
        ($build_path or $key or ($banner and $userdic and $passdic)) and
        filesize < 600KB
}

Behavioral Hunt Query (Sigma)

title: PyInstaller ftpcrack payload execution
description: Detects execution of PyInstaller-ftpcrack siblings via temp-directory extraction and python27.dll load
status: experimental
logsource:
    category: process_creation
    product: windows
detection:
    selection:
        CommandLine|contains:
            - '_MEI'
            - 'python27.dll'
    selection2:
        ImageLoaded|endswith: 'python27.dll'
        ImageLoaded|contains: '_MEI'
    condition: selection or selection2
falsepositives:
    - Legacy Python 2.7 applications legitimately packaged with PyInstaller
level: medium

IOC List

Indicator Value Type
SHA-256 6b8812689ae1496ffc34a77c73e2569c6bd66422d1365ea41e46a7b67669b280 Hash
PE timestamp Tue Sep 4 14:43:33 2018 UTC Timestamp
Build path F:\files\ftp\crack\exe\build\ftpcrack\ Build artefact
AES key 1qazxsw23edcvfrN Weak encryption key
FTP banner 220 FileZilla, 220 Service Protocol fingerprint
User dictionary admin, root, www-data, user, test, ftp, administrator Credential spray
Password dictionary 123456, password, 123123, admin, P@ssw0rd!!, qwa123, r00t Credential spray
Temp path %TEMP%\_MEI* Extraction directory

Behavioral Fingerprint

This binary is a PyInstaller single-file PE32 (MSVC 14.0, Sep 2018 timestamp) that extracts 10 zlib-compressed AES-encrypted Python modules to a _MEI* temp directory, loads python27.dll, and executes an embedded FTP brute-force scanner. The scanner generates random IP addresses, probes TCP/21 for FTP banners matching 220 FileZilla or 220 Service, then sprays built-in USER_DIC/PASSWORD_DIC credentials in multi-threaded fashion. No external C2 or mining pool communication occurs. The weak AES key 1qazxsw23edcvfrN is recoverable from the first CArchive stream.

Detection Signatures

  • MITRE ATT&CK: T1059.006 (Python), T1074.001 (Data Staged: Local Data Staging), T1105 (Ingress Tool Transfer), T1110.001 (Brute Force: Password Guessing), T1046 (Network Service Scanning), T1574.002 (DLL Side-Loading)
  • CAPA: Not available — capa signatures missing on analysis host ^[capa.txt]

References

  • coinminer — Shared PyInstaller build pipeline; same author/toolkit
  • ftpcrack — Dedicated entity page for the FTP brute-force cluster
  • concepts/pyinstaller-bootloader — PyInstaller single-file C bootloader
  • concepts/python-packed-payload — Python logic hidden in PE overlay
  • OpenCTI: coinminer / exe / urlhaus (mislabelled)

Provenance

Analysis derived from static extraction of wiki/wiki/raw/analyses/6b8812689ae1496ffc34a77c73e2569c6bd66422d1365ea41e46a7b67669b280/ artefacts. Overlay streams decompressed via Python zlib.decompress() with raw offsets computed from PE section table. PE header parsed with pefile and radare2. No dynamic execution performed (CAPE skipped — no Windows guest). FLOSS failed with argument error ^[floss.txt].