135b3b8d21eee1397dad0cd496e1e8f978724063ab093ee619b9bfcee87e6537coinminer (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) callsmainat0x00401000^[r2:entry0] ^[r2:main] mainresolves Python runtime APIs viaGetProcAddressagainstpython27.dll^[strings.txt:118-212]- Bootloader creates temp directory, extracts CArchive, sets
_MEIPASS2, and callsPy_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.pycwith weak key1qazxsw23edcvfrN), 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
ftpcrackdirectory 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.dllandc:\\python27\\Lib\\site-packages\\PyInstallerpaths). ^[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
0x173C00is 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
_MEIpath - 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_Genericonly ^[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—filecommand (PE32 executable, 6 sections)exiftool.json— ExifTool 12.76 (PE metadata)pefile.txt— pefile 2023.2.7 (sections, imports, resources)strings.txt—stringscommand (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:--noflag collision, no results)triage.json— triage-fast pipeline v1metadata.json— artifact metadata from OpenCTIdynamic-analysis.md— CAPE status (skipped, no Windows guest)yara.txt— YARA scan (PE_File_Genericonly)- 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