How to Analyze Nginx & Apache Access Logs to Detect SQL Injection & Exploit Probes

Web server access logs contain a complete chronological ledger of every single HTTP request received by your server. In the aftermath of a security breach, or as part of routine blue-team threat hunting, your access logs hold the vital forensic evidence needed to determine how an attacker gained access, what files were exfiltrated, and which vulnerability signatures were probed on your Linux VPS.

However, when dealing with millions of log lines in /var/log/nginx/access.log, manual inspection is impossible. Sysadmins must master terminal-native forensics tools like grep, awk, sort, uniq, and visual log parsers like GoAccess to rapidly filter attack patterns, detect SQL injection (SQLi) scans, and identify unauthorized file modifications.

1. The Anatomy of Standard Nginx / Apache Log Format

The Combined Log Format records seven crucial fields per line:

192.0.2.45 - - [12/Sep/2026:16:30:15 +0000] "GET /index.php?id=1%27%20UNION%20SELECT%20null HTTP/1.1" 403 162 "-" "sqlmap/1.6#stable"
  • Client IP ($remote_addr): The IP address originating the connection.
  • Timestamp ($time_local): The exact date, time, and UTC offset.
  • Request Line: HTTP Method (GET), URI string, and Protocol (HTTP/1.1).
  • HTTP Status Code: Response code (200, 403, 404, 500).
  • Bytes Sent: Size of response payload (useful for identifying data exfiltration).
  • User-Agent: The client software identifier.

2. Hunting SQL Injection (SQLi) Probes with Grep

Attackers and automated penetration tools (such as sqlmap) append SQL keywords, unions, and quote characters to query parameters. Search your logs for common SQL injection signatures:

# Search for UNION SELECT, benchmark(), sleep(), or OR 1=1 patterns
grep -iE '(union.*select|select.*from|order.*by|[0-9]=1|benchmark\(|sleep\()' /var/log/nginx/access.log

# Extract top offending IPs attempting SQL injections
grep -iE '(union.*select|select.*from|order.*by|[0-9]=1)' /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -nr | head -n 10

3. Detecting Directory Traversal and Local File Inclusion (LFI)

Local File Inclusion attacks attempt to escape the web root to read sensitive operating system files like /etc/passwd or application configs like wp-config.php:

# Search for directory traversal dot-dot-slash patterns
grep -E '(\.\./|\.\.\|%2e%2e%2f|%2e%2e/)' /var/log/nginx/access.log

# Search for direct probes against sensitive Linux files
grep -iE '(/etc/passwd|/proc/version|/boot.ini|win.ini|wp-config\.php\.bak)' /var/log/nginx/access.log

4. Identifying Vulnerability Scanners and Exploit Probes

Automated scanning bots probe common administrative paths and unpatched framework scripts:

# Count 404 probes for phpMyAdmin, adminer, and environment secrets
grep -E '(phpmyadmin|adminer|\.env|\.git/config|\.aws/credentials)' /var/log/nginx/access.log | awk '{print $1, $7, $9}' | head -n 20

To identify the most aggressive IP addresses generating 404 errors (indicative of vulnerability scanning):

awk '($9 ~ /404/) {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -n 15

5. Real-Time Visual Log Analysis with GoAccess

For live interactive forensic dashboards inside your terminal, install GoAccess:

# Install GoAccess
sudo apt install -y goaccess

# Launch real-time terminal dashboard
goaccess /var/log/nginx/access.log --log-format=COMBINED

# Generate standalone visual HTML report
goaccess /var/log/nginx/access.log -o /var/www/html/report.html --log-format=COMBINED --real-time-html

GoAccess provides instant visual graphs detailing top IP addresses, 404 URLs, HTTP status code distributions, bandwidth usage spikes, and active crawler user agents.

Automated Forensic Analysis: Log Rotation, GeoIP Audits & Awk Filters

Modern blue-team sysadmins leverage automated bash pipelines and GeoIP geolocation parsing to investigate server security incidents in seconds:

  • Tracking Data Exfiltration with Bytes-Sent Filters: When an attacker exploits an SQL injection or downloads unauthorized database dumps, the response payload size is massive compared to standard HTML pages. Filter access logs for unusually large successful HTTP responses (e.g., > 10MB):
    # Find requests where bytes sent exceed 10,000,000 bytes (10MB)
    awk '($9 ~ /200/) && ($10 > 10000000) {print $1, $4, $7, $10}' /var/log/nginx/access.log | head -n 20
  • GeoIP Enrichment for Suspicious Access Logs: Combine awk with geoiplookup to map attacking IP addresses to their originating geographic jurisdiction:
    grep -i "admin" /var/log/nginx/access.log | awk '{print $1}' | sort -u | while read IP; do
        echo "$IP - $(geoiplookup $IP | cut -d: -f2)"
    done | head -n 15
  • Detecting Web Shell Interactions via POST Frequency: Stealth web shells (e.g., hidden uploader.php files) typically receive frequent HTTP POST requests containing base64 command strings. Search your logs for unusual POST requests targeting obscure file paths:
    grep "POST" /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -nr | head -n 15

    Any unrecognized PHP file receiving POST requests outside of wp-login.php and admin-ajax.php warrants immediate filesystem inspection.

Automated Log Forensics: Cron-Driven Attack Alerts & Discord Webhooks

Transform reactive post-breach log analysis into an automated real-time incident alert engine using a lightweight bash script:

  • Automated Hourly SQLi and Traversal Scanner: Schedule a cron script that parses recent access logs and sends instant webhooks to your team’s Discord or Slack channel if attack frequency exceeds baseline thresholds:
    #!/usr/bin/env bash
    LOG="/var/log/nginx/access.log"
    ATTACKS=$(grep -iE '(union.*select|\.\./|etc/passwd)' "$LOG" | wc -l)
    
    if [ "$ATTACKS" -gt 10 ]; then
        curl -H "Content-Type: application/json" -X POST       -d "{"content": "⚠️ Alert: $ATTACKS SQL injection / LFI probes detected on production VPS!"}"       https://discord.com/api/webhooks/YOUR_WEBHOOK_URL
    fi
  • Log Rotation Tuning to Preserve Evidence: Ensure /etc/logrotate.d/nginx retains at least 90 days of compressed log history (rotate 90) to support historical compliance audits.

Run Forensics on High-Performance CpanelFree VPS

Analyze gigabytes of log data with high-speed NVMe storage and dedicated CPU cores. Experience enterprise-grade hosting reliability and root control on CpanelFree.

Discover CpanelFree Cloud VPS Hosting →

Leave a Comment