typeanalysisfamilycoinminerconfidencemediumcreated2026-08-03updated2026-08-03malware-familycryptominercompilerpepython-pyinstallerdefense-evasion
SHA-256: 135b3b8d21eee1397dad0cd496e1e8f978724063ab093ee619b9bfcee87e6537

coinminer (mislabelled): 135b3b8d — PyInstaller ftpcrack sibling, 1.5 MB, 18 zlib streams, no AES

Executive Summary

PyInstaller single-file PE32 sharing the Sep 2018 ftpcrack build pipeline with the confirmed coinminer cluster and the 672 KB ftpcrack sibling 551d2b0e. Same MSVC 14.0 linker, same compilation second, same bootloader — but larger (1.5 MB), with 18 plain-zlib streams instead of 11 AES-encrypted streams. The embedded payload is ftpcrack.py, an FTP brute-force credential scanner with built-in user/password dictionaries, random IP generation, and multi-threaded credential spraying. No mining pool URLs, Stratum protocol, or wallet strings were recovered. OpenCTI coinminer label is a pipeline-level misattribution.

What It Is

Field Value
SHA-256 135b3b8d21eee1397dad0cd496e1e8f978724063ab093ee619b9bfcee87e6537
File type PE32 executable (GUI) Intel 80386, 6 sections ^[file.txt]
Size 1,572,672 bytes (1.5 MB)
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 ~1,197 KB starting at raw offset 0x3CE00, 18 zlib-compressed streams (plain, no AES) ^[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]
Secondary PE Appended at raw offset 0x173C00 (316 KB, also MSVC 14.0, 6 sections, Windows GUI) ^[binwalk.txt:30] ^[manual-pe-analysis]

The outer PE is a stock PyInstaller C bootloader compiled with MSVC 14.0. It 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

PyInstaller Bootloader → CArchive Extraction

The entry point at 0x004079d3 is the PyInstaller bootloader stub. Standard flow: resolve executable path via GetModuleFileNameW, allocate ARCHIVE_STATUS, open self as archive, iterate TOC entries, and decompress each stream to %TEMP%\_MEI<XXXX> using zlib/inflate 1.2.8. ^[strings.txt:79] ^[strings.txt:115] ^[r2:entry0] ^[r2:main]

main at 0x00401000 calls fcn.004049d0 (archive status resolution) then fcn.00402520 (extraction core). ^[r2:main] No anti-debug, no VM detection, no API hashing — stock PyInstaller circa 2018.

CArchive Overlay Structure

The ~1,197 KB overlay contains 18 zlib-compressed streams (plain zlib, no AES encryption layer, no pyimod00_crypto_key). Decompressed analysis of key streams:

Stream Offset Decompressed Content
1 0x3CE00 182 B PyInstaller runtime metadata
2 0x3CE92 234 B struct.pyc (Python stdlib)
3 0x3CF3B 2,480 B pyimod01_os_path.pyc — references c:\\python27\\Lib\\site-packages\\PyInstaller\\loader\\pyimod01_os_pa ^[manual-zlib-analysis]
4 0x3D3A6 11,725 B pyimod02_archive.pyc
5 0x3E4C3 22,100 B pyimod03_importers.pyc
6 0x40210 5,263 B _bootstrap.pyc
7 0x4093E 32,741 B ftpcrack.py — FTP brute-force cracker ^[manual-zlib-analysis]
8–17 Various Various Python 2.7 runtime extension modules (_AES.pyd, _hashlib.pyd, etc.) and support files
18 Various ~351 KB python27.dll (UPX-packed) ^[manual-zlib-analysis]

No pyimod00_crypto_key.pyc is present, confirming this variant uses plain zlib compression without the weak AES key (1qazxsw23edcvfrN) observed in the AES-encrypted siblings. ^[manual-key-search]

Stream 7: ftpcrack.py — The Real Payload

Stream 7 decompresses to 32,741 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 ^[manual-zlib-analysis]
  • Credential dictionaries: USER_DIC, PASSWORD_DIC, user_list ^[manual-zlib-analysis]
  • Password patterns: {user}, {user}123, {user}2016, password1, pass1234, 123456, www-data, ssh ^[manual-zlib-analysis]
  • IP generation: RANDOM_IP_POOL, get_random_ip, get_local_ipaddr, ip_addr_min, ip_addr_max, ipPool ^[manual-zlib-analysis]
  • Threading: threading, Thread, ThreadNum ^[manual-zlib-analysis]
  • Output format: username:%s,password:%s ^[manual-zlib-analysis]
  • Build path references: F:\\files\\ftp\\crack\\exe\\build\\ftpcrack\\ftpcrack.py ^[manual-zlib-analysis]
  • Windows service wrapper: StateftpService, Application State ftp Service, _svc_description_ ^[manual-zlib-analysis]
  • Port scanning: scan_port, portscan, Nscan, icmpSocket, ac_ip ^[manual-zlib-analysis]

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

Secondary PE at Offset 0x173C00

Binwalk identified a second PE header at raw offset 0x173C00 inside the overlay region. ^[binwalk.txt:30] Manual analysis confirms:

  • Valid DOS/NT header (MZ → PE\0\0) ^[manual-pe-analysis]
  • 6 sections, same as the outer PE ^[manual-pe-analysis]
  • Subsystem: Windows GUI ^[manual-pe-analysis]
  • No timestamp set (1970-01-01) ^[manual-pe-analysis]
  • MSVC 14.0 linker ^[manual-pe-analysis]

This is likely an embedded dependency (UPX-packed python27.dll or another extension module) appended before the main CArchive, a known PyInstaller packaging artefact when bundling large native extensions.

Cluster Relationship

This sample shares the exact same build fingerprint as the confirmed PyInstaller coinminer cluster and the 551d2b0e ftpcrack sibling:

  • Same compilation timestamp: Sep 4 2018 14:43:33 UTC ^[rabin2-info.txt:11]
  • Same MSVC 14.0 toolchain ^[exiftool.json]
  • Same build path: F:\\files\\ftp\\crack\\exe\\build\\ftpcrack\\ ^[manual-zlib-analysis]
  • Same PyInstaller bootloader version and runtime modules (Python 2.7, pyimod01_os_path, pyimod02_archive, pyimod03_importers)

The absence of an AES encryption layer distinguishes this sample from the AES-encrypted coinminer/ftpcrack siblings (e.g., 359fcf01, 058ab625, 983d2606). It is instead a plain-zlib variant from the same build pipeline, analogous to the plain-zlib coinminer sibling 1fed143e (4.14 MB, 44 zlib blocks).

Decompiled Behaviour

Static analysis via radare2 confirms standard PyInstaller bootloader behaviour:

  • Entry at 0x004079d3 (entry0) calls main at 0x00401000 ^[r2:entry0] ^[r2:main]
  • main resolves Python runtime APIs via GetProcAddress against python27.dll ^[strings.txt:118-212]
  • Bootloader creates temp directory, extracts CArchive, sets _MEIPASS2, and calls Py_Initialize ^[strings.txt:115-229]
  • No anti-debug, anti-VM, or sandbox evasion in the outer PE
  • Import surface: KERNEL32.dll (file ops, process creation, environment), USER32.dll (MessageBoxA/W), WS2_32.dll (ntohl) ^[strings.txt:472-501]

The WS2_32.dll import is minimal (ntohl only) and serves the PyInstaller bootloader, not the FTP payload directly. Actual socket operations happen inside the Python runtime.

C2 Infrastructure

None recovered. The FTP cracker does not beacon to a C2. It generates random IP addresses and scans for anonymous FTP or weak credentials locally. No hardcoded URLs, domains, or IPs were found in any decompressed stream.

Interesting Tidbits

  • Plain-zlib variant: Unlike the AES-encrypted siblings (which carry pyimod00_crypto_key.pyc with weak key 1qazxsw23edcvfrN), this sample uses plain zlib compression. This suggests the build pipeline had at least two output modes: encrypted and unencrypted. ^[manual-key-search]
  • Build pipeline reuse: The same ftpcrack directory was used for coinminers, AES-encrypted ftpcrack tools, and now this plain-zlib ftpcrack tool — confirming a multi-module crimeware toolkit. ^[manual-zlib-analysis] ^[entities/coinminer.md]
  • Python 2.7: Payload runs on Python 2.7.15 (based on python27.dll and c:\\python27\\Lib\\site-packages\\PyInstaller paths). ^[manual-zlib-analysis]
  • Service masquerade: The FTP cracker includes Windows service wrapper strings (StateftpService), suggesting it may install as a persistent background service. ^[manual-zlib-analysis]
  • No obfuscation: Python bytecode is unobfuscated beyond standard PyInstaller zlib compression. No PyArmor, no ConfuserEx.
  • Secondary PE: The embedded PE at 0x173C00 is unusual in size (316 KB) and may be a bundled UPX-packed DLL rather than a standard PyInstaller runtime module.

How To Mess With It (Homelab Replication)

Goal: Build a comparable PyInstaller single-file executable with an embedded Python FTP scanner.

# Install Python 2.7 and PyInstaller 3.x (matching 2018 era)
pip install pyinstaller==3.4

# Write a simple Python payload
cat > ftpcrack_demo.py << 'EOF'
import ftplib, random, threading, socket
# Simplified FTP brute-force logic
EOF

# Build with PyInstaller (no encryption, plain zlib)
pyinstaller --onefile --windowed ftpcrack_demo.py

# Compare capa fingerprint
capa dist/ftpcrack_demo.exe

The resulting binary should match this sample's capa fingerprint: PyInstaller bootloader, zlib overlay, python27.dll imports, _MEIPASS2 string, and GetProcAddress resolution pattern. The absence of pyimod00_crypto_key.pyc distinguishes it from the AES-encrypted siblings.

Deployable Signatures

YARA Rule

rule PyInstaller_FTPcrack_PlainZlib_Sep2018 {
    meta:
        description = "PyInstaller single-file PE from the Sep 2018 ftpcrack build pipeline, plain-zlib variant (no AES)"
        author = "Titus"
        date = "2026-08-03"
        sha256 = "135b3b8d21eee1397dad0cd496e1e8f978724063ab093ee619b9bfcee87e6537"
    strings:
        $pyi1 = "_MEIPASS2" ascii wide
        $pyi2 = "pyi-windows-manifest-filename" ascii wide
        $pyi3 = "Installing PYZ: Could not get sys.path" ascii wide
        $pyi4 = "Failed to execute script %s" ascii wide
        $pyi5 = "base_library.zip" ascii wide
        $inflate = "inflate 1.2.8 Copyright 1995-2013 Mark Adler" ascii wide
        $ftpcrack = "ftpcrack.pyt" ascii wide
        $user_dic = "USER_DIC" ascii wide
        $pass_dic = "PASSWORD_DIC" ascii wide
        $ftp_banner = /^220.*?ftp/ ascii wide
        $build_path = "F:\\files\\ftp\\crack\\exe\\build\\ftpcrack\\" ascii wide
    condition:
        uint16(0) == 0x5A4D and
        4 of ($pyi*) and
        $inflate and
        ($ftpcrack or $user_dic or $pass_dic or $ftp_banner or $build_path) and
        filesize > 1MB and
        filesize < 2MB
}

Sigma Rule

title: PyInstaller FTP Brute-Force Tool Execution (Plain-Zlib Variant)
logsource:
    product: windows
    category: process_creation
detection:
    selection:
        - ImageLoaded|contains:
            - 'python27.dll'
        - CommandLine|contains:
            - '_MEIPASS2'
    condition: selection
falsepositives:
    - Legitimate PyInstaller applications (rare with python27.dll in 2026+)
level: high

IOC List

Indicator Type Value
SHA-256 Hash 135b3b8d21eee1397dad0cd496e1e8f978724063ab093ee619b9bfcee87e6537
SSDeep Hash 24576:R3oCTWeZPEfxnW9yFdNM+lu8n5bpGLIe1hdp1YdGrksfC3fTItkgbVU+n0Stfsrx:R3XTWsOBDNQ2iselXOfTITJR0nr4u ^[triage.json]
Build path String F:\files\ftp\crack\exe\build\ftpcrack\
PE timestamp Timestamp 2018-09-04 14:43:33 UTC
Service name String StateftpService
Temp path pattern String %TEMP%\_MEI*\* (PyInstaller extraction directory)

Behavioral Fingerprint

This binary is a PyInstaller single-file PE with a ~1.2 MB zlib-compressed overlay containing 18 plain-zlib streams. On execution it extracts Python 2.7 runtime modules to a temp directory (_MEIPASS2), loads python27.dll, and executes embedded Python bytecode for an FTP brute-force scanner. It does not beacon to external C2 but instead generates random IP addresses and attempts credential-spray login against discovered FTP services. The outer PE has no anti-analysis features and relies entirely on the PyInstaller packer for obfuscation. Distinguished from AES-encrypted siblings by the absence of pyimod00_crypto_key.pyc.

Detection Signatures

  • MITRE ATT&CK
    • T1059.003 (Windows Command Shell) — possible batch/powershell launcher in embedded payload; not confirmed statically
    • 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 _MEI path
    • T1110.001 (Brute Force: Password Guessing) — FTP credential spraying from embedded dictionaries
    • T1046 (Network Service Scanning) — random IP generation and FTP banner detection
  • capa: N/A (capa signatures missing on this host, tool execution failed) ^[capa.txt]
  • yara: PE_File_Generic only ^[yara.txt]

References

  • entities/coinminer.md — PyInstaller coinminer cluster (shared build pipeline; includes AES-encrypted and plain-zlib siblings)
  • concepts/pyinstaller-bootloader — PyInstaller single-file C bootloader
  • concepts/python-packed-payload — Python logic hidden in PE overlay
  • /intel/analyses/551d2b0e5b243ef5abaa91e6776184ef0dc447a339609d60a3576aee31e8a822.html — AES-encrypted ftpcrack sibling (672 KB, 11 streams, weak key 1qazxsw23edcvfrN)
  • /intel/analyses/640ed5b536824541112a8b54488353d2938b4d0368a3ed14d41efff1d841c346.html — Plain-zlib coinminer sibling (735 KB, no AES)
  • /intel/analyses/1fed143e0f95ce0e7e6070d89745c74b6a086df0387a2e091720be20a27774b4.html — Plain-zlib coinminer sibling (4.14 MB, 44 zlib blocks)
  • OpenCTI artifact: 34f86758-2fe4-4c51-aa57-2174182ea031 ^[metadata.json]

Provenance

  • file.txt — file command (PE32 executable, 6 sections)
  • exiftool.json — ExifTool 12.76 (PE metadata)
  • pefile.txt — pefile 2023.2.7 (sections, imports, resources)
  • strings.txt — strings command (3064 lines)
  • rabin2-info.txt — radare2 5.9.4 (rabin2 -I)
  • binwalk.txt — binwalk 2.3.4 (embedded artefacts / zlib blocks)
  • capa.txt — flare-capa 7.0.0 (signature path error, no results)
  • floss.txt — flare-floss (execution error: --no flag collision, no results)
  • triage.json — triage-fast pipeline v1
  • metadata.json — artifact metadata from OpenCTI
  • dynamic-analysis.md — CAPE status (skipped, no Windows guest)
  • yara.txt — YARA scan (PE_File_Generic only)
  • radare2 analysis via MCP (mcp_radare2_open_file, analyze level 3, list_entrypoints, decompile_function)
  • Manual overlay extraction and zlib stream analysis performed via Python 3.12 zlib module

^[manual-zlib-analysis]: Manual Python zlib extraction of 18 streams from PE overlay; stream 7 confirmed as ftpcrack.py with USER_DIC, PASSWORD_DIC, RANDOM_IP_POOL, and F:\\files\\ftp\\crack\\exe\\build\\ftpcrack\\ build path ^[manual-pe-analysis]: Manual PE header parsing of secondary PE at offset 0x173C00 via Python struct module ^[manual-key-search]: Binary-wide search for 1qazxsw23edcvfrN, pyimod00_crypto_key, and crypto_key returned no hits