Website Defacement — Unauthorized Web Root and CMS Content Tampering
Website defacement remains a common Impact objective for hacktivist and ideologically-motivated actors, and increasingly appears as a secondary objective in ransomware and extortion intrusions to pressure victims publicly. The typical path to defacement is initial access via an exposed CMS admin panel (WordPress, Joomla), an unpatched CVE in a web application, or credentials reused/purchased from a prior breach, followed directly by modification of homepage or landing-page content — either through the CMS's own content editor or by dropping a file directly into the web root that overwrites index.html/index.php/default.aspx. Two independent detection surfaces exist: (1) endpoint/file telemetry showing a write to a canonical homepage filename inside a web-exposed directory, especially when the writing process is a shell, script interpreter, or the web server worker itself rather than a known deployment/CI process; and (2) CMS application-layer telemetry showing an admin authentication event immediately followed by a content-publish action from a source IP that has never previously been associated with that admin account. Neither signal alone is fully reliable (legitimate deploys touch index files; legitimate admins log in from new locations occasionally), but the combination — an unrecognized process or unrecognized source touching production homepage content outside a known deployment window — is a high-fidelity defacement indicator.
What is THREAT-Impact-WebsiteDefacementIntegrityTamper Website Defacement — Unauthorized Web Root and CMS Content Tampering?
Website Defacement — Unauthorized Web Root and CMS Content Tampering (THREAT-Impact-WebsiteDefacementIntegrityTamper) maps to the Impact tactic — the adversary is trying to manipulate, interrupt, or destroy your systems and data in MITRE ATT&CK.
This page provides production-ready detection logic for Website Defacement — Unauthorized Web Root and CMS Content Tampering, covering the data sources and telemetry it touches: Microsoft Defender for Endpoint (DeviceFileEvents), CMS/web application audit log (WordPress, Joomla, custom CMS — ingested as a custom log table), IIS / Apache / nginx access logs. The queries below are rated high severity at medium confidence, and ship for 7 SIEM platforms — KQL, SPL, Elastic, QRadar, Sumo, YARA-L, LogScale.
MITRE ATT&CK
- Tactic
- Impact
// THREAT: Website Defacement - Web Root Tampering + CMS Admin Content Publish Anomaly
// Requires DeviceFileEvents (MDE) for the web-root signal and a CMS/web app log table (here modeled as a generic 'CMSAuditLogs_CL' custom log) for the admin-publish signal
let LookbackWindow = 24h;
let HomepageFileNames = dynamic(["index.html", "index.php", "index.htm", "default.aspx", "default.asp", "home.html", "wp-config.php"]);
let KnownDeployProcesses = dynamic(["msbuild.exe", "dotnet.exe", "git.exe", "rsync", "scp", "w3wp.exe", "kuduexecutable.exe", "docker.exe"]);
// Signal 1: homepage/critical file written to a web-exposed directory by an unexpected process
let WebRootTamper = DeviceFileEvents
| where Timestamp > ago(LookbackWindow)
| where ActionType in ("FileCreated", "FileModified", "FileRenamed")
| where FolderPath has_any ("\\wwwroot\\", "\\htdocs\\", "\\inetpub\\", "/var/www/", "/usr/share/nginx/")
| where FileName in~ (HomepageFileNames)
| where InitiatingProcessFileName !in~ (KnownDeployProcesses)
| project Timestamp, DeviceName, FileName, FolderPath, ActionType,
InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessAccountName
| extend Indicator = "WebRootHomepageTamperedByUnexpectedProcess"
| extend RiskScore = 90;
// Signal 2: CMS admin authentication immediately followed by a content-publish action from a source IP never seen before for that account (requires a CMS audit log ingested as CMSAuditLogs_CL)
let PriorIPsPerAccount = CMSAuditLogs_CL
| where TimeGenerated between (ago(90d) .. ago(LookbackWindow))
| where Action_s in ("login_success", "admin_login")
| summarize KnownSourceIPs = make_set(SourceIP_s) by AdminAccount_s;
let AdminPublishAnomaly = CMSAuditLogs_CL
| where TimeGenerated > ago(LookbackWindow)
| where Action_s in ("login_success", "admin_login")
| join kind=inner (
CMSAuditLogs_CL
| where TimeGenerated > ago(LookbackWindow)
| where Action_s in ("publish_post", "update_page", "edit_theme_file", "plugin_install")
) on AdminAccount_s
| where TimeGenerated1 - TimeGenerated between (0min .. 30min)
| lookup PriorIPsPerAccount on AdminAccount_s
| where KnownSourceIPs !has SourceIP_s
| project TimeGenerated, AdminAccount_s, SourceIP_s, Action_s1, KnownSourceIPs
| extend Indicator = "CMSAdminPublishFromNeverSeenSourceIP"
| extend RiskScore = 75;
union WebRootTamper, AdminPublishAnomaly
| sort by RiskScore desc, Timestamp desc Two-signal defacement detection. Signal 1 (MDE DeviceFileEvents) flags any create/modify/rename of a canonical homepage or landing-page filename inside a web-exposed directory when the writing process is not one of the organization's known deployment tools — catching both web-shell-driven overwrites and direct filesystem tampering after compromise. Signal 2 correlates CMS admin login events with a subsequent content-publish action within 30 minutes from a source IP never previously associated with that admin account, catching defacement performed entirely through the legitimate CMS editor after credential theft or session hijack.
Data Sources
Required Tables
False Positives
- Legitimate CI/CD deployment pipelines writing index files during a release — ensure the deployment service account or process is added to KnownDeployProcesses
- Site administrators traveling or working from a new location/VPN exit node who legitimately publish content from a new source IP
- Staging-to-production content sync tools that touch homepage files as part of routine content refresh
- Web application firewalls or CDN edge workers that rewrite homepage content for A/B testing or geo-targeting
Sigma rule & cross-platform mapping
The detection logic for Website Defacement — Unauthorized Web Root and CMS Content Tampering (THREAT-Impact-WebsiteDefacementIntegrityTamper) above is provided in a vendor-neutral
form so you can deploy it on any SIEM. The same logic is shipped here as native
KQL (Microsoft Sentinel / Defender), SPL (Splunk), Elastic (Elastic Security (EQL)), QRadar (IBM QRadar (AQL)), Sumo (Sumo Logic CSE), YARA-L (Google Chronicle / SecOps), LogScale (CrowdStrike LogScale (CQL)) queries. In Sigma terms, this detection targets the
following logsource:
logsource:
product: azure Browse the community-maintained Sigma rules for this technique:
Platform-specific guides for THREAT-Impact-WebsiteDefacementIntegrityTamper
Testing Methodology
Validate this detection against 2 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1 Simulate Web Root Homepage Overwrite via Shell
Expected signal: File creation/modification event for index.html in a web-exposed directory, InitiatingProcess is a shell (bash/sh) rather than a known deployment tool.
- Test 2 Simulate CMS Admin Publish From New Source IP
Expected signal: Two CMS audit log events for the same admin account within 30 minutes: a login followed by a publish action, from an IP absent from the account's known-IP set.
Response Playbook
Triage
- Confirm the change is unauthorized: diff the current homepage content against the last known-good version in source control or the CDN cache to see exactly what was altered.
- Identify the writing process and account for the file-level signal, or the admin account and source IP for the CMS-level signal — determine whether that account's credentials were recently involved in a phishing or credential-stuffing alert.
- Check whether the site is public-facing and currently serving the defaced content to visitors, or whether it was caught before propagating past a staging/CDN cache layer.
- Look for a preceding initial-access indicator on the same host: web shell upload, CMS plugin/theme file upload, or exploitation of a known CVE in the CMS or web framework.
- Determine scope: is this one site/vhost on a shared web server, or could the same access path affect other tenants on the same host?
Containment
- Restore the homepage/affected pages from a known-good backup or source-control revision immediately to limit public exposure.
- Revoke sessions and force a password reset for the compromised admin account; enforce MFA on the CMS admin panel if not already required.
- Isolate the host (if self-hosted) via EDR, or place the CDN/WAF in front of the origin with a maintenance page while remediation completes.
- Remove any dropped web shell or unauthorized plugin/theme file identified during triage, and patch the CVE or misconfiguration that enabled initial access.
- If the defacement is part of a broader extortion campaign, coordinate with the incident commander before making the fix public — some actors monitor for restoration and re-deface.
Evidence Collection
- The defaced file's full content and a diff against the last known-good version
- DeviceFileEvents / Sysmon FileCreate history for the affected file and directory over the prior 30 days
- CMS audit log entries for the admin account: login history, IP history, and all content actions in the preceding 7 days
- Web server access logs for the affected vhost around the time of the change
- Any web shell or backdoor file discovered on the host, preserved for forensic analysis
Escalation Criteria
- ! Defacement is currently live and publicly visible on a customer-facing or brand-critical domain
- ! Defacement includes political, extremist, or extortion messaging tied to a known threat actor or campaign
- ! Evidence of a web shell or persistent backdoor beyond the single content change
- ! Multiple sites/vhosts on the same infrastructure show tampering, indicating broader compromise
- ! The compromised admin account also has access to other systems (shared credentials, SSO)
Investigation Guide
Forensic Artifacts
- >
Sysmon Event ID 11 (FileCreate) or Event ID 2 (FileCreationTime changed) for the web root directory - >
CMS application logs: wp-content/debug.log, plugin/theme edit history, revision history for the affected page - >
Web server access/error logs showing the request that triggered the content change (POST to /wp-admin/post.php, /administrator/index.php, or an uploaded file request) - >
Any newly created PHP/ASPX file in an uploads or plugin directory (common web shell staging locations)
Tuning Guidance
Maintain an accurate KnownDeployProcesses allowlist reflecting your actual CI/CD and configuration-management tooling; the largest source of false positives is a legitimate deploy process not yet on the list. For the CMS admin-publish signal, seed PriorIPsPerAccount with at least 90 days of history before enabling alerting, and consider excluding known corporate egress IP ranges/VPN concentrators from the 'never seen' comparison to reduce noise from NAT pool rotation.
Hunting Queries
Hunt for newly created server-side script files written by the web server worker process itself — a common precursor to defacement where a web shell is dropped before the homepage is modified.
DeviceFileEvents
| where Timestamp > ago(30d)
| where FolderPath has_any ("\\wwwroot\\", "/var/www/")
| where FileName endswith ".php" or FileName endswith ".aspx"
| where InitiatingProcessFileName in~ ("w3wp.exe", "php-cgi.exe", "httpd", "nginx")
| where ActionType == "FileCreated"
| summarize FirstSeen=min(Timestamp), Count=count() by FileName, FolderPath, DeviceName
| where FirstSeen > ago(30d)
| sort by FirstSeen desc index=mde sourcetype="DeviceFileEvents" ActionType=FileCreated (FolderPath="*\\wwwroot\\*" OR FolderPath="*/var/www/*") (FileName="*.php" OR FileName="*.aspx") InitiatingProcessFileName IN ("w3wp.exe","php-cgi.exe","httpd","nginx")
| stats earliest(_time) AS FirstSeen count AS Count by FileName FolderPath DeviceName
| sort - FirstSeen Atomic Red Team Tests
Overwrites a test index.html file in a web-exposed directory using a shell process rather than a deployment tool, simulating the file-tampering path to defacement. Run only against a lab/test web root.
Command
echo '<html><body>TEST DEFACEMENT SIMULATION</body></html>' > /var/www/test-site/index.html Cleanup
git -C /var/www/test-site checkout -- index.html Expected Telemetry
File creation/modification event for index.html in a web-exposed directory, InitiatingProcess is a shell (bash/sh) rather than a known deployment tool.
Expected Detection
Alert fires on WebRootHomepageTamperedByUnexpectedProcess indicator with RiskScore=90.
Simulates a CMS admin login and content-publish action logged from a source IP not present in the account's prior 90-day login history, replicating the credential-theft-then-deface pattern. Requires test CMS audit log entries.
Command
# Insert test CMSAuditLogs_CL rows: login_success then publish_post within 5 minutes, SourceIP=203.0.113.50 (not in prior 90-day set for the test account) Cleanup
Remove the injected test log rows from CMSAuditLogs_CL Expected Telemetry
Two CMS audit log events for the same admin account within 30 minutes: a login followed by a publish action, from an IP absent from the account's known-IP set.
Expected Detection
Alert fires on CMSAdminPublishFromNeverSeenSourceIP indicator with RiskScore=75.