Grep Patterns for SIEM & Security
|
Learning regex? See the structured curriculum:
This page is a quick reference for security/SIEM patterns. |
Overview
grep (and its faster cousin rg/ripgrep) is the foundation of log analysis and threat hunting. Master these patterns and you’ll slice through terabytes of logs like butter.
Core Syntax
grep [options] 'pattern' file
grep [options] 'pattern' file1 file2 ...
command | grep [options] 'pattern'
Essential Options
| Option | Description | Example |
|---|---|---|
|
Case insensitive |
|
|
Invert match (NOT) |
|
|
Count matches |
|
|
Line numbers |
|
|
Files with matches only |
|
|
Files WITHOUT matches |
|
|
Recursive search |
|
|
Extended regex (ERE) |
|
|
Perl regex (PCRE) |
|
|
Only matching part |
|
|
N lines after |
|
|
N lines before |
|
|
N lines context (before+after) |
|
|
Whole word only |
|
|
Whole line only |
|
|
Patterns from file |
|
|
Quiet (exit status only) |
|
|
Highlight matches |
|
IP Address Hunting
IPv4 Patterns
# Basic IPv4 (catches most)
grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' file
# Strict IPv4 (validates octets 0-255)
grep -P '\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b' file
# Extract IPs only (no surrounding text)
grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' file | sort -u
# RFC1918 private IPs
grep -E '(^10\.|^172\.(1[6-9]|2[0-9]|3[01])\.|^192\.168\.)' file
# Public IPs only (exclude private)
grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' file | \
grep -vE '^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.|127\.)'
# Specific subnet
grep -E '10\.50\.1\.[0-9]{1,3}' file
# CIDR notation
grep -E '[0-9.]+/[0-9]{1,2}' file
IPv6 Patterns
# Basic IPv6
grep -Ei '([0-9a-f]{1,4}:){7}[0-9a-f]{1,4}' file
# IPv6 with compression (::)
grep -Ei '([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}' file
MAC Address Hunting
# Colon-separated (AA:BB:CC:DD:EE:FF)
grep -Ei '([0-9a-f]{2}:){5}[0-9a-f]{2}' file
# Dash-separated (AA-BB-CC-DD-EE-FF)
grep -Ei '([0-9a-f]{2}-){5}[0-9a-f]{2}' file
# Dot-separated Cisco (AABB.CCDD.EEFF)
grep -Ei '([0-9a-f]{4}\.){2}[0-9a-f]{4}' file
# Any format
grep -Ei '([0-9a-f]{2}[:-]){5}[0-9a-f]{2}|([0-9a-f]{4}\.){2}[0-9a-f]{4}' file
# Extract unique MACs
grep -oEi '([0-9a-f]{2}:){5}[0-9a-f]{2}' file | tr '[:lower:]' '[:upper:]' | sort -u
Authentication & Credential Hunting
Login Events
# Failed logins (Linux)
grep -i 'failed\|failure\|invalid' /var/log/auth.log
# SSH failures
grep 'sshd.*Failed password' /var/log/auth.log
# SSH accepted logins
grep 'sshd.*Accepted' /var/log/auth.log
# Sudo commands
grep 'sudo:' /var/log/auth.log
# Su commands
grep 'su\[' /var/log/auth.log
# PAM authentication
grep 'pam_unix' /var/log/auth.log
Windows Security Events
# Failed logins (Event 4625)
grep -E 'EventID[=:]["'\''[:space:]]*4625' security.log
# Successful logins (Event 4624)
grep -E 'EventID[=:]["'\''[:space:]]*4624' security.log
# Account lockouts (Event 4740)
grep -E 'EventID[=:]["'\''[:space:]]*4740' security.log
# Password changes (Event 4723, 4724)
grep -E 'EventID[=:]["'\''[:space:]]*(4723|4724)' security.log
# New user created (Event 4720)
grep -E 'EventID[=:]["'\''[:space:]]*4720' security.log
# User added to privileged group (Event 4728, 4732, 4756)
grep -E 'EventID[=:]["'\''[:space:]]*(4728|4732|4756)' security.log
# Kerberos TGT request (Event 4768)
grep -E 'EventID[=:]["'\''[:space:]]*4768' security.log
# Service ticket request (Event 4769)
grep -E 'EventID[=:]["'\''[:space:]]*4769' security.log
# Multiple events
grep -E 'EventID[=:]["'\''[:space:]]*(4624|4625|4648|4672)' security.log
Credential Exposure
# Passwords in configs (DANGEROUS - audit only!)
grep -riE 'password[[:space:]]*[=:]' /etc/ 2>/dev/null
# API keys and tokens
grep -riE '(api[_-]?key|token|secret)[[:space:]]*[=:]' . 2>/dev/null
# Base64 encoded (potential creds)
grep -oE '[A-Za-z0-9+/]{40,}={0,2}' file
# AWS keys
grep -E 'AKIA[0-9A-Z]{16}' file
# Private keys
grep -l 'PRIVATE KEY' *.pem *.key
Threat Hunting Patterns
Lateral Movement
# SMB/CIFS activity (port 445)
grep -E '(:|\s)445(\s|$|/)' firewall.log
# RDP connections (port 3389)
grep -E '(:|\s)3389(\s|$|/)' firewall.log
# WinRM (ports 5985, 5986)
grep -E '(:|\s)(5985|5986)(\s|$|/)' firewall.log
# PsExec indicators
grep -iE 'psexec|PSEXESVC' event.log
# WMI activity
grep -iE 'wmic|wmiprvse' event.log
# PowerShell remoting
grep -iE 'Enter-PSSession|Invoke-Command' script.log
Data Exfiltration
# DNS tunneling (long subdomains)
grep -E '[a-z0-9]{30,}\.[a-z]+\.[a-z]+' dns.log
# Large outbound transfers
grep -E 'bytes[=:][[:space:]]*[0-9]{7,}' netflow.log
# Uncommon ports
grep -vE '(:|\s)(80|443|53|22|25|110|143|993|995|3389)(\s|$|/)' firewall.log
# Cloud storage domains
grep -iE 'dropbox|onedrive|gdrive|mega\.nz|wetransfer' proxy.log
# Paste sites
grep -iE 'pastebin|hastebin|ghostbin|paste\.ee' proxy.log
Malware Indicators
# Known malware user agents
grep -iE 'python-requests|curl|wget|powershell' access.log | grep -vi 'mozilla'
# Base64 in URLs (potential C2)
grep -E '[?&][a-z]+=[A-Za-z0-9+/]{20,}' access.log
# Suspicious PowerShell patterns
grep -iE 'powershell.*(-enc|-e |encodedcommand|downloadstring|iex|invoke-expression)' event.log
# Encoded commands
grep -iE '(frombase64|tobase64|convert.*base64)' script.log
# Common C2 callbacks
grep -E '/(beacon|check|poll|task|cmd|shell|exec)' proxy.log
# Webshells
grep -iE '(cmd\.php|shell\.php|c99|r57|wso\.php)' access.log
Persistence Mechanisms
# Scheduled tasks (Windows)
grep -iE 'schtasks|taskschd' event.log
# Cron modifications
grep -E '(crontab|/etc/cron)' auth.log
# Service changes
grep -iE '(sc\.exe|systemctl|service.*start)' event.log
# Registry run keys
grep -iE 'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run' event.log
# Startup folder
grep -iE 'Startup' event.log
Firewall & Network Logs
iptables
# All dropped packets
grep 'DPT=' /var/log/firewall.log | grep 'DROP'
# Extract source IPs from drops
grep -oP 'SRC=\K[0-9.]+' /var/log/firewall.log | sort | uniq -c | sort -rn
# Specific port scans
grep 'DPT=22' /var/log/firewall.log | grep -oP 'SRC=\K[0-9.]+' | sort | uniq -c | sort -rn
# SYN floods
grep 'SYN' /var/log/firewall.log | grep -oP 'SRC=\K[0-9.]+' | sort | uniq -c | sort -rn | head -20
pfSense/OPNsense
# Blocked connections
grep 'block' /var/log/filter.log
# Allowed connections
grep 'pass' /var/log/filter.log
# Specific interface
grep 'em0' /var/log/filter.log
Cisco ASA
# Denied connections
grep '%ASA-4-106023' asa.log
# Built connections
grep '%ASA-6-302013' asa.log
# Teardown connections
grep '%ASA-6-302014' asa.log
# Failed authentications
grep '%ASA-6-113005' asa.log
ISE & RADIUS Hunting
# Failed authentications
grep -iE 'failed|reject|deny' ise.log
# Successful authentications
grep -iE 'passed|accept|success' ise.log
# Specific authentication method
grep -i 'EAP-TLS' ise.log
# MAB authentications
grep -i 'MAB' ise.log
# Specific endpoint
grep -i 'aa:bb:cc:dd:ee:ff' ise.log
# Authorization profiles applied
grep -i 'AuthorizationProfile' ise.log
# CoA (Change of Authorization)
grep -iE 'CoA|Reauthenticate|Disconnect' ise.log
# Guest authentications
grep -i 'GuestEndpoints' ise.log
# netapi ISE session analysis
netapi ise mnt sessions | grep -i 'eap-tls'
netapi ise mnt sessions | grep -v 'CONNECTED'
Web Server Logs
Apache/Nginx
# 4xx/5xx errors
grep -E '" (4|5)[0-9]{2} ' access.log
# Specific status codes
grep '" 401 ' access.log # Unauthorized
grep '" 403 ' access.log # Forbidden
grep '" 404 ' access.log # Not Found
grep '" 500 ' access.log # Server Error
# POST requests
grep '"POST ' access.log
# Large responses (data exfil indicator)
awk '$10 > 10000000' access.log # Over 10MB
# SQL injection attempts
grep -iE '(union.*select|select.*from|drop.*table|insert.*into|1=1|or.*1.*=.*1)' access.log
# XSS attempts
grep -iE '(<script|javascript:|onerror=|onload=)' access.log
# Path traversal
grep -E '\.\./\.\.' access.log
# Common scanners
grep -iE '(nikto|sqlmap|nmap|dirbuster|gobuster|burp)' access.log
# Top 20 IPs by requests
grep -oE '^[0-9.]+' access.log | sort | uniq -c | sort -rn | head -20
WAF/ModSecurity
# All ModSecurity blocks
grep 'ModSecurity: Access denied' modsec.log
# Specific rule triggers
grep 'id "942100"' modsec.log # SQL injection
# High severity
grep -E 'severity "[0-2]"' modsec.log
QRadar AQL Output Parsing
# Parse QRadar CSV exports
grep 'High' qradar_export.csv | grep -v 'Header'
# Extract source IPs from offense list
grep -oE 'sourceIP[=:]["'\'']?[0-9.]+' offense.json
# Find specific log sources
grep -i 'windows' qradar_export.csv
# High magnitude events
awk -F',' '$5 > 8' events.csv # Magnitude > 8
Performance Patterns
Count and Statistics
# Count matches
grep -c 'ERROR' file
# Count matches per file
grep -c 'ERROR' *.log | sort -t: -k2 -rn
# Count unique values
grep -oE 'SRC=[0-9.]+' file | sort | uniq -c | sort -rn
# Lines matching multiple patterns (AND)
grep 'pattern1' file | grep 'pattern2'
# Lines matching any pattern (OR)
grep -E 'pattern1|pattern2' file
# Exclude multiple patterns
grep -v 'DEBUG' file | grep -v 'INFO'
# Or: grep -vE 'DEBUG|INFO' file
Large File Handling
# First match only (stop after finding)
grep -m 1 'pattern' hugefile.log
# Last N matches
grep 'pattern' file | tail -20
# Binary file handling
grep -a 'pattern' binary.file
# Null-separated output (for xargs)
grep -lZ 'pattern' *.log | xargs -0 rm
# Parallel grep with xargs
find /var/log -name "*.log" | xargs -P 4 grep -l 'ERROR'
Ripgrep (rg) Advantages
When you need speed, ripgrep is the answer:
# Basic search (ignores .git, binary files)
rg 'pattern' /var/log
# Case insensitive
rg -i 'error'
# Regex search
rg -e 'error|warn|crit'
# File type filter
rg -t py 'import requests'
rg -t log 'ERROR'
# Exclude patterns
rg --glob '!*.bak' 'pattern'
# Count matches
rg -c 'pattern'
# Only matching part
rg -o 'SRC=[0-9.]+'
# JSON output
rg --json 'pattern' | jq
# Search hidden files
rg --hidden 'pattern'
# Fixed string (no regex)
rg -F '10.50.1.1'
# Multiline search
rg -U 'start.*\n.*end'
# Replace (preview)
rg 'old' --replace 'new'
Combined Power Patterns
Grep + Sort + Uniq
# Top 20 error messages
grep -oE 'ERROR[: ]+.*' *.log | sort | uniq -c | sort -rn | head -20
# Top IPs with failed auth
grep 'Failed password' /var/log/auth.log | \
grep -oE 'from [0-9.]+' | \
cut -d' ' -f2 | \
sort | uniq -c | sort -rn | head -10
Grep + AWK
# Grep filter + AWK column extraction
grep 'ERROR' access.log | awk '{print $1, $4, $9}'
# Count by hour
grep '2026-02-12' access.log | \
awk -F: '{print $2":00"}' | \
sort | uniq -c
Grep + SED
# Extract and clean
grep 'password=' config | sed 's/password=.*/password=REDACTED/'
# Format output
grep -E 'SRC=[0-9.]+' firewall.log | \
sed -E 's/.*SRC=([0-9.]+).*/\1/' | \
sort -u
IOC Hunting
# Hunt for IOCs from file
cat iocs.txt | while read ioc; do
grep -r "$ioc" /var/log/ 2>/dev/null && echo "FOUND: $ioc"
done
# Or more efficiently
grep -rFf iocs.txt /var/log/
# With context
grep -rFf iocs.txt -C 3 /var/log/
SIEM Quick Reference Card
+-----------------------------------------------------------------------------+
| GREP SIEM QUICK REFERENCE |
+-----------------------------------------------------------------------------+
| BASIC PATTERNS |
| Case insensitive: grep -i 'error' |
| Invert match: grep -v 'DEBUG' |
| Extended regex: grep -E 'error|warn|crit' |
| Line numbers: grep -n 'ERROR' |
| Count only: grep -c 'ERROR' |
| Files only: grep -l 'ERROR' *.log |
+-----------------------------------------------------------------------------+
| CONTEXT |
| After: grep -A 5 'ERROR' |
| Before: grep -B 5 'ERROR' |
| Both: grep -C 3 'ERROR' |
+-----------------------------------------------------------------------------+
| IP HUNTING |
| Any IPv4: grep -E '[0-9]{1,3}(\.[0-9]{1,3}){3}' |
| Extract only: grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}' |
| Specific subnet: grep -E '10\.50\.1\.' |
| Exclude private: grep -vE '^(10\.|172\.(1[6-9]|2|3[01])\.|192\.168)' |
+-----------------------------------------------------------------------------+
| AUTHENTICATION |
| SSH failures: grep 'Failed password' /var/log/auth.log |
| SSH success: grep 'Accepted' /var/log/auth.log |
| Windows 4625: grep -E 'EventID.*4625' |
| Windows 4624: grep -E 'EventID.*4624' |
+-----------------------------------------------------------------------------+
| THREAT HUNTING |
| Lateral movement: grep -E '(:|\s)(445|3389|5985)(\s|$)' |
| PowerShell: grep -iE 'powershell.*(-enc|downloadstring)' |
| SQL injection: grep -iE 'union.*select|1=1' |
| Path traversal: grep '\.\./\.\.' |
+-----------------------------------------------------------------------------+
| PERFORMANCE |
| First match: grep -m 1 'pattern' |
| Recursive: grep -r 'pattern' /var/log |
| From file: grep -f iocs.txt logs.txt |
| Ripgrep: rg 'pattern' (faster, smarter) |
+-----------------------------------------------------------------------------+
| COMMON COMBOS |
| Top IPs: grep -oE 'IP' file | sort | uniq -c | sort -rn |
| With awk: grep 'ERROR' file | awk '{print $1}' |
| Multiple AND: grep 'A' file | grep 'B' |
| Multiple OR: grep -E 'A|B|C' file |
+-----------------------------------------------------------------------------+
Real-World Workflows
Daily Security Check
#!/bin/bash
# Quick daily security check
echo "=== Failed Auth Last 24h ==="
grep "Failed password" /var/log/auth.log | tail -50
echo -e "\n=== Top Failed IPs ==="
grep "Failed password" /var/log/auth.log | \
grep -oP 'from \K[0-9.]+' | \
sort | uniq -c | sort -rn | head -10
echo -e "\n=== Successful Root Logins ==="
grep "session opened for user root" /var/log/auth.log | tail -10
echo -e "\n=== Sudo Commands ==="
grep "COMMAND=" /var/log/auth.log | tail -20
IOC Sweep
#!/bin/bash
# Sweep logs for IOCs
IOC_FILE="${1:-iocs.txt}"
LOG_DIR="${2:-/var/log}"
echo "=== IOC Sweep: $IOC_FILE against $LOG_DIR ==="
while IFS= read -r ioc; do
[[ -z "$ioc" || "$ioc" =~ ^# ]] && continue
results=$(grep -r "$ioc" "$LOG_DIR" 2>/dev/null)
if [[ -n "$results" ]]; then
echo -e "\n[FOUND] $ioc"
echo "$results" | head -5
fi
done < "$IOC_FILE"
Quick Incident Response
#!/bin/bash
# Quick IR data gathering
SUSPECT_IP="$1"
if [[ -z "$SUSPECT_IP" ]]; then
echo "Usage: $0 <suspect_ip>"
exit 1
fi
echo "=== Hunting for $SUSPECT_IP ==="
echo -e "\n--- Firewall logs ---"
grep "$SUSPECT_IP" /var/log/firewall.log | tail -20
echo -e "\n--- Auth logs ---"
grep "$SUSPECT_IP" /var/log/auth.log | tail -20
echo -e "\n--- Web access ---"
grep "$SUSPECT_IP" /var/log/nginx/access.log 2>/dev/null | tail -20
echo -e "\n--- DNS queries ---"
grep "$SUSPECT_IP" /var/log/dnsmasq.log 2>/dev/null | tail -20