mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-28 15:10:58 +03:00
Add folder anatomy (scripts/agent.py + references/api-reference.md) for 648 cybersecurity skills
Complete skill folder anatomy across all cybersecurity skills: - scripts/agent.py: 80-150 line Python agents using real libraries (impacket, boto3, azure-mgmt-*, kubernetes, pefile, yara, scapy, shodan, stix2, etc.) - references/api-reference.md: real API documentation with method signatures - LICENSE: MIT license for all skill folders
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Anthropic Agent Skills Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,47 @@
|
||||
# API Reference: Lateral Movement Detection
|
||||
|
||||
## Windows Event Log IDs
|
||||
|
||||
| Event ID | Source | Description |
|
||||
|----------|--------|-------------|
|
||||
| 4624 | Security | Successful logon (Logon_Type 3=network, 10=RDP) |
|
||||
| 4625 | Security | Failed logon attempt |
|
||||
| 4648 | Security | Explicit credential logon (runas) |
|
||||
| 4672 | Security | Special privileges assigned (admin logon) |
|
||||
| 4769 | Security | Kerberos TGS request (Pass-the-Ticket) |
|
||||
| 5140 | Security | Network share access (C$, ADMIN$, IPC$) |
|
||||
| 7045 | System | New service installed (PsExec) |
|
||||
|
||||
## Sysmon Event Codes
|
||||
|
||||
| Event Code | Description |
|
||||
|------------|-------------|
|
||||
| 1 | Process creation with command line |
|
||||
| 3 | Network connection |
|
||||
| 10 | Process access (LSASS credential dumping) |
|
||||
| 17/18 | Named pipe created/connected (PsExec) |
|
||||
|
||||
## MITRE ATT&CK Techniques (TA0008)
|
||||
|
||||
| Technique | ID | Detection Signal |
|
||||
|-----------|----|-----------------|
|
||||
| Pass-the-Hash | T1550.002 | NTLM Type 3 logon to multiple hosts |
|
||||
| PsExec | T1021.002 | PSEXESVC service creation + named pipe |
|
||||
| WMI Execution | T1047 | WmiPrvSE spawning cmd/powershell |
|
||||
| RDP | T1021.001 | Logon_Type 10 to multiple targets |
|
||||
| SMB Admin Share | T1021.002 | EventCode 5140 on C$/ADMIN$ |
|
||||
|
||||
## Python Libraries
|
||||
|
||||
| Library | Version | Purpose |
|
||||
|---------|---------|---------|
|
||||
| `csv` | stdlib | Parse exported Windows event logs |
|
||||
| `json` | stdlib | Report output generation |
|
||||
| `collections` | stdlib | Event aggregation and counting |
|
||||
|
||||
## References
|
||||
|
||||
- MITRE ATT&CK Lateral Movement: https://attack.mitre.org/tactics/TA0008/
|
||||
- Splunk Security Essentials: https://splunkbase.splunk.com/app/3435
|
||||
- Sigma rules (lateral movement): https://github.com/SigmaHQ/sigma
|
||||
- Microsoft Defender for Identity: https://learn.microsoft.com/en-us/defender-for-identity/
|
||||
@@ -0,0 +1,221 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Agent for performing lateral movement detection.
|
||||
|
||||
Analyzes Windows event logs and network flow data to detect
|
||||
Pass-the-Hash, PsExec, WMI, RDP, and SMB-based lateral movement
|
||||
mapped to MITRE ATT&CK TA0008 techniques.
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import csv
|
||||
import re
|
||||
from collections import defaultdict
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class LateralMovementDetector:
|
||||
"""Detects lateral movement patterns from log data."""
|
||||
|
||||
def __init__(self, output_dir):
|
||||
self.output_dir = Path(output_dir)
|
||||
self.output_dir.mkdir(parents=True, exist_ok=True)
|
||||
self.auth_events = []
|
||||
self.process_events = []
|
||||
self.network_flows = []
|
||||
|
||||
def load_auth_events(self, csv_path):
|
||||
"""Load Windows authentication events (4624, 4625, 4648, 4672)."""
|
||||
with open(csv_path, "r") as f:
|
||||
for row in csv.DictReader(f):
|
||||
self.auth_events.append(row)
|
||||
|
||||
def load_process_events(self, csv_path):
|
||||
"""Load Sysmon process creation events (EventCode 1)."""
|
||||
with open(csv_path, "r") as f:
|
||||
for row in csv.DictReader(f):
|
||||
self.process_events.append(row)
|
||||
|
||||
def load_network_flows(self, csv_path):
|
||||
"""Load network flow data (NetFlow/Zeek)."""
|
||||
with open(csv_path, "r") as f:
|
||||
for row in csv.DictReader(f):
|
||||
self.network_flows.append(row)
|
||||
|
||||
def detect_pass_the_hash(self):
|
||||
"""Detect Pass-the-Hash via NTLM Type 3 logons to multiple hosts."""
|
||||
ntlm_logons = defaultdict(lambda: {"targets": set(), "count": 0, "events": []})
|
||||
|
||||
for event in self.auth_events:
|
||||
if (event.get("EventCode") == "4624" and
|
||||
event.get("Logon_Type") == "3" and
|
||||
event.get("AuthenticationPackageName", "").upper() == "NTLM"):
|
||||
user = event.get("TargetUserName", "")
|
||||
src = event.get("src_ip", event.get("IpAddress", ""))
|
||||
target = event.get("ComputerName", "")
|
||||
if user and not user.endswith("$") and user != "ANONYMOUS LOGON":
|
||||
key = f"{src}|{user}"
|
||||
ntlm_logons[key]["targets"].add(target)
|
||||
ntlm_logons[key]["count"] += 1
|
||||
ntlm_logons[key]["events"].append(event)
|
||||
|
||||
findings = []
|
||||
for key, data in ntlm_logons.items():
|
||||
if len(data["targets"]) > 3:
|
||||
src_ip, user = key.split("|", 1)
|
||||
findings.append({
|
||||
"technique": "T1550.002",
|
||||
"name": "Pass-the-Hash",
|
||||
"src_ip": src_ip,
|
||||
"user": user,
|
||||
"unique_targets": len(data["targets"]),
|
||||
"total_logons": data["count"],
|
||||
"targets": sorted(data["targets"]),
|
||||
})
|
||||
return findings
|
||||
|
||||
def detect_psexec(self):
|
||||
"""Detect PsExec execution via process creation and service events."""
|
||||
findings = []
|
||||
for event in self.process_events:
|
||||
image = event.get("Image", "").lower()
|
||||
parent = event.get("ParentImage", "").lower()
|
||||
if "psexec" in image or "psexesvc" in image or "psexesvc" in parent:
|
||||
findings.append({
|
||||
"technique": "T1021.002",
|
||||
"name": "PsExec Execution",
|
||||
"computer": event.get("Computer", ""),
|
||||
"user": event.get("User", ""),
|
||||
"image": event.get("Image", ""),
|
||||
"parent": event.get("ParentImage", ""),
|
||||
"cmdline": event.get("CommandLine", ""),
|
||||
"timestamp": event.get("timestamp", event.get("UtcTime", "")),
|
||||
})
|
||||
return findings
|
||||
|
||||
def detect_wmi_execution(self):
|
||||
"""Detect WMI remote execution via WmiPrvSE child processes."""
|
||||
findings = []
|
||||
for event in self.process_events:
|
||||
parent = event.get("ParentImage", "").lower()
|
||||
image = event.get("Image", "").lower()
|
||||
if "wmiprvse" in parent and ("cmd.exe" in image or "powershell" in image):
|
||||
findings.append({
|
||||
"technique": "T1047",
|
||||
"name": "WMI Remote Execution",
|
||||
"computer": event.get("Computer", ""),
|
||||
"user": event.get("User", ""),
|
||||
"image": event.get("Image", ""),
|
||||
"cmdline": event.get("CommandLine", ""),
|
||||
"timestamp": event.get("timestamp", ""),
|
||||
})
|
||||
return findings
|
||||
|
||||
def detect_rdp_lateral(self):
|
||||
"""Detect RDP lateral movement via Logon_Type 10."""
|
||||
rdp_sessions = defaultdict(lambda: {"targets": set(), "count": 0})
|
||||
for event in self.auth_events:
|
||||
if event.get("EventCode") == "4624" and event.get("Logon_Type") == "10":
|
||||
src = event.get("src_ip", event.get("IpAddress", ""))
|
||||
user = event.get("TargetUserName", "")
|
||||
target = event.get("ComputerName", "")
|
||||
key = f"{src}|{user}"
|
||||
rdp_sessions[key]["targets"].add(target)
|
||||
rdp_sessions[key]["count"] += 1
|
||||
|
||||
findings = []
|
||||
for key, data in rdp_sessions.items():
|
||||
if len(data["targets"]) > 2:
|
||||
src_ip, user = key.split("|", 1)
|
||||
findings.append({
|
||||
"technique": "T1021.001",
|
||||
"name": "RDP Lateral Movement",
|
||||
"src_ip": src_ip,
|
||||
"user": user,
|
||||
"unique_targets": len(data["targets"]),
|
||||
"targets": sorted(data["targets"]),
|
||||
})
|
||||
return findings
|
||||
|
||||
def detect_smb_scanning(self):
|
||||
"""Detect mass SMB connections indicating lateral movement."""
|
||||
smb_sources = defaultdict(lambda: {"targets": set(), "bytes": 0})
|
||||
for flow in self.network_flows:
|
||||
if flow.get("dest_port") == "445":
|
||||
src = flow.get("src_ip", "")
|
||||
dst = flow.get("dest_ip", "")
|
||||
smb_sources[src]["targets"].add(dst)
|
||||
smb_sources[src]["bytes"] += int(flow.get("bytes", 0))
|
||||
|
||||
findings = []
|
||||
for src, data in smb_sources.items():
|
||||
if len(data["targets"]) > 10:
|
||||
findings.append({
|
||||
"technique": "T1021.002",
|
||||
"name": "SMB Mass Connection",
|
||||
"src_ip": src,
|
||||
"unique_targets": len(data["targets"]),
|
||||
"total_bytes": data["bytes"],
|
||||
"severity": "CRITICAL" if len(data["targets"]) > 50 else "HIGH",
|
||||
})
|
||||
return findings
|
||||
|
||||
def build_movement_graph(self):
|
||||
"""Build a source->destination graph of lateral movement."""
|
||||
edges = defaultdict(int)
|
||||
for event in self.auth_events:
|
||||
if event.get("EventCode") == "4624" and event.get("Logon_Type") in ("3", "10"):
|
||||
src = event.get("src_ip", event.get("IpAddress", ""))
|
||||
dst = event.get("ComputerName", "")
|
||||
user = event.get("TargetUserName", "")
|
||||
if src and dst:
|
||||
edges[f"{src} -> {dst} ({user})"] += 1
|
||||
return dict(sorted(edges.items(), key=lambda x: x[1], reverse=True)[:50])
|
||||
|
||||
def generate_report(self):
|
||||
"""Run all detections and generate a comprehensive report."""
|
||||
report = {
|
||||
"report_date": datetime.utcnow().isoformat(),
|
||||
"detections": {
|
||||
"pass_the_hash": self.detect_pass_the_hash(),
|
||||
"psexec": self.detect_psexec(),
|
||||
"wmi_execution": self.detect_wmi_execution(),
|
||||
"rdp_lateral": self.detect_rdp_lateral(),
|
||||
"smb_scanning": self.detect_smb_scanning(),
|
||||
},
|
||||
"movement_graph": self.build_movement_graph(),
|
||||
}
|
||||
|
||||
total_findings = sum(len(v) for v in report["detections"].values())
|
||||
report["summary"] = {
|
||||
"total_findings": total_findings,
|
||||
"techniques_detected": [k for k, v in report["detections"].items() if v],
|
||||
}
|
||||
|
||||
report_path = self.output_dir / "lateral_movement_report.json"
|
||||
with open(report_path, "w") as f:
|
||||
json.dump(report, f, indent=2, default=list)
|
||||
print(json.dumps(report, indent=2, default=list))
|
||||
return report
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 3:
|
||||
print("Usage: agent.py <auth_events_csv> <output_dir> [process_csv] [flows_csv]")
|
||||
sys.exit(1)
|
||||
|
||||
auth_csv = sys.argv[1]
|
||||
output_dir = sys.argv[2]
|
||||
|
||||
detector = LateralMovementDetector(output_dir)
|
||||
detector.load_auth_events(auth_csv)
|
||||
if len(sys.argv) > 3:
|
||||
detector.load_process_events(sys.argv[3])
|
||||
if len(sys.argv) > 4:
|
||||
detector.load_network_flows(sys.argv[4])
|
||||
detector.generate_report()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user