typeanalysisfamilyphorpiexconfidencehighcreated2026-09-02updated2026-09-02malware-familypespamimpactc2-protocoldefense-evasion
SHA-256: 5076fdc39445369e67daaccb7ec1699107a5f227aaaec978ec9d77d966124f3d

phorpiex: 5076fdc3 — MSVC9 sextortion spam bot $800 variant, mutex t2, earliest known build

Self-contained SMTP sextortion spam bot compiled 2026-05-29 12:15:01 UTC — the earliest confirmed build in the Phorpiex $800 sub-cluster, predating twin siblings dc2936ea (mutex t4, 12:33:18 UTC) and c3b1b4e4 (mutex t5, 12:34:02 UTC) by ~18 minutes. Identical toolchain, decrypt key, BTC wallet, and thread architecture; only the mutex string differs, confirming campaign-level parameter rotation on a shared builder.

What It Is

Field Value
SHA-256 5076fdc39445369e67daaccb7ec1699107a5f227aaaec978ec9d77d966124f3d
File PE32 executable (GUI) Intel 80386, 5 sections, 18,944 bytes ^[file.txt]
Linker MSVC 9.0 (Visual Studio 2008), MSVCR90.dll CRT ^[exiftool.json] ^[rabin2-info.txt]
Compiled 2026-05-29 12:15:01 UTC ^[exiftool.json]
Signed Unsigned ^[rabin2-info.txt]
Packing None — normal section layout, .text entropy 5.99 ^[pefile.txt] ^[binwalk.txt]
Family phorpiex — confirmed sibling of dc2936ea and c3b1b4e4 via identical decrypt key, BTC wallet, SMTP engine, and MSVC9/MSVCR90 toolchain.

How It Works

  1. Startup gate — Sleeps 2,000 ms, then creates mutex t2. Exits immediately if the mutex already exists (GetLastError() == 183) ^[r2:main].
  2. Evasion — Deletes its own Zone.Identifier ADS to strip the "Downloaded from Internet" marker ^[r2:main].
  3. MX resolution — Queries yahoo.com via DnsQuery_A (type 15 / MX) to resolve a relay target ^[strings.txt:16] ^[r2:fcn.00401790].
  4. String decrypt — Decrypts runtime strings with XOR+NOT using the 4-byte key Tmlr (0x54,0x6D,0x6C,0x72) ^[r2:fcn.00401030].
  5. Recipient list download — Generates a random %TEMP%\{rand}n.txt filename (srand(GetTickCount()) + rand()), downloads the recipient list via WinInet with a hardcoded Chrome/202 UA ^[strings.txt:17] ^[r2:fcn.004024e0].
  6. Thread storm — Spawns 5,000 threads in nested loops (100 outer × 50 inner). Each thread opens the temp file, uses x87 FPU RNG (fild/fdivrp/fcompp) to randomly select one recipient line, tokenises on : and //, and passes the result to the SMTP engine ^[r2:fcn.004024e0] ^[r2:fcn.00402340].
  7. SMTP delivery — Opens a TCP socket to the resolved MX, negotiates EHLO/HELO, emits MAIL FROM (spoofed as the victim's own address), RCPT TO, DATA, then sends the full sextortion template including the $800 demand and BTC wallet 1Gpu4hxcqpLZyjQ4JHZ6ieojyVBFj81Y3K ^[strings.txt:36-60] ^[r2:fcn.00401a10].
  8. Cleanup — Sleeps 20 s, deletes the temp file, then exits ^[r2:fcn.004024e0].

Decompiled Behavior

main @ 0x00402740 ^[r2:main]

  • Sleep(2000) — anti-emulation delay.
  • CreateMutexA(NULL, FALSE, "t2"); exits on ERROR_ALREADY_EXISTS.
  • Builds %s:Zone.Identifier and calls DeleteFileW.
  • WSAStartup(0x202, ...), then calls fcn.00401790 (DNS MX query).
  • Calls fcn.00401030 (string decrypt), then spawns one background thread at fcn.004024e0.
  • Falls into Sleep(0xcdfe600) (~60 hours) — main thread sleeps forever while the worker runs.

fcn.004024e0 (thread dispatcher) ^[r2:fcn.004024e0]

  • Seeds PRNG with GetTickCount(), formats %TEMP%\{rand}n.txt, downloads via fcn.00401900.
  • Outer loop 100 iterations; inner loop 50 iterations. Each inner iteration creates a thread at fcn.00402340 then sleeps rand() % 50 + 50 ms.
  • After loops: Sleep(20000), deletes temp file, exits.

fcn.00402340 (per-thread SMTP worker) ^[r2:fcn.00402340]

  • Opens temp file (_wfopen(L"r")), reads every line with fgets.
  • Uses x87 FPU (fild/fdivrp/fcompp) to probabilistically select one line.
  • Tokenises on : and // via strtok, calls fcn.00401a10.

fcn.00401a10 (SMTP client) ^[r2:fcn.00401a10]

  • socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) + connect to MX target.
  • Sets SO_KEEPALIVE. Implements a 7-case state machine:
    • Case 0: Search banner for ESMTP.
    • Case 1: Send HELO %s\r\n.
    • Case 2: Send MAIL FROM: %s\r\n.
    • Case 3: Send RCPT TO: <%s>\r\n.
    • Case 4: Send DATA\r\n.
    • Case 5: Assemble full email body (From, To, Subject, Date, Message-ID, MIME headers, sextortion plaintext).
    • Case 6: Send QUIT\r\n.

fcn.00401030 (string decrypt) ^[r2:fcn.00401030]

  • Loads 4-byte key Tmlr from .rdata.
  • Iterates: buf[i] = ~(buf[i] ^ key[i % 4]).

fcn.00401900 (WinInet downloader) ^[r2:fcn.00401900]

  • InternetOpenW with Chrome/202 UA.
  • Downloads URL (runtime-decrypted) into a 1023-byte buffer at 0x406130.
  • If arg_8h == 1, writes to disk via CreateFileW + WriteFile.

C2 Infrastructure

No traditional C2. Self-contained for spam delivery with two supporting network calls:

  • External IP discovery — http://icanhazip.com/ (hardcoded, used in email headers) ^[strings.txt:18].
  • MX resolution — yahoo.com via DnsQuery_A (type 15 / MX) ^[strings.txt:16].
  • Recipient list staging — WinInet-downloaded plaintext to %TEMP%\{rand}n.txt. URL is runtime-decrypted; not recovered statically.

Interesting Tidbits

  • Earliest $800 build: Compiled 12:15:01 UTC, predating the t4/t5 twins by ~18 minutes. This confirms the builder was actively generating mutex-rotated variants in a single campaign burst ^[exiftool.json].
  • Decrypt key Tmlr is Base64 for the lowercase letter i — likely a builder default ^[r2:fcn.00401030].
  • x87 FPU RNG for line selection is unusual in crimeware; copied from a legacy C tutorial ^[r2:fcn.00402340].
  • 5,000 threads is massive over-subscription for a 19 KB binary. Fire-and-forget delivery with no connection pooling ^[r2:fcn.004024e0].
  • Email template is English-only, identical to siblings 150e4652, edd6ad22, dc2936ea, and c3b1b4e4 — only BTC wallet and ransom amount vary, confirming a shared builder ^[strings.txt:36-60].
  • floss.txt and capa.txt both failed during triage (CLI argument error and missing signature database, respectively) ^[floss.txt] ^[capa.txt].
  • No persistence: no registry writes, scheduled tasks, or startup folder drops. One-shot execution.

How To Mess With It (Homelab Replication)

Toolchain: Visual Studio 2008 (MSVC 9.0) or modern MinGW-w64 with -lwininet -lws2_32 -ldnsapi.

Core C skeleton that reproduces the static fingerprint:

#include <windows.h>
#include <wininet.h>
#include <stdio.h>
#pragma comment(lib, "wininet.lib")

void decrypt(char *s) {
    const char key[] = "Tmlr";
    for (size_t i = 0; i < strlen(s); i++)
        s[i] = ~(s[i] ^ key[i % 4]);
}

int main() {
    Sleep(2000);
    HANDLE h = CreateMutexA(NULL, FALSE, "t2");
    if (GetLastError() == ERROR_ALREADY_EXISTS) return 0;
    // ... WSAStartup, DnsQuery_A, InternetOpenW, thread storm ...
    return 0;
}

Verification: Compile and inspect with rabin2 -i repro.exe. Expected imports: MSVCR90.dll, WININET.dll, WS2_32.dll, DNSAPI.dll, KERNEL32.dll, USER32.dll, SHLWAPI.dll. No ADVAPI32.dll, no CRYPT32.dll.

Deployable Signatures

YARA

rule phorpiex_sextortion_spam_bot_5076fdc3 {
    meta:
        description = "Phorpiex sextortion spam bot $800 variant (5076fdc3)"
        author      = "PacketPursuit"
        date        = "2026-09-02"
        sha256      = "5076fdc39445369e67daaccb7ec1699107a5f227aaaec978ec9d77d966124f3d"
    strings:
        $btc     = "1Gpu4hxcqpLZyjQ4JHZ6ieojyVBFj81Y3K" ascii wide
        $ua      = "Chrome/202.0.4664.110 Safari/537.36" ascii wide
        $mx      = "yahoo.com" ascii wide
        $ipcheck = "http://icanhazip.com/" ascii wide
        $ehlo    = "EHLO %s\r\n" ascii wide
        $mailfrom= "MAIL FROM: %s\r\n" ascii wide
        $subject = "YOU PERVERT! I RECORDED YOU!" ascii wide
        $mutex   = "t2" ascii wide
        $tmpl1   = "Unfortunately, there is some bad news for you." ascii wide
        $tmpl2   = "My Trojan allowed me to access your files, accounts, and your camera." ascii wide
        $tmpl3   = "I RECORDED YOU (through your camera) MASTURBATING!" ascii wide
        $tmpl4   = "All you need is $800 USD in Bitcoin (BTC)" ascii wide
    condition:
        uint16(0) == 0x5A4D and filesize < 30KB and
        4 of ($tmpl*) and
        ( ($btc and $ua) or ($mx and $ipcheck and $ehlo and $mailfrom) )
}

Behavioral Hunt Query (KQL)

// Process creates mutex t2 and imports WININET+WS2_32+DNSAPI
let phorpiex_mutex = "t2";
let phorpiex_btc   = "1Gpu4hxcqpLZyjQ4JHZ6ieojyVBFj81Y3K";
DeviceProcessEvents
| where InitiatingProcessCommandLine !contains "explorer.exe"
| where ProcessCommandLine contains phorpiex_mutex
   or ProcessCommandLine contains phorpiex_btc
// Memory-hunt variant: search process memory for BTC wallet string

IOC List

Indicator Value Notes
SHA-256 5076fdc39445369e67daaccb7ec1699107a5f227aaaec978ec9d77d966124f3d Canonical
ssdeep 192:CIISCngTBvblVPT0Y76fIkq2NleQY9T4KUSvu9zw+ggSmOiMbO5Ot1EdkF39TGJQ:UIblVP4Y/2N0bLu9JgPL7Nyav8U9c4 ^[ssdeep.txt]
tlsh E8824B0FF9418216D1E210B452B5867BDA799C72338458DBFBD08A9D0BA86E6FC3315F ^[tlsh.txt]
Mutex t2 Single-instance gate ^[r2:main]
BTC wallet 1Gpu4hxcqpLZyjQ4JHZ6ieojyVBFj81Y3K Campaign-specific ^[strings.txt:59]
Fake UA Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/202.0.4664.110 Safari/537.36 Impossible version ^[strings.txt:17]
MX target yahoo.com DNS query target ^[strings.txt:16]
IP check http://icanhazip.com/ External IP discovery ^[strings.txt:18]
Temp file %TEMP%\{rand}n.txt Random numeric suffix via srand(GetTickCount()) ^[r2:fcn.004024e0]
Subject YOU PERVERT! I RECORDED YOU! Window title / email subject ^[strings.txt:146]

Behavioral Fingerprint

This PE32 GUI binary, compiled with MSVC 9.0 and linked against MSVCR90.dll, imports WININET.dll, WS2_32.dll, and DNSAPI.dll but not ADVAPI32.dll or CRYPT32.dll. Upon execution it creates mutex t2, deletes its own Zone.Identifier ADS, queries yahoo.com via DnsQuery_A for MX records, downloads a recipient list over HTTP using a hardcoded Chrome/202 UA, then spawns 5,000 threads that open TCP/25 sockets and emit SMTP EHLO, MAIL FROM, and RCPT TO commands followed by a sextortion email body demanding $800 in BTC to wallet 1Gpu4hxcqpLZyjQ4JHZ6ieojyVBFj81Y3K. It writes a temporary %TEMP%\{rand}n.txt file and deletes it after the campaign loop.

Detection Signatures

  • YARA: Suspicious_Wininet_Imports (triage hit) ^[yara.txt].
  • capa: Failed — signature database not installed during triage ^[capa.txt].
  • floss: Failed — CLI argument parsing error (--no flag) ^[floss.txt].

References

  • phorpiex — Crimeware botnet/dropper family; umbrella label for spam-delivered droppers and sextortion spam bots.
  • dc2936ea — Phorpiex sibling ($800 variant, mutex t4, twin build, compiled ~18 min later) ^[/intel/analyses/dc2936ea921e2cbc56b315d1c08d2c3e1ce4f4e22524c9bdee12a8ea2e037e5a.html]
  • c3b1b4e4 — Phorpiex sibling ($800 variant, mutex t5, twin build, compiled ~19 min later) ^[/intel/analyses/c3b1b4e4eab9589b9132c57cc6dc9f26b93fee922b78923780cb79ce705f106b.html]
  • edd6ad22 — Phorpiex sibling ($800 variant, mutex etyueu, identical toolchain) ^[/intel/analyses/edd6ad227595d25c2cf6cf41d2ac9b6640b2e977aabb2d07eea58fa500b6db19.html]
  • 150e4652 — Phorpiex sibling ($1200 variant, identical SMTP engine) ^[/intel/analyses/150e46523ae4a3e90ce949f15630b2f07d475d3a781188301edded1d527f03af.html]
  • techniques/chrome-128-ua-masquerade — Impossible Chrome version masquerade technique.

Provenance

  • file.txt — file v5.44
  • exiftool.json — ExifTool v12.76
  • pefile.txt — pefile v2023.2.7 + Python 3.11
  • rabin2-info.txt — radare2 v5.9.2
  • strings.txt — strings from GNU binutils 2.40
  • floss.txt — flare-floss v3.1.0 (CLI error)
  • capa.txt — capa v7.0.0 (signature path missing)
  • yara.txt — YARA v4.5.0
  • ssdeep.txt — ssdeep v2.14.1
  • tlsh.txt — tlsh v4.12.0
  • Static RE performed with radare2 v5.9.2 (78 functions recovered, level-3 analysis) on 2026-09-02.