SOP-13: Web Application Attack Response

·

Web application attacks (SQL injection, XSS, RCE, deserialization, SSRF, file upload bypass) target public-facing endpoints to reach the database, the underlying server, or downstream services. They differ from infrastructure attacks because the entry point is your own code — patching the server doesn't fix the bug.

Detection lives at three layers: edge WAF (Azure Front Door / AWS WAF / Cloudflare), application telemetry (App Service logs, container stdout, structured app logs in Sentinel), and database/process behaviour (EDR catching the shell, SQL audit logs catching the suspicious query). This SOP routes alerts from any of those layers into a single triage flow and gives KQL/SPL for the most common signals.

◈ Table of Contents

01 Background 02 Identification 03 Containment 04 Eradication 05 Escalation
01

Background

CONTEXT
B1Attack Classes & MITRE Mapping
AttackMITREKey IndicatorSeverity
SQL InjectionT1190 (Exploit Public-Facing App)WAF SQLI rule hit; UNION SELECT / OR 1=1 / SLEEP( in URI/body; DB anomaly: bulk SELECTsHIGH
Reflected / Stored / DOM XSST1059.007 (JavaScript)<script> / onerror= / javascript: in input; CSP report-uri hits; cookie exfil GET requestsHIGH
Remote Code ExecutionT1190 + T1059Web worker (w3wp / node / php-fpm / java) spawns cmd.exe / bash / curl / wget / powershellCRITICAL
SSRFT1190 + T1078.004App makes requests to 169.254.169.254 (cloud metadata), localhost, or internal private rangesCRITICAL
Insecure DeserializationT1059Serialized blob (ysoserial, pickle, PHP serialized) followed by suspicious child processCRITICAL
File Upload Bypass / WebshellT1505.003.jsp/.aspx/.php written to web root by web user; subsequent executionCRITICAL
Path Traversal / LFIT1083 (File & Dir Discovery)../ / ..%2f / encoded variants reading /etc/passwd, web.config, .envHIGH
B2Log Sources
SourceTable / PortalKey Events
Azure Front Door / App Gateway WAFAzureDiagnostics (ResourceType=APPLICATIONGATEWAYS / FRONTDOORS)action_s = Blocked/Allowed, ruleName, requestUri
App Service / Container logsAppServiceHTTPLogs, AppServiceConsoleLogs, ContainerLogV25xx errors, stack traces, suspicious request bodies
EDR (Defender for Endpoint)DeviceProcessEventsWeb worker process tree (w3wp.exe → cmd.exe, java → bash)
SQL Audit / Query StoreSQLSecurityAuditEvents / Postgres auditLong queries, UNION patterns, bulk SELECT, sysobjects access
CSP report endpointApp custom tableInline script violations from user input pages
02

Identification

INVESTIGATE
Web App Attack — Investigation Workflow
I1WAF — Triage the Attacking SourceKQL
KQL — Sentinel: WAF blocks by source IP & rule
// All WAF actions in last 48h, group by source + rule to see the campaign shape AzureDiagnostics | where TimeGenerated > ago(48h) | where ResourceType in ("APPLICATIONGATEWAYS", "FRONTDOORS") | where Category in ("ApplicationGatewayFirewallLog", "FrontDoorWebApplicationFirewallLog") | extend SrcIP = column_ifexists("clientIp_s", clientIP_s) | extend Action = column_ifexists("action_s", action_s) | summarize Hits=count(), Rules=make_set(ruleName_s, 20), URIs=make_set(requestUri_s, 10), Actions=make_set(Action, 5) by SrcIP, bin(TimeGenerated, 1h) | where Hits > 5 | order by Hits desc
KQL — Were any malicious payloads Allowed (bypass)?
AzureDiagnostics | where TimeGenerated > ago(7d) | where Category in ("ApplicationGatewayFirewallLog", "FrontDoorWebApplicationFirewallLog") | where action_s == "Detected" // logged but NOT blocked or action_s == "Allowed" | where ruleName_s has_any ("SQLI", "XSS", "RCE", "LFI", "RFI", "PROTOCOL_ENFORCEMENT") | project TimeGenerated, clientIp_s, requestUri_s, ruleName_s, action_s, message_s | order by TimeGenerated desc

WAF in Detection-only mode is a common silent failure — payloads are logged but allowed through. Confirm Prevention mode on production WAFs and treat any "Detected" with sensitive rule names as if it was a successful exploit.

I2RCE — Web Worker Spawning ShellKQL
KQL — Defender for Endpoint: web worker → shell
// Highest-fidelity signal for web RCE DeviceProcessEvents | where TimeGenerated > ago(7d) | where InitiatingProcessFileName in~ ("w3wp.exe", "node.exe", "php-fpm", "java", "python.exe", "python3", "tomcat.exe") | where FileName in~ ("cmd.exe", "powershell.exe", "pwsh.exe", "bash", "sh", "wget", "curl", "certutil.exe", "bitsadmin.exe", "nslookup.exe", "whoami.exe") | project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, FileName, ProcessCommandLine, AccountName | order by TimeGenerated desc
KQL — Webshell written to web root
DeviceFileEvents | where TimeGenerated > ago(7d) | where FolderPath has_any ("\\wwwroot\\", "/var/www/", "/htdocs/", "/webapps/") | where FileName endswith ".jsp" or FileName endswith ".aspx" or FileName endswith ".asp" or FileName endswith ".php" or FileName endswith ".jspx" | where InitiatingProcessAccountName !in~ ("administrator", "system") | project TimeGenerated, DeviceName, FileName, FolderPath, InitiatingProcessFileName, InitiatingProcessAccountName | order by TimeGenerated desc
I3SQLi — Database Anomaly DetectionKQL + SPL
KQL — Azure SQL audit: UNION / sleep payloads
AzureDiagnostics | where TimeGenerated > ago(7d) | where ResourceType == "SERVERS/DATABASES" | where Category == "SQLSecurityAuditEvents" | where statement_s has_any ("UNION SELECT", "WAITFOR DELAY", "SLEEP(", "BENCHMARK(", "EXTRACTVALUE(", "UPDATEXML(", "INFORMATION_SCHEMA") | project TimeGenerated, client_ip_s, server_principal_name_s, database_name_s, statement_s | order by TimeGenerated desc
SPL — Splunk: Long queries from web app account
index=db sourcetype=mssql:audit | where len(statement) > 1000 OR match(statement, "(?i)union\s+select|sleep\(|waitfor\s+delay") | stats count by client_ip, server_principal_name, _time | sort -count
I4FP vs TP Decision Gate
True-Positive SignalsFalse-Positive Signals
WAF blocks rising sharply from one IP/ASN across many parametersDocumented internal pen-test or DAST scan window
5xx error spike correlated with WAF "Detected" entries for SQLI/XSS rulesBad release deploying broken SQL — no malicious payload in body
w3wp.exe → cmd.exe + outbound curl/wget to attacker IPLegitimate sidecar diagnostic running scheduled curl probe
New .jsp / .aspx / .php in webroot written by app pool identity outside deploy windowCI/CD agent legitimately writing app files during deploy
03

Containment

STOP IT
C1Stop the BleedingImmediate
  • 1
    Block attacker IP at WAF: Add IP/ASN to Custom Rule with action=Block at the highest priority. Verify in next request that the rule fires.
  • 2
    If RCE confirmed — isolate the webserver: Defender for Endpoint → Devices → Isolate. For App Service / containers, scale the affected instance to 0 or rotate it out of rotation immediately.
  • 3
    Kill webshell processes: Live Response → Get-Process -Name w3wp,node,php-fpm, identify suspicious child PIDs, Stop-Process -Id [PID] -Force.
  • 4
    Revoke any session that was stolen: If XSS exfil confirmed, force-logout the affected users; invalidate JWT signing keys; rotate session cookies secret.
  • 5
    Block egress where shell tried to call out: Add firewall rule denying webserver outbound to attacker C2; verify SNI/IP in proxy logs.
C2Limit Blast Radius
  • 1
    Rotate DB credential used by the app: If SQLi succeeded, the connection string is implicitly exposed; rotate it and update the app config.
  • 2
    Revoke cloud metadata token if SSRF: For SSRF to 169.254.169.254, rotate IAM role / managed identity credentials. Force re-issuance.
  • 3
    Snapshot for forensics, then keep WAF rule in place until the underlying code is patched — assume the attacker will try again.
04

Eradication

CLEAN UP
E1Fix the Bug, Not Just the Symptom
  • 1
    Identify the vulnerable parameter from the attack payload. Patch the code: parameterised queries for SQLi, context-aware output encoding + CSP for XSS, allow-list deserialization, server-side URL allow-list for SSRF.
  • 2
    Remove every webshell file written during the incident. Verify by hash comparison against gold image. Rebuild any host where a shell ran rather than just deleting files.
  • 3
    Reset secrets the attacker could have read: DB creds, API keys, OAuth client secrets, JWT signing keys, encryption keys stored on the webserver.
  • 4
    Re-run identification KQL queries — expected: 0 matches for the incident window.
  • 5
    Ship the fix, then remove the WAF custom rule blocking the payload (or convert it from custom block to a structured WAF managed rule update).
Eradication Complete When
  • Vulnerable code patched, peer-reviewed, deployed to all environments
  • All webshells removed; affected hosts rebuilt from gold image
  • Database credentials, JWT keys, and API secrets rotated
  • WAF managed ruleset upgraded; logging confirmed for next 48h
  • Threat-model review scheduled for the affected endpoint class
05

Escalation

TIERS
ESC1Escalation Tiers
TierTriggerAction / Handoff Bundle
L1 → L2WAF detect / block of high-severity rule; cannot determine bypass within 30 minSource IPs, payload samples, rule names, URI patterns
L2 → IR TeamRCE confirmed (shell from web worker), OR webshell on disk, OR SSRF reached metadataProcess tree, file artifacts, network egress, isolation status
IR → CISO + Legal + PrivacyConfirmed customer data extracted via SQLi/SSRF; PCI / PII / PHI rows touchedAffected row count, column-level scope, regulatory notification clock start
Engineering On-CallVulnerability is in code (not config) and needs hotfixReproduction request, suspect commit/file, suggested patch

Authorized security research & penetration testing only. Unauthorized use is illegal. Authored by Rudra Verma | Senior Security Architect | CyberHawk Threat Intel.

◈ Stay Connected

Follow CyberHawk Threat Intel for SOC SOPs, threat intelligence, and hands-on analyst tooling.

Website YouTube Twitter / X TikTok Telegram
SOPs Blog Courses

"They can't exploit you if you are the Exploit."