Hacked ASP.NET or IIS Website: Cleanup and Recovery
By Glenn Lyvers · Updated · 4 min read
Nearly all hacked-site advice assumes Linux hosting and PHP. If your site runs on IIS, the concepts carry over but almost none of the specifics do — different configuration files, different shell formats, different permission model. Here is the Windows version of the same job.
web.config is where to start
This is the IIS equivalent of a hacked .htaccess, and it is the single most productive place to look. It controls request handling, URL rewriting, custom error pages, HTTP modules and handler mappings, and a small addition to it can redirect traffic conditionally, map unexpected extensions to code execution, or load a module on every request.
Check every web.config in the site, not just the one at the root — they cascade into subdirectories and attackers routinely drop copies deeper in the tree where nobody looks. Look for rewrite rules you did not write, handler mappings for unusual extensions, and any reference to a module or assembly you cannot account for. My guide on hacked .htaccess files covers the same logic in the Apache world.
ASPX shells and uploaded files
The Windows equivalent of a PHP web shell is an ASPX page, and there are well-known families of them just as there are on the PHP side. They give the same capability: a browser-based file manager, command execution and database access, running as whatever identity your application pool uses.
Look for .aspx, .asp, .ashx and .asmx files you did not create, especially in upload directories, image folders and anywhere that should hold content rather than code. Also check for unexpected assemblies in your bin directory, since a compiled backdoor is harder to spot by reading files and just as effective. My guide on web shells covers what one is capable of once you find it.
Application pool identity and permissions
The permissions question on Windows is about the application pool identity — the account your site runs as. What that account can write to is what an attacker who achieves code execution can write to, and over-permissive filesystem rights are a recurring cause of a small compromise becoming a large one.
Check what your application pool identity is and what it has write access to. The content directories should generally not be writable by the account serving them, with narrow exceptions for genuine upload paths. Check whether separate sites on the server share an identity, since that is the Windows version of the cross-site contamination problem covered in my guide on shared hosting contamination.
Where persistence hides on Windows
Scheduled Tasks are the obvious one and the first place to look after the files — a task running a script on a timer is the direct equivalent of a malicious cron job. Check what is scheduled, when it was created and what it runs.
Then: Windows services that should not exist, entries in the IIS configuration loading custom modules globally rather than per-site, and registry run keys if the compromise reached the operating system rather than just the site. A global IIS module is particularly worth checking because it affects every site on the server and is invisible from any individual site's files.
Reading IIS logs
IIS writes its own logs in its own format and location, typically under the system's inetpub logs directory organised per site. The fields are configurable, which is worth knowing because a site logging a minimal field set will tell you less than you need.
Look for the same patterns as anywhere else: POST requests to paths that should not receive them, requests to files you do not recognize returning success, and repeated requests from a single address probing different paths. Also check the Windows Event Log, which records authentication events and service changes that never appear in a web log. My guide on reading access logs covers the general technique.
Cleaning and hardening
Preserve evidence first, then remove the shells and injected configuration, redeploy application files from a known-good build rather than repairing in place, and clean the database. Rotate connection strings, application secrets and any credentials in configuration, and remember that connection strings in web.config are readable by anything with file access.
Then tighten: minimum necessary write permissions for the application pool identity, separate identities per site, patched framework and operating system, request filtering to block execution in upload paths, and removal of handler mappings the application does not need. If you want the site gone through properly by someone who has done this on Windows as well as Linux, that is work I take on — see the platforms I clean.
Common questions
What is the IIS equivalent of a hacked .htaccess?
web.config. It controls rewriting, handler mappings, custom errors and HTTP modules, so a small addition can redirect traffic conditionally or map unexpected extensions to code execution. Check every web.config in the site, not only the root one, since they cascade into subdirectories.
What do web shells look like on Windows?
Usually .aspx pages, with well-known families just as on the PHP side, offering a file manager, command execution and database access. Also check your bin directory for unexpected compiled assemblies, which are harder to spot by reading and equally capable.
Why does the application pool identity matter?
Because it is the account your site runs as, and what it can write to is what an attacker with code execution can write to. Over-permissive write access on content directories turns a limited compromise into a full one, and a shared identity lets a compromise spread between sites.
Where are the IIS logs?
Typically under the system's inetpub logs directory, organised per site. The logged fields are configurable, so a site with a minimal configuration records less than you will want. Check the Windows Event Log too — it records authentication and service changes that never appear in web logs.
Where does persistence hide on a Windows server?
Scheduled Tasks first, then unexpected Windows services, then globally registered IIS modules that load for every site on the server. A global module is especially worth checking because it is invisible from any individual site's own files.
More than malware
Most people meet me in an emergency. It isn’t all I do.
I’ve been building and repairing systems since 1995. Whatever brought you here, there’s a good chance I can help with the rest of it too — and you’ll be dealing with the same person either way.
Hacked, but not WordPress?
Joomla, Drupal, Magento, Shopify, PrestaShop, Laravel, Node, IIS and plain HTML — cleaned the same way, priced the same way.
Take a look →Custom builds & AI systems
Plugins, custom applications, website chatbots and automation — built to do exactly what you need, maintained by the person who wrote them.
Take a look →Servers, speed, SEO & accessibility
Migrations, faster load times, technical SEO and accessibility fixes. Measured improvements, with the numbers to show you.
Take a look →Better web hosting
Fast, secure hosting with SSL and backups included at no extra charge. Clear pricing, no long-term contracts, no surprises.
Take a look →Classes & free tools
Rather learn to handle it yourself? I teach this, and I give away the tools I built for my own cleanups.
Take a look →Something else broken?
Half my work is untangling what someone else started, gave up on, or broke. Describe it in plain words and I’ll tell you honestly.
Take a look →Tell me what’s wrong. I’ll tell you what it takes.
No queue, no call centre, no sales pitch — one person who answers, quotes honestly, and does the work.