Web root permissions are more permissive than intended
Most people think of Internet Information Services (IIS) as just a web server. It hosts internal portals, APIs, SharePoint deployments, authentication gateways, and line-of-business applications. It is deeply embedded in the environment, widely trusted by network policies and rarely subjected to same scrutiny as a user workstation.
At the process level, all this runs inside w3wp.exe, a Microsoft-signed, highly privileged worker process that legitimately loads dynamic links, makes network connections and performs complex application logic. End-point security products expect this behaviour and firewalls permit this traffic.
That implicit trust is what makes it interesting.
In our recent research, we explored a simple question:
What happens if an attacker gains write access to an IIS web root?
Not full server compromise.
Not domain admin.
Just the ability to drop a file into wwwroot.
Modern Endpoint Detection and Response (EDR) platforms catch traditional post-exploitation patterns: executables on disk, suspicious child processes, or scripting engine abuse. IIS behaves differently.
An Active Server Pages Extended (ASPX) page is compiled and executed on the first request. There is no separate deployment step – drop the file, browse to it and it runs inside a trusted worker process that already performs complex operations as part of normal business activity.
In our research, we show that a single ASPX page can act as a fully reflective, in-memory Dynamic Link Loader (DLL). The payload never exists on disk. It’s delivered via HTTP request, mapped into memory, relocated and executed entirely inside w3wp.exe. There’s no temporary DLL, no new process tree and no obvious parent-child anomalies – just native code running inside IIS worker pool process.
IIS is widely deployed in enterprise environments, and in many organisations:
Web root permissions are more permissive than intended
Service accounts can write to application directories
File upload vulnerabilities exist
Database compromise can lead to file write access
With nothing more than write access to wwwroot, an attacker can establish a persistent, authenticated, in-memory execution platform inside a trusted process.
That makes IIS a powerful lateral movement enabler.
To avoid touching disk entirely, as part of our research we rebuilt key elements of the Windows Portable Executable (PE) loader in C#.
That meant:
If any of these steps are done incorrectly, w3wp.exe crashes. That’s not theoretical – we hit the edge cases and debugged the failures.
The full paper walks through these implementation details clearly, including the subtle issues that most high-level discussions skip – especially around x64 structured exception handling and C runtime initialisation.
Getting reflective loading to work is only part of the challenge. The next step was reducing the static and behavioural footprint of the loader itself.
Early versions relied on static DllImport declarations for well-known Windows APIs. Those signatures are easy for scanners to flag. We replaced them with dynamic API resolution so that only minimal bootstrap imports remain visible, while sensitive calls are resolved at runtime.
Recognisable API names were removed from the source entirely. Instead of embedding strings such as VirtualAlloc or CreateThread, names are reconstructed dynamically. Suspicious hexadecimal constants like 0x40 or 0x1000 are no longer hardcoded; they are computed at runtime to avoid obvious static indicators.
We also eliminated identifiable opcode patterns. Earlier development builds used fixed byte arrays for entry point stubs. These were replaced with programmatically constructed instruction sequences, so no recognisable shellcode patterns appear in the file.
Finally, identifiers and comments were sanitised. Names that clearly described reflective loading behaviour were replaced with neutral terminology. The result is a loader that blends more naturally into the surrounding ASP.NET application code.
The objective was not invisibility. It was understanding how small design choices influence detection surface and how modern defensive tooling interprets artifacts.
Fileless does not mean invisible.
Even when no DLL is written to disk, the technique still requires executable memory allocation inside w3wp.exe. It results in threads that begin execution from unbacked memory regions. It correlates inbound HTTP requests with memory changes in a trusted process.
Individually, those signals may look benign. IIS legitimately allocates memory. Threads are created all the time. HTTP POST requests are normal.
But when those events align within a narrow time window on the same host, they form a meaningful detection opportunity.
Effective defence in this space requires telemetry correlation across web logs, process memory monitoring and thread creation events. It also requires tightening web root permissions and monitoring for unexpected file changes in content directories.
This research demonstrates a complete attack chain: from write access to an IIS web root to arbitrary native code execution in memory inside a trusted process.
For red teamers, the lesson is clear. IIS is not just infrastructure. It can become a stable, trusted execution platform that blends into normal enterprise activity.
For defenders, the takeaway is equally important. When execution happens inside trusted, Microsoft-signed processes and payloads never appear as standalone files, detection strategies must move beyond simple file scanning and process ancestry checks.
IIS is often treated as a passive web server.
In the wrong hands, it becomes something much more powerful
Whether you’re on the offensive or defensive side, this paper provides detailed, practical insights you won’t find in high-level discussions. If you want the full technical breakdown – from reflective loading implementation to detection guidance – the complete paper is a must-read.