ワンクリックで
log-analysis
Security log analysis and anomaly detection for access, auth, and syslog files
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Security log analysis and anomaly detection for access, auth, and syslog files
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Interactive gap analysis against Korea's ISMS-P 102-control certification framework (management, protection, personal information)
Analyze suspicious files through triage/static/dynamic/code phases to produce IOCs, YARA/Sigma rules, and MITRE ATT&CK mappings
File hash reputation lookup via VirusTotal API v3 for MD5/SHA1/SHA256 detection ratio, threat classification, and vendor results
OWASP Top 10 (2021) checklist-based inspection and compliance matrix generation
Multi-chain smart contract security for Solana, Algorand, Cairo, Cosmos, Substrate, and TON with pre-audit readiness checks
Detect timing side-channel vulnerabilities in cryptographic code caused by secret-dependent branching and memory access patterns
| name | log-analysis |
| description | Security log analysis and anomaly detection for access, auth, and syslog files |
| license | MIT |
| metadata | {"category":"incident-response","locale":"en","phase":"v1"} |
Analyzes security log files to detect anomalies. Extracts top IPs, paths, status codes, and User-Agents from web access logs, and detects brute-force patterns (multiple 401s) and scanning behavior (sequential path enumeration). Extracts failed login patterns from auth logs and error/warning patterns from syslog, then outputs a summary report with a timeline.
grep, awk, sort, uniq (available by default on most Linux systems)python3 (advanced analysis and report generation)| Field | Description | Example |
|---|---|---|
LOG_FILE | Path to the log file to analyze | /var/log/nginx/access.log |
LOG_TYPE | Log type: access / auth / syslog | access |
TOP_N | Number of top entries to display (default: 20) | 20 |
LOG_FILE="${SECSKILL_LOG_FILE:-${1:-}}"
LOG_TYPE="${SECSKILL_LOG_TYPE:-${2:-auto}}"
TOP_N="${SECSKILL_TOP_N:-${3:-20}}"
if [ -z "$LOG_FILE" ]; then
read -rp "Enter log file path: " LOG_FILE
fi
if [ ! -f "$LOG_FILE" ]; then
echo "[!] File not found: $LOG_FILE"
exit 1
fi
# Auto-detect log type
if [ "$LOG_TYPE" = "auto" ]; then
filename=$(basename "$LOG_FILE")
case "$filename" in
access*|nginx*|apache*|httpd*) LOG_TYPE="access" ;;
auth*|secure*|sshd*) LOG_TYPE="auth" ;;
syslog*|messages*|system*) LOG_TYPE="syslog" ;;
*) LOG_TYPE="access" ; echo "[*] Could not auto-detect log type, assuming access log." ;;
esac
fi
TOTAL_LINES=$(wc -l < "$LOG_FILE")
FILE_SIZE=$(du -sh "$LOG_FILE" | cut -f1)
echo "[+] Log file: $LOG_FILE"
echo " Type: $LOG_TYPE | Lines: $TOTAL_LINES | Size: $FILE_SIZE"
if [ "$LOG_TYPE" = "access" ]; then
echo ""
echo "=== Web Access Log Analysis ==="
# Top IP addresses
echo "[Top IP addresses] (Top $TOP_N)"
awk '{print $1}' "$LOG_FILE" | sort | uniq -c | sort -rn | head -"$TOP_N" | \
awk '{printf " %6d hits %s\n", $1, $2}'
# Top request paths
echo ""
echo "[Top request paths] (Top $TOP_N)"
awk '{print $7}' "$LOG_FILE" | cut -d'?' -f1 | sort | uniq -c | sort -rn | head -"$TOP_N" | \
awk '{printf " %6d hits %s\n", $1, $2}'
# HTTP status code distribution
echo ""
echo "[HTTP status code distribution]"
awk '{print $9}' "$LOG_FILE" | grep -E '^[0-9]{3}$' | sort | uniq -c | sort -rn | \
awk '{printf " %s: %d hits\n", $2, $1}'
# Top User-Agents
echo ""
echo "[Top User-Agents] (Top 10)"
awk -F'"' '{print $6}' "$LOG_FILE" | sort | uniq -c | sort -rn | head -10 | \
awk '{printf " %5d hits %s\n", $1, substr($0, index($0,$2))}'
fi
if [ "$LOG_TYPE" = "access" ]; then
echo ""
echo "=== Anomaly Detection ==="
python3 - "$LOG_FILE" "$TOP_N" <<'PYEOF'
import sys, re
from collections import defaultdict
log_file = sys.argv[1]
top_n = int(sys.argv[2])
ip_401 = defaultdict(int)
ip_404 = defaultdict(int)
ip_paths = defaultdict(set)
suspicious_ips = set()
# Parse Combined Log Format
log_pattern = re.compile(r'(\S+) \S+ \S+ \[.*?\] "\S+ (\S+) \S+" (\d{3})')
with open(log_file, 'r', errors='replace') as f:
for line in f:
m = log_pattern.match(line)
if not m:
continue
ip, path, status = m.group(1), m.group(2), m.group(3)
if status == '401':
ip_401[ip] += 1
if status == '404':
ip_404[ip] += 1
ip_paths[ip].add(path)
# Brute-force: 10+ 401 errors from the same IP
print("\n[Suspected brute-force IPs] (10+ 401 errors)")
bf_found = False
for ip, count in sorted(ip_401.items(), key=lambda x: -x[1]):
if count >= 10:
print(f" [!] {ip}: {count} authentication failures")
suspicious_ips.add(ip)
bf_found = True
if not bf_found:
print(" [OK] No brute-force pattern detected")
# Scanning: 20+ 404 errors from the same IP (path enumeration)
print("\n[Suspected scanning IPs] (20+ 404 errors)")
scan_found = False
for ip, count in sorted(ip_404.items(), key=lambda x: -x[1]):
if count >= 20:
unique_paths = len(ip_paths[ip])
print(f" [!] {ip}: {count} 404 errors, {unique_paths} unique paths")
suspicious_ips.add(ip)
scan_found = True
if not scan_found:
print(" [OK] No scanning pattern detected")
if suspicious_ips:
print(f"\n[Summary] {len(suspicious_ips)} suspicious IP(s) found: {', '.join(suspicious_ips)}")
# Suggest block commands
print("\n[Example block commands (review before executing)]")
for ip in list(suspicious_ips)[:5]:
print(f" # iptables -A INPUT -s {ip} -j DROP")
PYEOF
fi
if [ "$LOG_TYPE" = "auth" ]; then
echo ""
echo "=== Auth Log Analysis ==="
# Failed SSH logins
echo "[Top IPs with failed SSH logins] (Top $TOP_N)"
grep -i "failed password\|invalid user\|authentication failure" "$LOG_FILE" | \
grep -oE 'from [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | \
awk '{print $2}' | sort | uniq -c | sort -rn | head -"$TOP_N" | \
awk '{printf " %6d hits %s\n", $1, $2}'
echo ""
echo "[Targeted user accounts] (Top $TOP_N)"
grep -i "invalid user\|failed password for" "$LOG_FILE" | \
grep -oE 'for [a-zA-Z0-9._-]+' | awk '{print $2}' | \
sort | uniq -c | sort -rn | head -"$TOP_N" | \
awk '{printf " %6d hits %s\n", $1, $2}'
echo ""
echo "[Successful logins]"
grep -i "accepted password\|accepted publickey" "$LOG_FILE" | \
grep -oE 'for [a-zA-Z0-9._-]+ from [0-9.]+' | \
sort | uniq -c | sort -rn | head -"$TOP_N" | \
awk '{printf " %4d hits %s\n", $1, substr($0, index($0,$2))}'
FAIL_COUNT=$(grep -ci "failed password\|invalid user" "$LOG_FILE" 2>/dev/null || echo 0)
echo ""
echo "[Summary] Total authentication failures: $FAIL_COUNT"
fi
if [ "$LOG_TYPE" = "syslog" ]; then
echo ""
echo "=== Syslog Analysis ==="
echo "[Error/warning patterns (Top $TOP_N)]"
grep -iE "error|warning|critical|alert|emerg|fail" "$LOG_FILE" | \
awk '{for(i=1;i<=NF;i++) if($i ~ /[Ee]rror|[Ww]arning|[Cc]ritical/) {key=$i; break}; print key}' | \
sort | uniq -c | sort -rn | head -"$TOP_N" | \
awk '{printf " %6d hits %s\n", $1, $2}'
echo ""
echo "[Error frequency by process] (Top $TOP_N)"
grep -iE "error|critical|emerg" "$LOG_FILE" | \
awk '{print $5}' | sed 's/\[.*\]//' | sed 's/://' | \
sort | uniq -c | sort -rn | head -"$TOP_N" | \
awk '{printf " %6d hits %s\n", $1, $2}'
fi
python3 - "$LOG_FILE" "$LOG_TYPE" <<'PYEOF'
import sys, re
from collections import defaultdict
log_file = sys.argv[1]
log_type = sys.argv[2]
print("\n" + "=" * 60)
print("Timeline Summary")
print("=" * 60)
# Request count by hour
hourly = defaultdict(int)
if log_type == "access":
time_pattern = re.compile(r'\[(\d{2}/\w+/\d{4}):(\d{2})')
elif log_type in ("auth", "syslog"):
time_pattern = re.compile(r'(\w+ \d+ (\d{2}):\d{2}:\d{2})')
with open(log_file, 'r', errors='replace') as f:
for line in f:
m = time_pattern.search(line)
if m:
if log_type == "access":
hour = m.group(2)
date = m.group(1).split(':')[0]
hourly[f"{date} {hour}:00"] += 1
else:
hour = m.group(2)
hourly[f"{hour}:00"] += 1
print("\n[Requests/events per hour]")
peak = max(hourly.values()) if hourly else 1
for time_key in sorted(hourly.keys())[-24:]:
count = hourly[time_key]
bar = '#' * int(count / peak * 30)
print(f" {time_key} {bar:<30} {count}")
print("\n[+] Analysis complete")
PYEOF
| Problem | Cause | Solution |
|---|---|---|
| Permission denied | No read access to log file | Use sudo or check permissions |
| Empty analysis output | Log format mismatch | Verify log format and adjust awk field numbers |
| python3 not installed | Missing Python | sudo apt install python3 |
| Slow on large files | Log file > 1 GB | Extract recent entries with tail -n 100000 |
zcat *.gz | python3 ....ioc-extract skill before correlating with malware-hash.awk field numbers accordingly.