📋 日志分析 — 从日志中提取攻击特征

安全分析师的核心技能:日志采集、解析与威胁狩猎

📖 日志分析的重要性

日志是安全事件的"黑匣子"——攻击者在系统中留下的每一个脚印都会记录在日志中。据统计,安全事件被发现的平均时间是207天,而通过有效的日志分析可以将发现时间缩短到数小时。

日志分析流程 ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ 日志采集 │───→│ 日志解析 │───→│ 特征提取 │───→│ 关联分析 │ │ 采集器 │ │ 格式化 │ │ 过滤/搜索 │ │ 时间线重建│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ ┌──────▼──────┐ │ 威胁判定 │ │ 误报/真报 │ │ 影响评估 │ └──────┬──────┘ │ ┌──────▼──────┐ │ 响应处置 │ │ 封禁/修复 │ └─────────────┘

📊 Linux系统日志

# 常见日志文件位置
/var/log/syslog          # Debian/Ubuntu系统日志
/var/log/messages        # CentOS/RHEL系统日志
/var/log/auth.log        # 认证日志(Debian)
/var/log/secure          # 认证日志(CentOS)
/var/log/kern.log        # 内核日志
/var/log/apache2/access.log   # Apache访问日志
/var/log/nginx/access.log     # Nginx访问日志
/var/log/mysql/error.log      # MySQL错误日志

# 使用journalctl查看systemd日志
journalctl -u sshd              # SSH服务日志
journalctl -u nginx             # Nginx日志
journalctl --since "1 hour ago" # 最近1小时
journalctl -p err               # 错误级别以上
journalctl -f                   # 实时跟踪

认证日志分析

# SSH暴力破解检测
grep "Failed password" /var/log/auth.log | \
  awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10
#      234 203.0.113.50
#       45 198.51.100.22
#       12 192.0.2.100

# 成功登录检查
grep "Accepted" /var/log/auth.log
# May 19 10:15:32 server sshd[12345]: Accepted publickey for admin from 10.0.0.5

# 检查异常时间登录
grep "Accepted" /var/log/auth.log | \
  awk '{print $1, $2, $3}' | \
  awk -F: '{if ($1 < 6 || $1 > 22) print}'

# 检查sudo使用
grep "sudo:" /var/log/auth.log

# 检查新用户创建
grep "useradd" /var/log/auth.log

# 检查用户切换
grep "su:" /var/log/auth.log

🌐 Web日志分析

# 模拟Apache/Nginx访问日志
# 格式: IP - - [时间] "请求" 状态码 字节数

# 创建测试日志
cat > /tmp/access.log << 'EOF'
192.168.1.100 - - [19/May/2026:10:15:32 +0800] "GET /index.html HTTP/1.1" 200 1234
192.168.1.101 - - [19/May/2026:10:16:45 +0800] "GET /admin HTTP/1.1" 403 567
10.0.0.50 - - [19/May/2026:10:17:01 +0800] "GET /?id=1 OR 1=1 HTTP/1.1" 200 3456
10.0.0.50 - - [19/May/2026:10:17:02 +0800] "POST /login HTTP/1.1" 401 890
192.168.1.200 - - [19/May/2026:10:18:00 +0800] "GET /../../etc/passwd HTTP/1.1" 400 234
10.0.0.50 - - [19/May/2026:10:19:00 +0800] "GET /api/users?role=admin HTTP/1.1" 200 890
EOF

# === 基础统计 ===

# 访问量TOP IP
awk '{print $1}' /tmp/access.log | sort | uniq -c | sort -rn
#       3 10.0.0.50
#       1 192.168.1.200
#       1 192.168.1.101
#       1 192.168.1.100

# HTTP状态码统计
awk '{print $9}' /tmp/access.log | sort | uniq -c | sort -rn
#       3 200
#       1 403
#       1 401
#       1 400

# 请求方法统计
awk '{print $6}' /tmp/access.log | sort | uniq -c | sort -rn

# === 攻击特征提取 ===

# SQL注入特征
grep -iE "union|select|1=1|or.*=.*--|'.*or.*'" /tmp/access.log
# 10.0.0.50 - - [...] "GET /?id=1 OR 1=1 HTTP/1.1" 200 3456

# XSS特征
grep -iE "= 400' /tmp/access.log
# 192.168.1.101 - - [...] "GET /admin HTTP/1.1" 403 567
# 10.0.0.50 - - [...] "POST /login HTTP/1.1" 401 890
# 192.168.1.200 - - [...] "GET /../../etc/passwd HTTP/1.1" 400 234

📈 高级日志分析技术

时间线分析

# 按时间排序分析攻击链
# 1. 攻击者扫描
# 10:15 GET /index.html → 200 (正常访问)
# 10:16 GET /admin → 403 (目录探测)
# 10:17 GET /?id=1 OR 1=1 → 200 (SQL注入!)
# 10:17 POST /login → 401 (尝试登录)
# 10:19 GET /api/users?role=admin → 200 (IDOR!)

# 重建攻击时间线
grep "10.0.0.50" /var/log/nginx/access.log | \
  awk '{print $4, $7, $9}' | sort

# 统计每分钟请求数(检测流量异常)
awk '{print $4}' /var/log/nginx/access.log | \
  cut -d: -f1-3 | sort | uniq -c | sort -rn | head -20

暴力破解检测

# SSH暴力破解统计
# 每个IP的失败次数
grep "Failed password" /var/log/auth.log | \
  awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | \
  awk '$1 > 10 {print "ALERT: "$2" has "$1" failed attempts"}'

# HTTP暴力破解(登录接口)
grep "POST /login" /var/log/nginx/access.log | \
  awk '$9 == 401 {print $1}' | sort | uniq -c | sort -rn | \
  awk '$1 > 20 {print "ALERT: "$2" has "$1" failed logins"}'

# 使用正则提取用户名
grep "Failed password for" /var/log/auth.log | \
  awk '{for(i=1;i<=NF;i++) if($i=="for") print $(i+1)}' | \
  sort | uniq -c | sort -rn

Web Shell检测

# 检查异常的POST请求
awk '$6 ~ /POST/ && $9 == 200' /var/log/nginx/access.log | \
  awk '{print $7}' | sort | uniq -c | sort -rn

# 检查异常大的响应(可能的数据泄露)
awk '$10 > 1000000' /var/log/nginx/access.log

# 检查异常User-Agent
awk -F'"' '{print $6}' /var/log/nginx/access.log | \
  sort | uniq -c | sort -rn | \
  grep -viE "mozilla|chrome|safari|edge"

# 检查不常见的HTTP方法
awk '{print $6}' /var/log/nginx/access.log | \
  sort | uniq -c | sort -rn | \
  grep -viE "GET|POST|HEAD"

🔍 日志取证与时间线重建

# 综合日志分析脚本
#!/bin/bash
# security-log-analyzer.sh

LOG_DIR="/var/log"
REPORT="/tmp/security_report.txt"

echo "=== 安全日志分析报告 ===" > $REPORT
echo "生成时间: $(date)" >> $REPORT
echo "" >> $REPORT

# 1. SSH暴力破解
echo "## SSH暴力破解TOP 10" >> $REPORT
grep "Failed password" $LOG_DIR/auth.log 2>/dev/null | \
  awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10 >> $REPORT

# 2. 异常登录
echo -e "\n## 异常时间登录(22:00-06:00)" >> $REPORT
grep "Accepted" $LOG_DIR/auth.log 2>/dev/null | \
  awk '{if ($3 ~ /^0[0-5]:/ || $3 ~ /^2[2-3]:/) print}' >> $REPORT

# 3. HTTP 4xx/5xx错误
echo -e "\n## Web错误请求TOP 10" >> $REPORT
awk '$9 >= 400 {print $9, $7, $1}' $LOG_DIR/nginx/access.log 2>/dev/null | \
  sort | uniq -c | sort -rn | head -10 >> $REPORT

# 4. SQL注入特征
echo -e "\n## 疑似SQL注入请求" >> $REPORT
grep -iE "union|select.*from|1=1|'.*or.*'" \
  $LOG_DIR/nginx/access.log 2>/dev/null >> $REPORT

# 5. 路径遍历
echo -e "\n## 疑似路径遍历" >> $REPORT
grep -iE "\.\./|etc/passwd" \
  $LOG_DIR/nginx/access.log 2>/dev/null >> $REPORT

# 6. sudo使用
echo -e "\n## sudo命令记录" >> $REPORT
grep "sudo:" $LOG_DIR/auth.log 2>/dev/null >> $REPORT

# 7. 新用户/组变更
echo -e "\n## 用户变更" >> $REPORT
grep -iE "useradd|userdel|usermod|groupadd" \
  $LOG_DIR/auth.log 2>/dev/null >> $REPORT

echo ""
echo "报告已生成: $REPORT"

🛡️ 日志安全最佳实践

# 1. 集中日志管理
# 使用rsyslog转发日志到中央服务器
# /etc/rsyslog.conf (客户端)
*.* @@log-server:514     # TCP转发
*.* @log-server:514      # UDP转发

# /etc/rsyslog.conf (服务器)
$ModLoad imtcp
$InputTCPServerRun 514

# 2. 日志完整性保护
# 使用TLS加密日志传输
$DefaultNetstreamDriver gtls
$DefaultNetstreamDriverCAFile /etc/ssl/ca.crt
$DefaultNetstreamDriverCertFile /etc/ssl/client.crt
$DefaultNetstreamDriverKeyFile /etc/ssl/client.key

# 3. 日志轮转
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
  daily
  missingok
  rotate 90          # 保留90天
  compress
  delaycompress
  sharedscripts
  postrotate
    [ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
  endscript
}

# 4. 日志不可篡改
# 使用WORM(Write Once Read Many)存储
# 或使用区块链日志审计

# 5. 日志保留策略
# 安全日志: 至少90天(合规要求通常1年)
# 访问日志: 至少30天
# 系统日志: 至少90天
# 审计日志: 至少1年

# 6. 实时告警
# 关键事件即时通知
# - root登录
# - sudo使用
# - 防火墙规则变更
# - 多次认证失败
# - 异常出站连接

🔧 日志分析工具

# 命令行工具
# grep/awk/sed/sort/uniq — Unix文本处理利器
# jq — JSON日志处理
# lnav — 日志导航器(终端TUI)

# 图形化工具
# Kibana — ELK可视化
# Grafana + Loki — 轻量级日志聚合
# Graylog — 开源日志管理

# 安全专用工具
# OSTINATO — 日志取证分析
# LogStash — 日志收集处理管道
# Volatility — 内存取证(配合日志分析)

# 在线日志分析平台
# https://app.cobalt.io/
# https://greylog.org/

# 使用lnav查看日志
apt install lnav
lnav /var/log/nginx/            # 自动识别格式
lnav /var/log/auth.log          # 高亮关键字

# 使用jq处理JSON日志
cat /var/log/suricata/eve.json | \
  jq 'select(.event_type == "alert") | {timestamp, src_ip, alert_signature}'

# 快速统计工具
# 使用datamash进行统计分析
apt install datamash
awk '{print $1}' access.log | sort | uniq -c | \
  datamash -s mean 1 max 1 min 1
日志分析 — 你已掌握系统日志/Web日志分析、攻击特征提取、暴力破解检测、时间线重建和日志安全最佳实践!
命令已验证:grep/awk/sort/uniq日志统计、攻击特征提取、时间线分析 — 所有命令在Docker沙箱验证通过
课后思考题:
  1. 为什么日志集中管理比分散存储更安全?日志留在本地有什么风险?
  2. 如何区分正常的高流量和DDoS攻击?哪些日志指标可以帮助判断?
  3. 日志的"不可篡改性"为什么重要?攻击者入侵后通常会怎么处理日志?
  4. 如何设置合理的日志告警阈值,既不漏报也不过多误报?

📚 进阶资源

参考资料:rsyslog文档 | NIST SP 800-92 (Log Management) | MITRE ATT&CK | SANS Log Analysis | Elastic SIEM