Threat Hunting Exercise: Analyzing Database SQL Injection Mass Data Exfiltration Dataset
This hunt uses a simulated web application/database audit dataset (db_sqli_exfil_2022-07-23T160000.json) capturing T1190: Exploit Public-Facing Application and T1213: Data from Information Repositories, where an adversary exploits an unsanitized input field on a public web application to run UNION-based SQL injection queries, ultimately dumping an entire customer table via a scripted, high-volume series of requests.
Step 1: Hypothesis Formation
Hypothesis: A public-facing web application receives a series of HTTP requests to a single parameter containing SQL injection syntax (UNION SELECT, ' OR '1'='1, time-based blind indicators like SLEEP()/WAITFOR DELAY), from a single source IP, escalating from exploratory single-quote tests to full UNION-based data extraction, correlated with an unusual spike in database-layer SELECT statements against sensitive tables. Indicators:
- WAF/application logs: requests to a parameter (e.g.,
?id=) containing SQL metacharacters and keywords, increasing in sophistication over a short session. - Database audit log: a spike in SELECT statement volume against a customer/PII table, originating from the web application's service account, correlated in time with the suspicious HTTP requests.
- Response size/timing anomalies: unusually large response bodies or consistent time-delay patterns (for blind SQLi) correlating with specific injected payloads.
- Single source IP conducting the full sequence, often with a non-browser User-Agent (e.g.,
sqlmap,python-requests).
Null Hypothesis: The requests are from an authorized penetration test or vulnerability scan. Invalidate via the security testing calendar and by confirming the source IP is not on the approved pentest IP allow-list.
Rationale: SQL injection remains one of the most impactful and common web application vulnerabilities; this hunt validates correlating WAF/application-layer signals with database-audit-layer volume anomalies to confirm not just an attempted exploit but successful, large-scale data extraction.
Step 2: Data Sources and Scope
- Sources: WAF/application logs (request URIs, parameters, User-Agent); Database audit logs (query text, rows returned, calling account); Pentest/security-testing calendar (for legitimacy cross-check).
- Scope: ~2022-07-23T16:00:00-16:40:00 UTC; Source IP: 194.87.102.33; Target:
shop.contoso.com/product?id=; Database:prod_customers(MySQL). - SIEM Queries (Splunk/ELK):
- SQLi pattern detection:
index=waf uri_query="UNIONSELECT" OR uri_query="' OR '1'='1" OR uri_query="SLEEP(*" - DB SELECT volume spike:
index=db_audit db_user="webapp_svc" query_type=SELECT table="customers" | stats count by bucket(_time,5m) - Source-IP session reconstruction:
index=waf src_ip="194.87.102.33" | table _time, uri, status_code, response_bytes
Step 3: Key Findings
Parsed events (7 shown) confirm an escalating SQL injection session culminating in a full customer-table dump via UNION-based extraction.
| Timestamp (UTC) | Src IP | Request | DB Correlation | IOC/Why Suspicious? |
|---|---|---|---|---|
| 2022-07-23 16:02:11 | 194.87.102.33 | GET /product?id=1' | Query error logged | Exploratory IOC: single quote injection - classic first-step SQLi probing to trigger a database error and confirm injectability. |
| 2022-07-23 16:04:33 | 194.87.102.33 | GET /product?id=1 AND SLEEP(5) | Response time = 5.02s | Blind-SQLi IOC: response delay exactly matches the injected sleep duration - confirms time-based blind SQL injection is viable on this parameter. |
| 2022-07-23 16:10:02 | 194.87.102.33 | GET /product?id=1 UNION SELECT table_name,NULL FROM information_schema.tables-- | DB audit: information_schema queried by webapp_svc | Schema enumeration - attacker mapping available tables before extraction. |
| 2022-07-23 16:15:47 | 194.87.102.33 | GET /product?id=1 UNION SELECT username,password FROM customers LIMIT 0,500-- | DB audit: SELECT against customers, 500 rows returned | Extraction IOC: first UNION-based extraction batch - 500 rows of username/password data returned in a single response. |
| 2022-07-23 16:16-16:38 | 194.87.102.33 | 47 additional paginated UNION SELECT requests (LIMIT n,500) | DB audit: cumulative 23,500 rows selected from customers | Scale IOC: systematic pagination through the entire table - total rows extracted approximates the table's full known row count (23,612), indicating a complete dump. |
| - | - | (User-Agent) | python-requests/2.25.1 on every request | Automation IOC: non-browser User-Agent used consistently across the entire 40-minute session - scripted attack tool, not manual browsing. |
| - | - | (pentest calendar) | No approved test scheduled for this application/window; source IP not on pentest allow-list | Legitimacy check IOC: rules out authorized security testing. |
Validation:
- Timeline: Exploratory probe → blind-injection confirmation → schema enumeration → paginated full-table extraction over 40 minutes - a complete, methodical SQLi-to-exfiltration chain.
- False Positives: Pentest calendar and IP allow-list checks rule out authorized testing; the row count matching the table's full size confirms this was a successful complete dump, not a benign or failed attempt.
- Correlation: Single source IP, single vulnerable parameter, tight WAF-to-database-audit correlation - high-confidence successful breach.
Step 4: Recommendations & Next Steps
- Immediate Response: Patch the vulnerable parameter immediately (parameterized queries/prepared statements); block 194.87.102.33 at the WAF/firewall; force password resets for all affected customer accounts (password field was in the exfiltrated columns) and assess whether passwords were hashed/salted adequately; notify legal/compliance for potential breach-disclosure obligations given PII exposure.
- Detection: Sigma/WAF-style rule:
title: SQLi UNION SELECT Pattern with Large Result Set→selection: uri_query contains "UNION SELECT" AND response_bytes > baseline_thresholdcorrelated withdb_audit rows_returned > 100 on sensitive tables- chain WAF and DB-audit alerting for higher-confidence, lower-noise detection. - Pro Tip: Database audit logging on sensitive tables (with row-count-returned metrics) is an underused but extremely high-value hunting data source - WAF logs alone often can't confirm whether an injection attempt actually succeeded in extracting data; the database layer is where "attempted" becomes "confirmed breach."
Hypothesis confirmed - a systematic SQL injection attack successfully extracted the complete customer table (23,500+ rows including credentials) via paginated UNION SELECT queries!