150e46523ae4a3e90ce949f15630b2f07d475d3a781188301edded1d527f03afphorpiex: 150e4652 — MSVCR90 self-contained sextortion spam bot with SMTP engine, ZIP constructor, and hardcoded BTC wallet
Executive Summary
A 23 KB PE32 MSVC9 stub, compiled the same day (2026-05-22 16:56:01 UTC) as sibling 17960bcb. Unlike the .rsrc-payload dropper 755bed07, this sample is a fully self-contained sextortion spam bot: it carries its own SMTP client state machine, constructs ZIP attachments in %TEMP%, downloads a payload via HTTP, and sends sextortion emails with a hardcoded Bitcoin wallet. No external payload staging is required at runtime.
What It Is
| Field | Value | Source |
|---|---|---|
| SHA-256 | 150e46523ae4a3e90ce949f15630b2f07d475d3a781188301edded1d527f03af |
triage.json ^[triage.json] |
| File type | PE32 executable (GUI) Intel 80386, 5 sections | file.txt ^[file.txt] |
| Size | 23 552 bytes | metadata.json ^[metadata.json] |
| Compile time | 2026-05-22 16:56:01 UTC | pefile.txt:34 ^[pefile.txt:34], rabin2-info.txt ^[rabin2-info.txt] |
| Linker | 9.0 (MSVC C runtime, MSVCR90.dll) | exiftool.json:18 ^[exiftool.json], strings.txt:77 ^[strings.txt:77] |
| Subsystem | Windows GUI | pefile.txt:67 ^[pefile.txt:67] |
| Signed | No | rabin2-info.txt:27 ^[rabin2-info.txt:27] |
| Overlay | None | binwalk.txt ^[binwalk.txt] |
| OpenCTI labels | dropped-by-phorpiex, exe, malware-bazaar |
metadata.json ^[metadata.json] |
| Family | phorpiex (medium confidence) | triage.json ^[triage.json] |
Family attribution
The compile timestamp matches sibling 17960bcb to the second, and the MSVCR90/Linker 9.0 build fingerprint matches 755bed07. Both carry the dropped-by-phorpiex MalwareBazaar label. The family entity page holds the shared build analysis; this report focuses on the spam-engine payload unique to this sample.
Decompiled Behavior
Entry point and CRT flow
entry0 at 0x00403927 is the standard MSVCR90 CRT startup (_tmainCRTStartup) ^[r2:entry0@0x00403927]. It initializes the SEH frame, calls GetStartupInfoA, runs _initterm_e then _initterm, and dispatches to main().
Notable: There is no initterm hijack in this binary. The _initterm table contains only standard CRT helpers, unlike 755bed07 where a custom payload function was registered there. ^[r2:entry0@0x00403927], ^[pefile.txt]
main() — spam engine bootstrap
main at 0x00402d70 ^[r2:main@0x00402d70]:
Sleep(2000)— brief delay.CreateMutexA("dd3ff3f3f")— single-instance mutex. IfGetLastError() == ERROR_ALREADY_EXISTS, the binary exits.- Deletes its own
Zone.IdentifierADS (<module_path>:Zone.Identifier) viaDeleteFileW. WSAStartup(0x0202, ...)— initializes Winsock.- Calls
fcn.00401c10(DNS MX resolver) then, if successful, enters the spam generation and delivery loop atfcn.004028f0.
String decryption (fcn.004013b0)
A two-pass decryptor used on several embedded strings (e.g. SMTP commands, template fragments):
- Pass 1: XOR each byte with a 4-byte cycle key:
0x54 0x6d 0x6c 0x72(ASCII"Tmlr") ^[r2:fcn.004013b0], ^[strings.txt:155] - Pass 2:
NOTeach resulting byte (bitwise inversion) ^[r2:fcn.004013b0]
This is a simple custom cipher; it does not defeat string extraction from memory but prevents naive static string matches on the raw binary.
External IP discovery (fcn.004014d0)
Opens an HTTP session to http://icanhazip.com/ using:
InternetOpenAwith a Chrome 96 user-agent ^[strings.txt:9], ^[r2:fcn.004014d0]InternetOpenUrlA→InternetReadFile- Parses the response for a dotted IPv4 string. On failure, falls back to
[0.0.0.0]^[r2:fcn.004014d0], ^[strings.txt:11]
DNS MX resolution (fcn.00401c10 / fcn.00401450)
- Queries
DnsQuery_Aforyahoo.comwith record type0x0F(DNS_TYPE_MX) ^[r2:fcn.00401c10], ^[strings.txt:15] - Iterates over MX records returned by
DnsQuery_A, storing them for the SMTP client DnsFreecleans up the result set
HTTP downloader (fcn.00401c80)
- Uses
InternetOpenWwith the same Chrome 96 UA ^[r2:fcn.00401c80] - Opens a URL (parameterized at runtime, not hardcoded in strings observed)
- Reads up to 1023 bytes via
InternetReadFileinto a buffer - Writes the buffer to a file created via
CreateFileW^[r2:fcn.00401c80]
The downloaded payload name is not statically visible; it is likely the Pervert.scr decoy screensaver referenced in the email template, or a secondary stage.
SMTP client state machine (fcn.00401d90)
A 7-case switch implementing a minimal SMTP dialogue:
| Case | Action |
|---|---|
| 0 | Read server banner; check for "ESMTP" via StrStrA ^[r2:fcn.00401d90:case0] |
| 2 | MAIL FROM: <%s>\r\n ^[r2:fcn.00401d90:case2] |
| 3 | RCPT TO: <%s>\r\n ^[r2:fcn.00401d90:case3] |
| 4 | DATA\r\n ^[r2:fcn.00401d90:case4] |
| 5 | Body assembly: generates Received: headers, From, To, Subject, Date, Message-ID, MIME multipart boundary, and the sextortion text. Inserts the external IP discovered earlier. Appends a ZIP attachment with base64 encoding. ^[r2:fcn.00401d90:case5] |
| 6 | QUIT / teardown ^[r2:fcn.00401d90:case6] |
The spam body is not fetched from a C2; the entire email template, including the $1200 ransom demand and BTC wallet address, is embedded in the .rdata section. ^[strings.txt:34-58], ^[r2:fcn.00401d90:case5]
ZIP attachment constructor (fcn.004030f0)
Builds a valid ZIP archive in %TEMP% incorporating:
- Local file header with DOS timestamp (generated from current system time via
GetSystemTime) ^[r2:fcn.00403470] - File name
Pervert.scr^[strings.txt:64], ^[r2:fcn.004030f0] - Standard CRC32 checksum computed via a pre-generated lookup table (polynomial
0xEDB88320) ^[r2:fcn.00402ea0] - Central directory record
- End-of-central-directory record
The ZIP is written to %TEMP%\<rand><rand><rand>.zip (three rand() % 1000 values) ^[r2:fcn.004028f0]. A companion .jpg file is also created with random filename for anti-detection obfuscation.
Spam generation orchestrator (fcn.004028f0)
- Sets up
srand(GetTickCount())for filename randomness. - Resolves
%TEMP%viaExpandEnvironmentStringsW. - Generates random filenames for
.zipand.jpg. - Calls
fcn.00401c80to download the payload (likelyPervert.scr). - Calls
fcn.004030f0to embed the payload into a ZIP. - Verifies file existence with
PathFileExistsW; retries afterSleep(1000)if missing. - Iterates MX records and invokes the SMTP engine for each target address.
- Cleans up temp files with
DeleteFileWbefore exiting the thread.
Build / RE
| Observation | Detail | Source |
|---|---|---|
| Compiler | MSVC 9.0 (Visual Studio 2008), linker 9.0 | rabin2-info.txt:11,17 ^[rabin2-info.txt] |
| CRT | MSVCR90.dll (static IAT import) | pefile.txt:239-282 ^[pefile.txt:239] |
| Language | C or C++ (no RTTI, no C++ exception tables) | pefile.txt:189-191 ^[pefile.txt:189] |
| Packing | None — no UPX, no custom packer. Sections align normally. | rabin2-info.txt:23 ^[rabin2-info.txt:23] |
| Anti-debug | IsDebuggerPresent at CRT startup (routine, no evasion response observed) |
pefile.txt:382 ^[pefile.txt:382] |
| Obfuscation | XOR+NOT string decryption with key "Tmlr" |
r2:fcn.004013b0 ^[r2:fcn.004013b0] |
| Signing | Unsigned | rabin2-info.txt:27 ^[rabin2-info.txt:27] |
| Resources | Standard RT_MANIFEST only; no hidden payload in .rsrc |
pefile.txt:397-436 ^[pefile.txt:397] |
| ASLR / DEP | Dynamic base (DllCharacteristics: 0x8140 → DYNAMIC_BASE, NX_COMPAT) |
pefile.txt:74 ^[pefile.txt:74] |
| Manifest | Requires Microsoft.VC90.CRT redistributable assembly |
strings.txt:156-168 ^[strings.txt:156] |
binwalk note: A ZIP end-of-central-directory signature was detected at 0x27F0 inside .text. This is a false positive — the binary does not store a ZIP archive; it constructs one at runtime via fcn.004030f0. The signature is incidental code bytes. ^[binwalk.txt]
Deploy / ATT&CK
| Technique | ID | Evidence |
|---|---|---|
| User Execution: Malicious File | T1204.002 | Spam-distributed executable, masquerading as benign software. |
| Application Layer Protocol: Web Protocols | T1071.001 | HTTP (InternetOpenUrlA / InternetReadFile) to fetch payload and external IP. ^[r2:fcn.004014d0], ^[r2:fcn.00401c80] |
| Application Layer Protocol: Mail Protocols | T1071.003 | Native SMTP client (socket/connect/send/recv) over port 25, with full RFC 2821 dialogue. ^[r2:fcn.00401d90] |
| Data Encoded: Base64 | T1132.001 | ZIP attachment transmitted as base64 inside MIME multipart body. ^[strings.txt:61], ^[r2:fcn.00401d90:case5] |
| Data Obfuscation: File Deletion | T1070.004 | Deletes generated temp files (DeleteFileW) and Zone.Identifier ADS after use. ^[r2:main@0x00402d70], ^[r2:fcn.004028f0] |
| Discovery: Internet Connection Discovery | T1016 | Resolves external IPv4 via icanhazip.com. ^[r2:fcn.004014d0] |
| Exfiltration: Automated Exfiltration | T1020 | Bulk email delivery of sextortion content to harvested addresses (inferred from SMTP RCPT TO loop). |
| Impact: Data Encrypted for Impact | T1486 | Extortion demand embedded in email body (not file encryption). ^[strings.txt:34-58] |
Persistence
None observed statically. The binary is a one-shot spam launcher; no registry keys, scheduled tasks, or service installations are present in the IAT or decompiled code.
C2 / Infrastructure
- External IP check:
http://icanhazip.com/^[strings.txt:10] - Payload download: HTTP via
WININET— URL is runtime-resolved (not hardcoded in strings). - SMTP target: MX records queried for
yahoo.com^[strings.txt:15]; actual recipient addresses are presumably provided at runtime (not in static strings). - No hardcoded C2 domain or IP for command and control.
Attribution
- Hardcoded BTC wallet:
1G1zmqks1vd9V3SdxCY71Hv9C7rHBLQbCY^[strings.txt:57] — a known Phorpiex/Trik sextortion wallet address seen in historical reporting. - Compile timestamp shared with sibling
17960bcb(same second) and near755bed07(same day, earlier hour), suggesting a single builder campaign. - Masquerade string:
YOU PERVERT! I RECORDED YOU!^[strings.txt:154]
Interesting Tidbits
- Self-contained vs. dropper:
755bed07is a dropper with a large.rsrcpayload. This sample (150e4652) and17960bcbare fully self-contained spam bots with no reflective payload. Same builder group, different product lines. - No C2 dependency for text: The entire sextortion narrative, including Bitcoin exchange URLs and wallet address, is embedded plaintext. The bot can operate fully offline after the initial payload download succeeds.
- Random filenames: Uses
srand(GetTickCount())for 3-digit random filenames, a simple sandbox evasion / anti-forensic measure. ^[r2:fcn.004028f0] - Standard ZIP format: The ZIP builder is textbook — Local File Header + File Data + CD + EOCD with proper CRC32. It is not a polyglot or malformed archive. ^[r2:fcn.004030f0]
- Mutex name:
"dd3ff3f3f"— repeated from17960bcb; likely a campaign identifier. ^[r2:main@0x00402d70] - CRT manifest dependency: Requires
Microsoft.VC90.CRTassembly; will fail to run on systems without the VS2008 redistributable unless the side-by-side runtime is present. ^[strings.txt:156]
How To Mess With It (Homelab Replication)
Goal: Reproduce a minimal SMTP-enabled spam bot with MSVC 9.0 build artifacts.
- Toolchain: Visual Studio 2008 (MSVC 9.0) or equivalent Windows SDK v6.0A.
- Project: Win32 GUI application, link against
msvcrt.lib/MSVCR90.dll. - Code skeleton:
- Standard
WinMainormainCRTStartup WSAStartup+socket+connectto port 25- Implement a 6-state
switchfor SMTP: HELO → MAIL FROM → RCPT TO → DATA → message body → QUIT - Use
CreateFileW+WriteFileto build a ZIP local file header, central dir, and EOCD - CRC32 via standard
0xEDB88320polynomial lookup table - Base64-encode the ZIP and embed into a MIME multipart message
- Standard
- String obfuscation: XOR with
{'T','m','l','r'}then bitwise NOT, decoded at runtime before SMTP send. - Verification: Compile and run
capa(when signatures are fixed). Expect hits on:send data via HTTP(WININET)send data via SMTP(Winsock)create or open file(CreateFileW for ZIP)resolve DNS(DnsQuery_A for MX)
Deployable Signatures
YARA rule
rule Phorpiex_Sextortion_SpamBot_MSVCR90
{
meta:
description = "Phorpiex self-contained sextortion spam bot (MSVCR90 build)"
author = "pp-hermes"
date = "2026-06-03"
hash = "150e46523ae4a3e90ce949f15630b2f07d475d3a781188301edded1d527f03af"
confidence = "medium"
strings:
$s1 = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" ascii wide
$s2 = "http://icanhazip.com/" ascii wide
$s3 = "MAIL FROM: %s\r\n" ascii
$s4 = "RCPT TO: <%s>\r\n" ascii
$s5 = "Content-Disposition: attachment; filename= \"Pervert.zip\"" ascii
$s6 = "My Bitcoin (BTC) wallet address is:" ascii
$s7 = "1G1zmqks1vd9V3SdxCY71Hv9C7rHBLQbCY" ascii
$s8 = "Pervert.scr" ascii wide
$s9 = "EHLO %s\r\n" ascii
$s10 = "HELO %s\r\n" ascii
$s11 = "yahoo.com" ascii
$s12 = "dd3ff3f3f" ascii
$ioc1 = { 54 6D 6C 72 } // XOR key "Tmlr"
$ioc2 = { 6E 2C 2F 2F } // NOT("Tmlr") fragment in .rdata
condition:
uint16(0) == 0x5A4D and
filesize > 20KB and filesize < 30KB and
6 of ($s*) and
any of ($ioc*)
}
Behavioral hunt query (Sigma-like)
# Detects execution of Phorpiex sextortion spam bot
# Matches process behavior: MZ + MSVCR90 + Zone.Identifier deletion + Winsock init
title: Phorpiex Sextortion Spam Bot Execution
detection:
selection:
- Image endswith '.exe'
- CommandLine|contains:
- 'Pervert.scr'
- 'dd3ff3f3f'
selection_api:
- API Call: DeleteFileW
Target endswith: ':Zone.Identifier'
- API Call: WSAStartup
selection_network:
- InitiatedConnection:
DestinationPort: 25
- InitiatedConnection:
RemoteUrl: 'icanhazip.com'
condition: selection or (selection_api and selection_network)
IOC list
| Type | Value | Context |
|---|---|---|
| SHA-256 | 150e46523ae4a3e90ce949f15630b2f07d475d3a781188301edded1d527f03af |
Sample hash |
| Mutex | dd3ff3f3f |
Single-instance check ^[r2:main@0x00402d70] |
| URL | http://icanhazip.com/ |
External IP check ^[strings.txt:10] |
| Domain | yahoo.com |
DNS MX query target ^[strings.txt:15] |
| BTC wallet | 1G1zmqks1vd9V3SdxCY71Hv9C7rHBLQbCY |
Hardcoded ransom demand ^[strings.txt:57] |
| Attachment name | Pervert.zip / Pervert.scr |
ZIP payload filename ^[strings.txt:64] |
| Temp path pattern | %TEMP%\<###><###><###>.zip |
Runtime-generated spam attachment ^[r2:fcn.004028f0] |
Behavioral fingerprint
This binary is a 20–25 KB PE32 MSVC9 GUI executable linked against MSVCR90. Upon launch it sleeps 2 seconds, creates a mutex dd3ff3f3f, deletes its own Zone.Identifier ADS, initializes Winsock, queries DNS MX records for yahoo.com, downloads an arbitrary payload via HTTP with a Chrome 96 user-agent from icanhazip.com, constructs a ZIP archive named Pervert.zip containing Pervert.scr in %TEMP%, computes CRC32 via a standard polynomial table, base64-encodes the ZIP, and transmits a multipart MIME sextortion email over raw TCP port 25 using a 6-state SMTP client. The email body contains a hardcoded Bitcoin wallet 1G1zmqks1vd9V3SdxCY71Hv9C7rHBLQbCY and demands $1200 USD.
Detection Signatures
| Capability | ATT&CK ID | Static Evidence |
|---|---|---|
| User Execution | T1204.002 | Spam-distributed PE, fake screensaver/social engineering subject line ^[strings.txt:62-63] |
| Web Protocols | T1071.001 | InternetOpenA, InternetOpenUrlA, InternetReadFile → http://icanhazip.com/ ^[r2:fcn.004014d0] |
| Mail Protocols | T1071.003 | socket, connect, send, recv on port 25; full SMTP state machine ^[r2:fcn.00401d90] |
| Data Encoding | T1132.001 | Base64 ZIP attachment inside MIME multipart body ^[strings.txt:61] |
| Data Obfuscation | T1070.004 | DeleteFileW on temp files and Zone.Identifier ADS ^[r2:main@0x00402d70] |
| Connection Discovery | T1016 | External IP via HTTP GET to icanhazip.com ^[r2:fcn.004014d0] |
References
- SHA-256 artifact:
150e46523ae4a3e90ce949f15630b2f07d475d3a781188301edded1d527f03af - Wiki entity: phorpiex
- Related deep-dive:
/intel/analyses/755bed077773b6cc7bea81ff624ded0554784accd5745d734742dafb73833b6b.html—.rsrc-payload dropper sibling - Related deep-dive:
/intel/analyses/17960bcb0d7fe57fac3a286fe7e8ba9b53783fdd53a2ef1132ae4d302d2c18f3.html— second sextortion spam bot sibling (same compile time)
Provenance
file.txt—filecommand output (PE32 executable)pefile.txt— pefile PE header dump (linker/compile time, imports, sections)strings.txt— raw ASCII/UNICODE strings (email template, BTC wallet, APIs)rabin2-info.txt— radare2 binary metadata (compiler, ASLR, signing)binwalk.txt— binwalk scan (false-positive ZIP ECD inside.text)radare2— decompilation (r2 level-3 analysis,pdcpseudo-C via MCP)exiftool.json— EXIFTool PE metadata (compile timestamp, manifest)triage.json— triage classification (dropped-by-phorpiex, deep tier)