One Open Directory, 12 Samples, and a Live RAT: Dissecting a LNK-to-DLL-to-.NET Attack Chain Staged on BlueVPS
From weaponized LNK files abusing Internet Explorer to a custom .NET RAT with token-based C2 — every stage recovered from an open directory the operator forgot to lock down
A security researcher flags an open directory. Inside: six weaponized LNK files, five custom DLL loaders compiled from the same builder, and a live .NET remote access trojan still downloadable from the operator's payload server. The actor left backup files, forgot to strip internal names, and hosted everything on an Apache server with directory listing enabled.
This is the story of how a single open directory at wildishadventure[.]com/secure9/ exposed a complete attack chain -- from initial access through payload delivery to C2 communication -- with every stage recoverable and every mistake documented.
The Tip
On April 2, 2026, malware researcher @malwrhunterteam flagged an open directory at wildishadventure[.]com/secure9/ hosting suspicious LNK files alongside extensionless PE binaries. Our auto-triage pipeline scored it 90/100 and promoted it to TIER1 for immediate investigation.
The directory was mirrored at the raw IP 171.22.182[.]231/secure9/ -- same content, same Apache/2.4.52 (Ubuntu) server, same BlueVPS Estonia hosting. The actor didn't even bother restricting access to the domain-fronted version.
Inside: 11 files. Six Windows shortcut files with single-letter names (B.LnK, K.LnK, N.LnK, Q.LnK, p.lnk) plus an older backup (N.LnK.old). Five PE32 DLLs with cryptic extensions (f.s, m.d, M.k, o.l) plus another backup (f.s.old). Each LNK pointed to a specific DLL. Each DLL downloaded a specific payload. And the newest files were updated just yesterday.
Stage 1: The LNK Files -- Internet Explorer Rises From the Grave
The LNK files aren't shortcuts in any traditional sense. They're 1,664-byte HTML Application containers that abuse a technique most defenders assumed died with Internet Explorer: the ActiveXObject('htmlfile') exploit.
When a victim opens one of these files, the embedded HTML triggers an onerror handler on a broken image tag. The JavaScript inside performs a series of operations:
h = new ActiveXObject('htmlfile');
h.open();
h.write('<object type=text/html data=?hf=1></object>');
This creates an in-memory HTML document object, which then loads an iframe pointing to the attacker's UNC path. The chain continues through execScript() calls that ultimately force Windows to fetch a DLL from a remote SMB or WebDAV share:
\\171.22.182[.]231\secure9\f.s
\\wildishadventure[.]com\secure9\m.d
\\wildishadventure[.]com\secure9\o.l
\\wildishadventure[.]com\secure9\M.k
Each LNK file targets a different DLL. The .old backup of N.LnK originally pointed to f.s but was updated a day later to point to o.l instead -- the actor iterating on their configuration in real time, with the evidence left in the open directory for anyone to find.
Stage 2: The DLL Loader -- One Builder, Four Configs
All five DLLs share a PE compilation timestamp of 2026-03-24 10:08:03 UTC. Same compiler, same entry point, same section layout, same 89,088-byte file size. They were built from a single source with a builder tool that swaps out configuration at a fixed offset.
The internal name? testingdll.dll. Exported function: RunPayload. Neither was stripped before deployment.
Each DLL is a WININET-based HTTP downloader. When RunPayload is called, it fetches a URL hardcoded at offset 0x142F8 and drops the downloaded file with a name from offset 0x14700. The configs across the four unique variants tell the story of an operator moving from testing to production:
| DLL | Download URL | Drop Name | Purpose |
|---|---|---|---|
| f.s | the.earth[.]li/~sgtatham/putty/latest/w32/puttytel.exe | codeword.exe | Testing -- downloads legitimate PuTTY |
| m.d | the.earth[.]li/~sgtatham/putty/0.83/w32/putty.exe | cronjob.exe | Testing -- downloads legitimate PuTTY |
| M.k | editor.fileviewer[.]blog/msedgewebview.exe | msedgewebview.exe | Production -- malicious payload |
| o.l | fileviewer[.]blog/verify/path.exe | svchost.exe | Production -- malicious payload |
The first two variants download legitimate PuTTY binaries from Simon Tatham's official server. This is the actor's development workflow caught in amber: they built the loader, tested it against a safe download to verify the WININET code worked, then swapped in the real payload URLs. And they left the test builds sitting in the open directory.
The drop filenames are equally revealing. svchost.exe and msedgewebview.exe are chosen to blend into a Windows process listing. codeword.exe and cronjob.exe are the test names -- functional but not designed to evade detection.
A custom .fptable PE section is present in all variants, reserved for runtime configuration injection -- suggesting the builder supports additional features beyond static URL embedding.
Stage 3: RemoteMgmt.Agent -- The Live RAT
The production payload was still live on fileviewer[.]blog/verify/path.exe when we downloaded it. A 22,528-byte .NET 4.8 assembly with the internal name RemoteMgmt.Agent.exe and a timestomped PE date of 2052 -- 26 years in the future.
This is a custom-built remote access trojan, not a commodity framework. The capabilities extracted from string and code analysis:
Command Execution: Full shell access via ExecuteCommand and RunCommand, with process management including KillProcess and KillAllRunningProcesses. A 30-second kill timeout ensures hung processes don't block the operator.
C2 Protocol: JSON over raw TCP on port 443. Not HTTPS -- raw TCP disguised on a common port. The message format:
{"Type": "", "ClientId": "", "CommandId": "", "Payload": "", "ExitCode": "", "Ts": ""}
Message types include Welcome, Execute, CommandOutput, CommandDone, CommandError, Heartbeat, Broadcast, AuthOk, AuthFail, ServerShutdown, Disconnect, and KillCommand -- a full-featured bidirectional protocol.
Authentication: Token-based. The agent sends an auth token on connection; the server responds with AUTH OK or AUTH FAIL. Host, token, and other settings are stored as encrypted byte arrays decrypted at runtime by a Dec() function.
Persistence: Watchdog thread with heartbeat loop and exponential backoff retry (configurable via BASE_RETRY_MS and MAX_RETRY_MS). The agent will keep trying to reconnect indefinitely.
Forensic Artifact: Creates rmgmt_agent.log in %TEMP% -- a log file that any incident responder can search for across an endpoint fleet.
Infrastructure
The operation spans two hosting providers and a CDN:
BlueVPS OU (Estonia) -- 171.22.182[.]231 hosts the open directory and serves as the DLL staging server. BlueVPS is a bullet-proof-adjacent Estonian VPS provider that appears frequently in malware hosting. The adjacent IP 171.22.182[.]233 hosts auth.chaburnette[.]fun -- potentially related infrastructure on the same /24.
Namecheap Shared Hosting -- 69.57.162[.]217 hosts fileviewer[.]blog and editor.fileviewer[.]blog on a LiteSpeed server. This is where the final RAT payload lives. Using shared hosting for payload delivery adds a layer of plausible deniability -- the IP is shared with hundreds of legitimate sites.
Cloudflare -- wildishadventure[.]com sits behind Cloudflare nameservers (odin.ns.cloudflare[.]com and zariyah.ns.cloudflare[.]com). The domain was registered via Namecheap on August 8, 2025, but the malware infrastructure wasn't deployed until March 24, 2026 -- seven months of the domain aging before weaponization.
A Let's Encrypt wildcard certificate was issued for wildishadventure[.]com on the same day as the DLL compilation, confirming the infrastructure stood up in a single coordinated session.
Development Timeline
| Date | Event |
|---|---|
| 2025-08-08 | wildishadventure[.]com registered via Namecheap |
| 2026-03-24 10:08 | All DLL variants compiled (PE timestamp) |
| 2026-03-24 10:36 | f.s.old uploaded (testing build) |
| 2026-03-24 11:58 | N.LnK.old uploaded (first LNK revision) |
| 2026-03-25 10:15-14:05 | Current LNK + DLL set deployed (5 files updated) |
| 2026-04-01 12:43-12:44 | M.k and Q.LnK updated (newest variant) |
| 2026-04-02 | path.exe still LIVE on fileviewer[.]blog |
The timeline shows continuous iteration. The actor built and tested on March 24, deployed the first operational set on March 25, and pushed an update on April 1 -- seven days later -- adding the msedgewebview.exe variant with a new payload URL. This is active development, not an abandoned kit.
OPSEC Failures
Six distinct mistakes that gave this operation away:
-
testingdll.dllinternal name not stripped. The development name is baked into the PE metadata. Any sandbox or analyst sees it immediately. -
.oldbackup files left in the directory.N.LnK.oldandf.s.oldshow the previous iteration of the attack chain, letting analysts reconstruct the development process. -
Apache autoindex enabled. The open directory exists because someone didn't add
Options -Indexesto the Apache config. The entire toolkit is browsable. -
PuTTY test URLs reveal workflow. Two of the four DLL configs download legitimate PuTTY binaries -- test builds that confirm the actor's development methodology and provide a baseline for diffing against the malicious configs.
-
Identical PE timestamps across all variants. A single compilation timestamp across four functionally different DLLs reveals a builder tool. This is a detection pivot -- any other binary with the same timestamp, section layout, and
.fptablesection is from the same operator. -
Cloudflare nameserver pair as a pivot. The
odinandzariyahNS pair assigned to this account can be used to discover other domains registered under the same Cloudflare account.
Indicators of Compromise
Network Indicators
wildishadventure[.]com-- LNK delivery domain171.22.182[.]231-- DLL staging server (BlueVPS Estonia)fileviewer[.]blog-- RAT payload hostingeditor.fileviewer[.]blog-- Secondary payload domain69.57.162[.]217-- Namecheap shared hosting IPhxxps://fileviewer[.]blog/verify/path.exe-- Live RAT download URLhxxps://editor.fileviewer[.]blog/msedgewebview.exe-- Secondary payload URL
File Indicators
LNK Files:
| SHA256 | File |
|---|---|
3b0c983b0d837e257477c5e70c33af67a50f5972737fcfb643019ce112bbc348 | B.LnK |
bbe0a52f5e495da916abf590f2be58a4c31d8416fc904a97e5a1f551a3a2e603 | K.LnK |
d954a786c79d7dc49eff7969119b807007b2a52cc21b28f92ba745e82c796c26 | N.LnK |
88dfe5534d2318316dda653ced9953bdcf8a4e8814a58e1f60828bae8fd75109 | N.LnK.old |
42533fbb40fe274c96a31c948ae6e84b6c103f9da6f27c9d1dc5c011f7b719d0 | Q.LnK |
DLL Loaders (testingdll.dll):
| SHA256 | File |
|---|---|
6f966ba09035db8ab76fff62bb7893d7c7b720537ae67f635b515f1d52597800 | f.s (PuTTY decoy) |
32b045efcde258ed0f32851da1f5fcd75380f7b4bb21dc387664c580fb77b645 | m.d (PuTTY decoy) |
9b00ce3b72371c12f93d50eba473241e0a5c8cc1050e3d9ab9fe4ec21e2f5841 | M.k (malicious) |
5742cad3cb1cde3099bb1146589aca26a526d3c13e4398d0adefb648fac91146 | o.l (malicious) |
Final Payload:
| SHA256 | File |
|---|---|
f2a450d41365e1276883a93122eb97870138767fff6e3269b5660c5ae1334dda | path.exe (RemoteMgmt.Agent) |
Behavioral Indicators
%TEMP%\rmgmt_agent.log-- RAT log file- TCP/443 C2 (raw TCP, not HTTPS)
- JSON C2 protocol:
Type,ClientId,CommandId,Payload,ExitCode,Ts - DLL export:
RunPayload - UNC path pattern:
\\{host}\secure9\{payload} - Drop filenames:
svchost.exe,codeword.exe,cronjob.exe,msedgewebview.exe
Detection
YARA
Three detection rules covering the DLL loader (.fptable section + RunPayload export), RemoteMgmt.Agent (.NET assembly strings), and LNK exploit (ActiveXObject + htmlfile pattern) are available on our GitHub:
Network
Suricata signatures for DLL download via UNC paths, the JSON C2 protocol pattern, and payload delivery from the identified infrastructure are published alongside this report.