Security Log Analysis Guide
Overview
Logs are the foundation of every security investigation, threat hunt, and incident response. Without quality logging and the ability to analyze it effectively, defenders are operating blind. This guide covers the most critical log sources a SOC analyst encounters daily - from Windows Event Logs and Linux system logs to cloud provider audit trails and network flow data.
Understanding log formats, key fields, and what normal vs. anomalous looks like in each source is a core competency for any security practitioner.
Log Source Priority Matrix
| Log Source | Detection Value | Volume | Priority |
|---|---|---|---|
| Windows Security Event Log | Very High | High | Critical |
| Windows Sysmon | Very High | Very High | Critical |
| DNS Logs | High | Very High | Critical |
| Firewall/NGFW Logs | High | Very High | Critical |
| Linux Auth Logs | High | Medium | High |
| Web Server Logs | High | High | High |
| Network Flow (Zeek/NetFlow) | High | Very High | High |
| Cloud Audit Logs | High | Medium | High |
| Email Logs | Medium | High | Medium |
| Endpoint EDR Logs | Very High | Very High | Critical |
Windows Event Logs
Windows Event Logs are the primary data source for detecting attacks against Windows systems and Active Directory environments. The Security, System, Application, and PowerShell logs each serve distinct detection purposes.
Critical Windows Event Log Channels
| Log Channel | Location | Key Detection Use |
|---|---|---|
| Security | %SystemRoot%\System32\winevt\Logs\Security.evtx | Authentication, account changes, privilege use, object access |
| System | %SystemRoot%\System32\winevt\Logs\System.evtx | Service installs, driver loads, system errors |
| Application | %SystemRoot%\System32\winevt\Logs\Application.evtx | Application crashes, errors, custom app events |
| PowerShell/Operational | Microsoft-Windows-PowerShell/Operational | PowerShell command execution, script block logging |
| Sysmon | Microsoft-Windows-Sysmon/Operational | Process creation, network connections, file creation, registry |
| TaskScheduler | Microsoft-Windows-TaskScheduler/Operational | Scheduled task creation and execution - persistence |
| WMI Activity | Microsoft-Windows-WMI-Activity/Operational | WMI queries and event subscriptions - persistence/lateral movement |
Critical Security Event IDs
| Event ID | Description | Why It Matters |
|---|---|---|
4624 | Successful logon | Baseline normal activity, detect anomalous logon times/locations |
4625 | Failed logon | Brute force detection, password spraying |
4648 | Logon using explicit credentials | Pass-the-hash, lateral movement detection |
4672 | Special privileges assigned | Privilege escalation, admin logons |
4688 | Process creation | Malware execution, living-off-the-land detection |
4698 | Scheduled task created | Persistence mechanism detection |
4720 | User account created | Unauthorized account creation |
4728/4732 | Member added to security group | Privilege escalation, group modification |
4768 | Kerberos TGT requested | Kerberoasting, AS-REP roasting detection |
4769 | Kerberos service ticket requested | Kerberoasting - look for RC4 encryption type |
4776 | NTLM authentication | Pass-the-hash, NTLM relay attacks |
7045 | New service installed | Malware persistence via service installation |
Sysmon Key Event IDs
| Sysmon ID | Description | Detection Use |
|---|---|---|
1 | Process creation | Malware execution, LOLBAS detection |
3 | Network connection | C2 beaconing, lateral movement |
7 | Image loaded (DLL) | DLL injection, process hollowing |
8 | CreateRemoteThread | Process injection detection |
10 | ProcessAccess | Credential dumping (lsass access) |
11 | FileCreate | Malware dropped to disk, webshells |
12/13 | Registry events | Registry persistence, Run keys |
22 | DNS query | DNS tunneling, C2 resolution |
25 | Process tampering | Process hollowing, herpaderping |
Linux / Unix Logs
Linux logs are distributed across multiple files depending on the distribution and configuration. Understanding where each log lives and what it records is essential for Linux-based incident response and threat hunting.
Key Linux Log Files
| Log File | Location | Contents |
|---|---|---|
| auth.log / secure | /var/log/auth.log (Debian) /var/log/secure (RHEL) | SSH logins, sudo usage, PAM authentication, su commands |
| syslog / messages | /var/log/syslog /var/log/messages | General system messages, kernel events, service activity |
| audit.log | /var/log/audit/audit.log | Auditd records - syscalls, file access, user commands |
| cron | /var/log/cron.log | Scheduled job execution - persistence detection |
| wtmp / btmp | /var/log/wtmp /var/log/btmp | Login history (wtmp) and failed logins (btmp) |
| lastlog | /var/log/lastlog | Most recent login per user |
| kern.log | /var/log/kern.log | Kernel messages - rootkit detection, module loads |
| bash_history | ~/.bash_history | User command history - post-compromise activity |
Common Linux Log Analysis Commands
# Failed SSH login attempts
grep "Failed password" /var/log/auth.log
grep "Failed password" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -rn
# Successful SSH logins
grep "Accepted password\|Accepted publickey" /var/log/auth.log
# sudo usage
grep "sudo:" /var/log/auth.log
# New user creation
grep "useradd\|adduser" /var/log/auth.log
# Check login history
last -a | head -50
lastb | head -50 # Failed logins (requires root)
# Auditd - track file access
ausearch -f /etc/passwd
ausearch -k passwd_changes # If rule configured
# Recent cron jobs
grep "CMD" /var/log/cron.log | tail -50
# Check for suspicious bash history
cat /home/*/.bash_history 2>/dev/null
cat /root/.bash_history 2>/dev/null
# Find recently modified files
find /tmp /var/tmp /dev/shm -newer /proc -type f 2>/dev/null
find / -mtime -1 -type f 2>/dev/null | grep -v proc
Suspicious Linux Log Patterns
- SSH logins from unusual geographic IPs or at unusual hours
- Multiple failed logins followed by a success (brute force)
- New cron jobs added to /etc/cron* directories
- Commands run via sudo that are not typical for that user
- New user accounts created or existing accounts modified
- Base64 encoded commands in bash history
- curl/wget downloading files to /tmp or /dev/shm
- Kernel module loads (insmod, modprobe) - possible rootkit
Web Server Logs
Web server logs record every HTTP request made to your web applications. They are critical for detecting web attacks, unauthorized access, and reconnaissance activity.
Apache / Nginx Access Log Format
# Apache Combined Log Format
192.168.1.100 - admin [26/Aug/2026:14:32:01 +0000] "GET /admin/config.php HTTP/1.1" 200 4521 "https://target.com" "Mozilla/5.0"
# Fields:
# %h - Client IP address
# %l - Ident (usually -)
# %u - Authenticated username
# [%t] - Timestamp
# "%r" - Request line (method, URI, protocol)
# %>s - HTTP status code
# %b - Response size in bytes
# "%{Referer}" - Referrer URL
# "%{User-Agent}" - User agent string
# Nginx default log format
$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"
Web Log Analysis Commands
# Top requesting IPs
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -20
# HTTP 4xx and 5xx errors
awk '$9 ~ /^[45]/' access.log | awk '{print $1, $7, $9}' | sort | uniq -c | sort -rn
# SQL injection attempts
grep -i "select\|union\|insert\|drop\|1=1\|or%20\|' or" access.log
# XSS attempts
grep -i "script\|onerror\|onload\|javascript\|alert(" access.log
# Directory traversal
grep -i "\.\./\|%2e%2e\|%252e" access.log
# Scanning tools detection
grep -i "nikto\|sqlmap\|nmap\|masscan\|dirbuster\|gobuster\|burpsuite" access.log
# Large response sizes (potential data exfiltration)
awk '{if ($10 > 1000000) print $0}' access.log
# Requests to sensitive files
grep -i "\.env\|wp-config\|config\.php\|\.git\|passwd\|shadow" access.log
# POST requests (form submissions, potential attacks)
grep '"POST' access.log | awk '{print $1, $7}' | sort | uniq -c | sort -rn
Suspicious Web Log Patterns
| Pattern | Possible Attack | Example |
|---|---|---|
| Sequential numeric IDs in URL | IDOR enumeration | /api/users/1, /api/users/2... |
| SQL keywords in parameters | SQL injection | ?id=1' OR 1=1-- |
| Script tags in parameters | XSS testing | ?name=<script>alert(1)</script> |
| ../../../ in path | Path traversal | /download?file=../../../etc/passwd |
| High 404 rate from one IP | Directory brute force | Multiple 404s in rapid succession |
| Requests to admin paths | Admin panel discovery | /admin, /wp-admin, /phpmyadmin |
| Empty or generic User-Agent | Automated scanner/bot | User-Agent: python-requests/2.28 |
| HTTP methods PUT/DELETE/TRACE | Method tampering | TRACE / HTTP/1.1 |
Firewall Logs
Firewall logs record allowed and denied network connections. They are essential for detecting port scans, lateral movement, C2 communications, and data exfiltration.
Key Firewall Log Fields
| Field | Description | Detection Use |
|---|---|---|
| src_ip / dst_ip | Source and destination IP addresses | External IPs communicating with internal hosts |
| src_port / dst_port | Source and destination ports | Unusual port usage, known malware ports |
| action | Allow / Deny / Drop | High deny rates from internal hosts = possible scanning |
| bytes_sent / bytes_recv | Data transferred | Large outbound transfers = possible exfiltration |
| duration | Connection duration | Long connections = possible C2 beaconing |
| protocol | TCP/UDP/ICMP | ICMP tunneling, unusual protocol use |
Firewall Detection Queries (KQL - Kibana)
# Internal host scanning - high deny count from single source
action: "deny" AND src_ip: 10.0.0.0/8
| stats count by src_ip, dst_port
| where count > 100
# Outbound connections to unusual ports
dst_port: (4444 OR 1337 OR 8888 OR 9001 OR 31337) AND action: "allow"
# Large outbound data transfers
action: "allow" AND direction: "outbound" AND bytes_sent > 10000000
# Connections to known malicious IP ranges (enrich with threat intel)
dst_ip: [IOC_LIST] AND action: "allow"
# Internal to internal on admin ports (lateral movement)
src_ip: 10.0.0.0/8 AND dst_ip: 10.0.0.0/8
AND dst_port: (22 OR 3389 OR 445 OR 5985 OR 5986)
# Beaconing detection - regular interval connections
action: "allow" AND dst_ip: [external]
| bucket @timestamp 1m
| stats count by dst_ip, _bucket
| where stddev(count) < 2 # Very regular = suspicious
Network Logs - Zeek (Bro)
Zeek (formerly Bro) is an open source network analysis framework that generates structured log files from network traffic. Security Onion ships with Zeek by default, making it a standard tool in open source SOC environments.
Zeek Log Files
| Log File | Contents | Key Fields |
|---|---|---|
| conn.log | All network connections | src_ip, dst_ip, port, proto, duration, bytes |
| dns.log | DNS queries and responses | query, qtype, answers, rcode |
| http.log | HTTP transactions | host, uri, method, status_code, user_agent |
| ssl.log | TLS/SSL handshakes | server_name, issuer, subject, cipher |
| files.log | Files transferred over network | filename, mime_type, md5, sha256 |
| weird.log | Unusual protocol behavior | name, addl (additional info) |
| notice.log | Zeek-generated alerts | note, msg, src, dst |
| smtp.log | Email transactions | from, to, subject, last_reply |
Zeek Log Analysis with Zeek-cut
# Top DNS queries
zeek-cut query < dns.log | sort | uniq -c | sort -rn | head -20
# DNS queries with NXDOMAIN (failed - possible DGA/C2)
zeek-cut query rcode < dns.log | grep "NXDOMAIN" | awk '{print $1}' | sort | uniq -c | sort -rn
# Long HTTP connections (possible C2 beaconing)
zeek-cut id.orig_h id.resp_h id.resp_p duration < conn.log | \
awk '$4 > 3600' | sort -k4 -rn | head -20
# Large outbound data transfers
zeek-cut id.orig_h id.resp_h orig_bytes resp_bytes < conn.log | \
awk '$3 > 10000000 || $4 > 10000000' | sort -k3 -rn
# Unique user agents in HTTP
zeek-cut user_agent < http.log | sort -u | grep -iv "mozilla\|chrome\|safari"
# Files downloaded - check hashes
zeek-cut filename md5 sha256 mime_type < files.log | grep -v "^-"
# SSL certificates - self-signed or unusual issuers
zeek-cut server_name issuer < ssl.log | grep -iv "Let's Encrypt\|DigiCert\|Comodo"
Authentication Logs
Authentication logs from identity providers and directory services are critical for detecting account compromise, credential attacks, and unauthorized access.
Active Directory Authentication Events
| Event ID | Event | Attack Indicator |
|---|---|---|
4740 | Account locked out | Multiple lockouts = password spray or brute force |
4767 | Account unlocked | Repeated unlock pattern = active attack |
4768 | Kerberos TGT requested | AS-REP roasting if pre-auth not required |
4769 | Kerberos service ticket | Kerberoasting if RC4 (0x17) encryption type |
4771 | Kerberos pre-auth failed | Password spraying against domain accounts |
4776 | NTLM auth attempt | Pass-the-hash if from unexpected source |
Password Spray Detection Pattern
# Password spray - many accounts, few attempts each
# EventID 4625 - Failed logon
EventID: 4625 AND LogonType: 3
| stats count by TargetUserName, IpAddress
| where count < 5 # Low per-account attempts
| stats count by IpAddress
| where count > 20 # High number of different accounts
# Result: Single IP trying many usernames = spray
Cloud Logs
Cloud provider audit logs record API calls, configuration changes, and access events across your cloud infrastructure. These logs are essential for detecting cloud-specific attacks including misconfiguration exploitation, credential theft, and lateral movement within cloud environments.
AWS CloudTrail
CloudTrail records all AWS API calls made in your account including identity, time, source IP, and request parameters.
{
"eventVersion": "1.08",
"userIdentity": {
"type": "IAMUser",
"userName": "john.doe",
"arn": "arn:aws:iam::123456789:user/john.doe"
},
"eventTime": "2026-08-26T14:32:01Z",
"eventSource": "s3.amazonaws.com",
"eventName": "GetObject",
"sourceIPAddress": "203.0.113.5",
"requestParameters": {
"bucketName": "sensitive-data-bucket",
"key": "customer-data.csv"
},
"responseElements": null,
"errorCode": null
}
Critical AWS CloudTrail Events to Monitor
| Event | Why Monitor |
|---|---|
| ConsoleLogin with MFA: No | Login without MFA - credential theft risk |
| CreateAccessKey | New programmatic access created - possible persistence |
| DeleteTrail / StopLogging | Attacker disabling audit trail |
| AuthorizeSecurityGroupIngress | Security group opened - possible backdoor |
| GetSecretValue | Secrets Manager access - credential harvesting |
| AssumeRoleWithWebIdentity | Role assumption - privilege escalation |
| PutBucketPolicy / PutBucketAcl | S3 bucket permissions changed - data exposure |
| CreateUser / AttachUserPolicy | IAM user creation or policy attachment - persistence |
SIEM Log Ingestion
Getting logs into your SIEM correctly is as important as having the logs in the first place. Proper parsing, normalization, and enrichment significantly improve detection quality.
ELK Stack Ingestion Pipeline
# Filebeat configuration for Windows Event Logs
filebeat.inputs:
- type: winlog
event_logs:
- name: Security
ignore_older: 72h
- name: Microsoft-Windows-Sysmon/Operational
- name: Microsoft-Windows-PowerShell/Operational
# Logstash filter pipeline - parse and enrich
filter {
if [winlog][channel] == "Security" {
mutate {
add_field => { "log_type" => "windows_security" }
}
}
# GeoIP enrichment
geoip {
source => "source.ip"
target => "source.geo"
}
# Threat intel enrichment
translate {
field => "source.ip"
destination => "threat.indicator"
dictionary_path => "/etc/logstash/threat_intel.yml"
}
}
Key Detection Patterns
These cross-log-source detection patterns are high-value indicators of compromise that should be baselined and alerted on in any SOC environment.
| Pattern | Log Sources | Technique |
|---|---|---|
| Failed logon spike followed by success | Windows Security, Linux auth | Brute force / credential stuffing |
| Logon at unusual time for user | Windows Security, VPN | Account compromise |
| New scheduled task or service | Windows Security (4698, 7045) | Persistence |
| lsass.exe memory access | Sysmon Event ID 10 | Credential dumping |
| PowerShell encoded commands | PowerShell Operational | Obfuscated malware execution |
| Process spawned from Office apps | Sysmon Event ID 1 | Macro-based malware |
| DNS queries with high entropy names | DNS logs, Zeek dns.log | DGA malware / DNS tunneling |
| Internal host connecting to TOR exit nodes | Firewall, Zeek conn.log | C2 over TOR |
| Massive S3 GetObject calls | AWS CloudTrail | Cloud data exfiltration |
| Web requests with SQLi patterns | Web server access logs | SQL injection attack |