Back to reports

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

PublishedApril 2, 2026
lnk-exploitdll-sideloadingratdotnetbluevpsopen-directoryattack-chain

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:

DLLDownload URLDrop NamePurpose
f.sthe.earth[.]li/~sgtatham/putty/latest/w32/puttytel.execodeword.exeTesting -- downloads legitimate PuTTY
m.dthe.earth[.]li/~sgtatham/putty/0.83/w32/putty.execronjob.exeTesting -- downloads legitimate PuTTY
M.keditor.fileviewer[.]blog/msedgewebview.exemsedgewebview.exeProduction -- malicious payload
o.lfileviewer[.]blog/verify/path.exesvchost.exeProduction -- 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

DateEvent
2025-08-08wildishadventure[.]com registered via Namecheap
2026-03-24 10:08All DLL variants compiled (PE timestamp)
2026-03-24 10:36f.s.old uploaded (testing build)
2026-03-24 11:58N.LnK.old uploaded (first LNK revision)
2026-03-25 10:15-14:05Current LNK + DLL set deployed (5 files updated)
2026-04-01 12:43-12:44M.k and Q.LnK updated (newest variant)
2026-04-02path.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:

  1. testingdll.dll internal name not stripped. The development name is baked into the PE metadata. Any sandbox or analyst sees it immediately.

  2. .old backup files left in the directory. N.LnK.old and f.s.old show the previous iteration of the attack chain, letting analysts reconstruct the development process.

  3. Apache autoindex enabled. The open directory exists because someone didn't add Options -Indexes to the Apache config. The entire toolkit is browsable.

  4. 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.

  5. 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 .fptable section is from the same operator.

  6. Cloudflare nameserver pair as a pivot. The odin and zariyah NS 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 domain
  • 171.22.182[.]231 -- DLL staging server (BlueVPS Estonia)
  • fileviewer[.]blog -- RAT payload hosting
  • editor.fileviewer[.]blog -- Secondary payload domain
  • 69.57.162[.]217 -- Namecheap shared hosting IP
  • hxxps://fileviewer[.]blog/verify/path.exe -- Live RAT download URL
  • hxxps://editor.fileviewer[.]blog/msedgewebview.exe -- Secondary payload URL

File Indicators

LNK Files:

SHA256File
3b0c983b0d837e257477c5e70c33af67a50f5972737fcfb643019ce112bbc348B.LnK
bbe0a52f5e495da916abf590f2be58a4c31d8416fc904a97e5a1f551a3a2e603K.LnK
d954a786c79d7dc49eff7969119b807007b2a52cc21b28f92ba745e82c796c26N.LnK
88dfe5534d2318316dda653ced9953bdcf8a4e8814a58e1f60828bae8fd75109N.LnK.old
42533fbb40fe274c96a31c948ae6e84b6c103f9da6f27c9d1dc5c011f7b719d0Q.LnK

DLL Loaders (testingdll.dll):

SHA256File
6f966ba09035db8ab76fff62bb7893d7c7b720537ae67f635b515f1d52597800f.s (PuTTY decoy)
32b045efcde258ed0f32851da1f5fcd75380f7b4bb21dc387664c580fb77b645m.d (PuTTY decoy)
9b00ce3b72371c12f93d50eba473241e0a5c8cc1050e3d9ab9fe4ec21e2f5841M.k (malicious)
5742cad3cb1cde3099bb1146589aca26a526d3c13e4398d0adefb648fac91146o.l (malicious)

Final Payload:

SHA256File
f2a450d41365e1276883a93122eb97870138767fff6e3269b5660c5ae1334ddapath.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.


Share