Skip to main content
Back to all investigations
SOC-031·Web·Severity: HighClassification: True PositiveEnvironment: Training Lab

Investigating Web Application SQL Injection via Apache Logs

Log analysis and triage of blind Boolean-based SQL injection attempts against a vulnerable plugin endpoint on a WordPress web server.

EnvironmentDebian 12 Web Server / Apache 2.4 (Lab Instance)
ToolsApache access.log, GoAccess, sqlmap (sanitized reproduction), Burp Suite
MITRE ATT&CKT1190
Published2026-08-02
Safety & Simulation Disclosure

Lab Environment: Executed on an isolated local web server running a deliberately vulnerable WordPress plugin in an educational sandboxed environment.

Executive Summary

Analysis of Apache access logs revealed an automated SQL injection probe directed at /wp-content/plugins/catalog-view/ajax-search.php?cat_id=1. The attacker submitted nested UNION SELECT and SLEEP(5) payloads. The backend database server experienced intermittent query stalls. The vulnerable script passed unescaped user input directly into a mysqli_query() string.

Scenario & Trigger

A monitoring alert reported a 400% spike in HTTP 500 response codes and response latency spikes on a staging e-commerce website.

HTTP 500 Spike & Database Query Latency Alert2026-08-02 16:42:00 UTC
Source: Application Performance Monitor
Endpoint: /wp-content/plugins/catalog-view/ajax-search.php ResponseTime: >5.2s HTTP_Status: 500 RequestCount: 184

Initial Evidence

  • Vulnerable URI: /wp-content/plugins/catalog-view/ajax-search.php
  • Attacker IP: 203.0.113.194 (Tor exit node)
  • Observed Parameter: cat_id
  • Sample Payload: cat_id=1%27%20AND%20(SELECT%206212%20FROM%20(SELECT(SLEEP(5)))a)--%20-

Investigation Methodology & Narrative

Step 1: Examined /var/log/apache2/access.log for requests containing URL-encoded single quotes (%27), UNION, and SLEEP keywords.

Step 2: Traced requests from IP 203.0.113.194. Observed an automated fingerprinting sequence starting with basic quote injection followed by time-based blind SQLi payloads.

Step 3: Inspected the PHP source code of ajax-search.php. Located line 24: $res = mysqli_query($conn, "SELECT * FROM wp_catalog WHERE category_id = " . $_GET['cat_id']);. Zero parameterization or input sanitization was implemented.

Step 4: Checked database audit logs. Verified the queries timed out or failed with syntax errors; no customer table records or administrator password hashes were extracted before the IP was blocked.

Incident Timeline

Time (UTC)EventTelemetry SourceAnalyst Note
16:38:12 UTCInitial single quote probe submittedaccess.logServer returned HTTP 500 due to unhandled SQL syntax error
16:40:05 UTCAutomated tool initiates time-based blind SQLi probesaccess.logSLEEP(5) payload caused 5.02-second response delays
16:42:00 UTCLatency alert triggered in monitoring systemAPM MonitorAnalyst joined investigation
16:50:00 UTCWAF virtual patch applied to block SQL keywords on cat_id parameterModSecurity / Cloudflare WAFImmediate mitigation applied while developer prepared patch

Indicators of Compromise (IOCs)

TypeObserved ValueContextReputation
IPv4203.0.113.194Source IP for automated SQL injection scanner (Tor node)Malicious
URLhxxp://site-lab[.]local/wp-content/plugins/catalog-view/ajax-search.php?cat_id=1Vulnerable endpoint targetedSuspicious

Log Analysis & Telemetry Dissection

Apache Access Log Excerpt/var/log/apache2/access.log
203.0.113.194 - - [02/Aug/2026:16:38:12 +0000] "GET /wp-content/plugins/catalog-view/ajax-search.php?cat_id=1' HTTP/1.1" 500 248 "-" "Mozilla/5.0"
203.0.113.194 - - [02/Aug/2026:16:40:05 +0000] "GET /wp-content/plugins/catalog-view/ajax-search.php?cat_id=1%27%20AND%20(SELECT%206212%20FROM%20(SELECT(SLEEP(5)))a)--%20- HTTP/1.1" 200 412 "-" "sqlmap/1.7"
203.0.113.194 - - [02/Aug/2026:16:40:11 +0000] "GET /wp-content/plugins/catalog-view/ajax-search.php?cat_id=1%20UNION%20ALL%20SELECT%20NULL,NULL,user_login,user_pass%20FROM%20wp_users--%20- HTTP/1.1" 500 248 "-" "sqlmap/1.7"

Analysis Note: Clear evidence of progressive SQL injection probing, showing tool user-agent (sqlmap/1.7) and attempts to dump the wp_users table.

MITRE ATT&CK Mapping

IDTechniqueTacticObserved Evidence
T1190 Exploit Public-Facing ApplicationInitial AccessSQL injection targeting publicly reachable catalog-view endpoint

Findings & Final Classification

True Positive SQL injection exploitation attempt. The vulnerability existed due to legacy unparameterized SQL queries in a custom WordPress plugin. The immediate WAF rule neutralized ongoing probing, and no database exfiltration occurred.

Recommended SOC Response & Hardening

  • •Refactor PHP endpoint to use prepared statements via PDO or WordPress $wpdb->prepare().
  • •Cast incoming cat_id parameter strictly to integer: $cat_id = intval($_GET['cat_id']);.
  • •Deploy ModSecurity Core Rule Set (CRS) or Cloudflare WAF managed ruleset to block common SQL injection vectors.
  • •Audit remaining custom theme and plugin files for similar raw concatenation patterns.

Analyst Reflection: What I Learned

• Time-based blind SQL injection leaves distinct latency signatures in web server access logs (%D or %T formatting in Apache).

• Input type casting ($intval) and prepared statements provide complete immunity against SQL injection when consistently applied.

References & Standards