grep -iE "union.*select|or 1=1|sleep\(" access.logFast SQLi sweep. Add information_schema, xp_cmdshell, benchmark\(.
grep -iE "<script|onerror=|javascript:|<svg" access.logXSS probes across the log — markup and event handlers in requests.
grep -En '%3C|%3E|<|>' access.logThe broad net — any angle bracket, raw or URL-encoded (%3C=< %3E=>). Catches encoded/novel XSS the keyword grep misses; noisier, so pair with the loud-IP filter. -n gives line numbers.
grep -E "\.\./|\.\.%2f|%2e%2e" access.logTraversal, raw and URL-encoded. Add etc/passwd, win.ini, php://.
grep -E '\.\./|%2E%2E%2F|%2E%2E%2E%2E%2F%2F' access.logUppercase-encoded traversal and a doubled-char evasion (%2E=. %2F=/). The lowercase line above is case-sensitive and misses these — so run both, or just use grep -iE to cover either case in one pass.
grep -iE "[;|&\`]\s*(id|whoami|cat|curl|wget|ping)\b" access.logCommand-injection probes — a shell separator followed by a recon command.
awk '$9>=500 {print $1}' access.log | sort | uniq -c | sort -rnTop IPs causing 500s — injection often breaks the app first. The awk counting pattern; swap $9 for your status column.
awk '{print $1}' access.log | sort | uniq -c | sort -rn | headLoudest clients — scanners spray. Pivot a noisy IP into the payload greps above, and enrich it with the tools on the home page.
grep -iE "sqlmap|nikto|nuclei|acunetix|nmap|masscan|curl/|python-requests" access.logScanner user-agents — not proof, but a strong prioritization signal.
Decode before you judgeEvasion: URL-encoding (%27=' %3C=<), double-encoding (%253C), case (UnIoN), inline comments (UN/**/ION), and whitespace tricks. URL-decode the log line (twice) before pattern-matching, or you'll miss it.