Does your IIS website have BadIIS? How to detect and remove the SEO-poisoning module attackers use to redirect visitors to scams
Disclosure: This post contains affiliate links. If you purchase via the links, CyberDudeBivash may earn a commission at no extra cost to you. We only recommend tools and training we use and trust for defending IIS and web infrastructure.
BadIIS is the shorthand defenders use for a class of malicious IIS modules that attackers install to hijack legitimate websites for SEO-poisoning, redirect visitors to scam/affiliate/malicious pages, and quietly monetize compromised infrastructure. These modules are often stealthy — they differentiate between search engine crawlers (serve spammy SEO content) and real visitors (redirect them to scams) — making detection difficult until user complaints or analytics anomalies appear.
This CyberDudeBivash guide covers: what BadIIS is, how attackers deploy it, how to detect it (with exact queries and playbook), how to remove and remediate, how to harden IIS, and how to stop SEO-poisoning campaigns at scale. We include hunting queries, WAF rules, recommended logs to collect, and incident response steps that CISOs can execute immediately.
- What is BadIIS and why attackers use it
- How BadIIS operates (attack flow)
- Signs of compromise — what to look for
- Indicators of Compromise (IoCs) & hunting queries
- How to detect BadIIS on live servers
- Removal & remediation playbook
- Prevention & hardening (IIS + Windows)
- WAF, CDN & detection rules (practical)
- Forensics & post-incident actions
- CISO playbook & policy recommendations
- FAQ
What is BadIIS and why attackers use it
BadIIS refers to malicious IIS native or managed modules (DLLs, managed assemblies, or handlers) installed into the IIS request pipeline. The intent is not to deface but to monetize and persist: attackers want long-lived access to your domain authority so search engines index spammy landing content. When real users click those spammy results, they are redirected to gambling, trick-to-download scams, or affiliate pages that pay criminals.
Attackers prefer this pattern because:
- Low friction: No need to host malicious domains on new infrastructure — use your domain's trust.
- High ROI: Search engines index legitimate domains faster, and affiliate scams convert better.
- Stealth: Bot/crawler detection logic served to search engines hides malicious behavior from casual checks.
- Persistence: Malicious modules persist across app pool restarts unless removed from configuration or filesystem.
How BadIIS operates — a typical attack flow
Typical stages of a BadIIS attack:
- Initial Compromise: Exploit a web app vulnerability (RCE, file upload, path traversal), credential theft, or third-party component compromise. Attackers often first drop a web shell or escalate to administrator privileges.
- Module Install: Attacker installs a native module (DLL) or a managed module and registers it in
applicationHost.config
or siteweb.config
so IIS loads it on request. - Boilerplate & Rules: The module contains logic to inspect headers, user-agent strings, referrers, IPs, and query strings. If it detects a search engine bot (Googlebot, Bingbot), it serves SEO content. If it detects a human with a referrer from search, it injects JS or redirects.
- Monetization: Redirects to affiliate/landing pages, proxies content from attacker-controlled servers, or drops additional malware on client browsers.
- Anti-analysis: Tamper logs, register as innocuous Microsoft modules, and hide files in non-web directories to complicate detection.
Signs of compromise — what to look for
BadIIS is stealthy but leaves telltale signs if you look for them:
- Different content to crawlers vs humans: Use curl with different user-agents and compare output. If content differs significantly (esp. keyword spam), investigate.
- Unexpected IIS modules or handlers registered in
%windir%\system32\inetsrv\config\applicationHost.config
or in site-levelweb.config
. - New native DLLs in
%windir%\system32\inetsrv\
or your application folder with unusual file timestamps. - Redirect chains or short-lived 302/301 responses serving external affiliate domains.
- Injected JavaScript in otherwise static responses for only some clients (check with curl without cookies).
- Unusual outbound connections from the webserver to uncommon IPs or to known malicious C2 domains.
- Analytics/SEO spikes: Crawl rates, indexation of spammy pages, or sudden SERP entries for unrelated keywords.
Indicators of Compromise (IoCs) & hunting queries
Below are practical IoCs and queries for your SIEM/EDR. Replace placeholder tokens with your environment specifics.
Filesystem IoCs (examples)
- Unrecognized DLLs in IIS directories:
C:\Windows\System32\inetsrv\badmodule.dll
- New assemblies under site folders:
C:\inetpub\wwwroot\_bin\module_loader.dll
- Modified
applicationHost.config
or siteweb.config
changed in the last 30 days.
Registry / Config IoCs
- IIS config entries registering unknown modules/handlers (look for module names that mimic Microsoft but point to third-party paths).
- AppPool identity changes or new service accounts created without documentation.
Network IoCs
- Outbound connections from webserver to unusual IPs on ports 80/443 or to remote C2 domains (check proxy logs).
- Redirect destinations: suspicious affiliate or scam domains (track via threat intel lists).
SIEM hunting queries (examples)
Below are starter queries for Splunk/Elastic/QRadar (conceptual — adapt to your schema):
/* Splunk: detect differences served to Googlebot vs normal UA */ index=web_logs host=www.example.com (user_agent="*Googlebot*" OR user_agent="*Bingbot*") | stats count by uri, user_agent, status | join uri [ search index=web_logs host=www.example.com user_agent!="*Googlebot*" user_agent!="*Bingbot*" | stats count by uri, user_agent, status ] | where some_field_indicates_different_content
/* Elastic: detect newly created DLLs in inetsrv in last 7 days */ GET _search { "query": { "bool": { "must": [ { "match": { "file.path": "C:\\Windows\\System32\\inetsrv" } }, { "range": { "file.mtime": { "gte": "now-7d" } } } ] } } }
/* EDR/Process: Detect w3wp.exe spawning cmd.exe or rundll32.exe with suspicious args */ ProcessName:w3wp.exe AND (CommandLine:*cmd.exe* OR CommandLine:*rundll32* OR CommandLine:*powershell*)
YARA-ish signature ideas (conceptual)
rule suspicious_iis_module_name { strings: $s1 = "BadIIS" nocase $s2 = "seo" nocase $s3 = "googlebot" nocase condition: (any of ($s*)) and filesize < 5MB }
How to detect BadIIS on live servers — hands-on checks
These are exact hands-on checks your ops, SOC, or a security engineer can run (no guessing):
1) Compare responses for crawler UA vs normal UA
curl -A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" -sS https://www.example.com/page > googlebot.html curl -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64)" -sS https://www.example.com/page > human.html diff -u googlebot.html human.html | less
If the files differ (especially if googlebot.html has keyword spam), escalate immediately.
2) Inspect IIS Modules & Config
# On server (run elevated) %windir%\system32\inetsrv\appcmd.exe list modules /xml # Or check applicationHost.config in %windir%\system32\inetsrv\config\
Look for modules with unfamiliar names or DLL paths outside normal Microsoft dirs.
3) Check web.config for added handlers
Site-level web.config
modifications often register handlers. Use file integrity or git-based config management to spot changes.
4) Review process tree for w3wp.exe
Use Sysinternals Process Explorer or EDR process tree to see if w3wp.exe spawned suspicious processes (cmd, powershell, rundll32) or loaded unknown DLLs.
5) Search for web shells & unknown files
# Example PowerShell search for recently modified files in site root Get-ChildItem -Path C:\inetpub\wwwroot -Recurse | Where-Object { $_.LastWriteTime -gt (Get-Date).AddDays(-30) } | Select FullName, LastWriteTime
6) Network-level checks
- Check firewall/proxy logs for webserver outbound connections to previously unseen hosts.
- Run a passive DNS lookup for outbound domains seen in logs and cross-reference with threat intel feeds.
Removal & remediation playbook (step-by-step)
If you confirm a BadIIS module or signs of SEO-poisoning, follow this structured cleanup. Do not skip forensic imaging before sweeping if the incident scope may require legal/attribution work.
Immediate containment (minutes)
- Isolate the host: Remove server from LB or block external traffic at network level (preserve internal access for IR as required).
- Snapshot: Take full disk and memory images (EDR, backup, VM snapshot) for forensic analysis before modifying artifacts.
- Revoke credentials: Rotate service account passwords and API keys related to site deployment pipelines.
Cleanup (hours)
- Use a clean forensic workstation to examine images and identify malicious files (DLLs, assemblies, web shells).
- Remove the registered module entries from
applicationHost.config
and siteweb.config
(after imaging). - Delete unauthorized DLLs and assemblies, but beware of file timestamp tampering — rely on forensic notes.
- Run full AV/EDR scans and check for persistent scheduled tasks or services the attacker may have created.
- Patch IIS/OS and web applications to remove root cause vectors (RCE, vulnerable libraries).
Recovery (1–3 days)
- Restore server from a known clean image if confidence in cleanup is low; reapply patches and hardening.
- Reinstate server into production behind WAF and CDN with strict ruleset.
- Monitor for re-infection for at least 30 days (hunt for reappearance of same IoCs).
Post-incident (weeks)
- Perform root cause analysis (how did attacker get in?).
- Review deployment pipelines, CI/CD secrets, and third-party tools used for site management.
- Train ops and dev teams on secure deployment and secrets handling.
Prevention & hardening — IIS & Windows best practices
Defenses stack that stops the BadIIS attack lifecycle:
Platform hardening
- Run IIS on minimal Windows Server builds; remove unnecessary features.
- Keep OS and IIS patches current (monthly patch cadence + emergency hotfixes).
- Limit local administrator accounts and use LAPS for workstation admin passwords.
Config hardening
- Lock down
applicationHost.config
andweb.config
with file ACLs so only authorized deployment accounts can modify them. - Use AppInit or Module signing where supported; validate module origins and code signatures.
- Enable request filtering and maximum content length; disable rarely used verbs and handlers.
Secrets & deployments
- Store deployment credentials and keys in vaults (HashiCorp, Azure Key Vault, or enterprise HSMs).
- Rotate CI/CD tokens regularly and avoid embedding secrets in pipeline scripts.
Least privilege & segmentation
- Run AppPools using low-privilege identities; do not use SYSTEM or high-priv accounts for AppPools.
- Place web servers in a segmented DMZ with outbound controls to only required destinations.
Monitoring & telemetry
- Forward IIS logs, Windows Security logs, and Sysmon to your SIEM.
- Monitor process creation events involving w3wp.exe, rundll32.exe, and unexpected child processes.
WAF, CDN & detection rules — practical recipes
Using a WAF and CDN is critical. Below are practical rule ideas that block common BadIIS behaviors without false positives when tuned:
1) Block suspicious UA pattern anomalies (tuned)
- Block requests where UA is empty but referrer is search engine — common for automated redirect probes.
2) Protect file upload endpoints
- Enforce content type checks, block double extensions, and limit allowed filetypes/size.
3) Block outbound proxying attempts
- Detect and block server responses that include immediate 302/301 to new domains if response included cookies or session state changes.
4) Bot-verification routing
Where possible, route suspected bot traffic to isolated endpoints to verify that a server is serving different content to crawlers and humans (can be used for detection).
5) WAF pseudo-rule (conceptual)
IF request.Path CONTAINS "/search" AND request.Headers["User-Agent"] CONTAINS "Googlebot" AND response.Body LENGTH > 1000 AND response.Body CONTAINS suspicious_keywords THEN alert AND block
Forensics & post-incident actions — what to collect & analyze
- Memory dumps: Capture RAM of the affected w3wp.exe processes to recover in-memory modules and strings.
- Disk images: Full image of webroot and program files to analyze dropped DLLs and shells.
- Registry backups: Export keys relevant to services and scheduled tasks.
- Network captures: PCAPs of outbound connections to attacker infrastructure for attribution.
- Logs: IIS logs, Windows Event logs, application logs, SIEM correlated events (48–90 days backlog if available).
CISO playbook & policy recommendations
Your leadership checklist for preventing and responding to BadIIS-style attacks:
- Mandate periodic webserver inventory & baseline configuration checks (monthly).
- Require code signing and module-whitelisting for any IIS modules deployed.
- Integrate webserver config audits into change management (deny changes outside pipeline).
- Establish a rapid-restore pipeline: immutable images for web servers and quick rollback playbooks.
- Onboard a threat intel source that tracks SEO-poisoning campaigns and domain lists.
- Run quarterly red-team exercises that test SEO-poisoning detection and incident response.
FAQ
Q: Can BadIIS be installed without admin rights?
A: Installing native IIS modules or editing applicationHost.config
requires elevated privileges. However, attackers often first obtain admin through web app RCE or credential theft, then install modules. Compromise paths vary, but module installation itself is a privileged operation.
Q: Will deleting the DLL fix the problem?
A: Deleting the DLL may stop the module but doesn't remove backdoors, replaced config entries, or other persistence. Follow the remediation playbook: image, contain, remove, patch, and monitor for re-infection.
Q: Should I rebuild the server or clean in place?
A: If you can forensically prove the root cause and fully remove all artifacts, cleaning may be acceptable. For confidence and speed, rebuilding from a known good image is preferred for production systems.
#CyberDudeBivash #BadIIS #IISCompromise #SEOpoisoning #ThreatHunting #DFIR #WebSecurity #WAF #CISO #IncidentResponse
Comments
Post a Comment