mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-12 14:14:56 +03:00
c47eed6a64
- Fix 25 shell=True subprocess calls with list-based commands - Fix 49 verify=False in defensive skills (env-var override) - Add timeout to 231 HTTP/subprocess/socket calls - Fix 6 SQL injection patterns with whitelist validation - Replace 8 __import__() with standard imports - Remove 701 unused imports across 442 files - Add authorized-testing disclaimers to all offensive skills - Complete 11 incomplete skill directories - Expand 10 stub SKILL.md files with full content - Fix 2 YAML parse errors in frontmatter - Fix 5 pre-existing syntax errors - Convert 22 hardcoded paths/ports to environment variables - Back up 21 redundant skill pairs to .bak - Fix 2 global declaration errors - 724/724 skills with full folder anatomy (SKILL.md + agent.py + api-reference.md + LICENSE) - 0 compile errors across all 724 agent.py files
143 lines
4.9 KiB
Python
143 lines
4.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Lateral movement detection agent using Splunk SPL query generation.
|
|
|
|
Generates and analyzes SPL queries for detecting lateral movement techniques
|
|
including pass-the-hash, RDP pivoting, WMI/PSExec execution, and SMB abuse.
|
|
"""
|
|
|
|
import argparse
|
|
import json
|
|
from datetime import datetime
|
|
|
|
LATERAL_MOVEMENT_QUERIES = {
|
|
"pass_the_hash": {
|
|
"mitre": "T1550.002",
|
|
"severity": "CRITICAL",
|
|
"spl": """index=wineventlog EventCode=4624 Logon_Type=3
|
|
| where Authentication_Package="NTLM" AND Logon_Process="NtLmSsp"
|
|
| where NOT match(Source_Network_Address, "^(127\\.0\\.0\\.1|::1|-)")
|
|
| stats count dc(Computer) as target_count values(Computer) as targets by Source_Network_Address Account_Name
|
|
| where target_count > 3
|
|
| sort -target_count"""
|
|
},
|
|
"psexec_execution": {
|
|
"mitre": "T1569.002",
|
|
"severity": "HIGH",
|
|
"spl": """index=sysmon EventCode=1
|
|
| where (ParentImage="*\\services.exe" AND Image="*\\PSEXESVC.exe")
|
|
OR (Image="*\\psexec.exe" OR Image="*\\psexec64.exe")
|
|
| stats count by Image, ParentImage, CommandLine, Computer, User
|
|
| sort -count"""
|
|
},
|
|
"wmi_remote_execution": {
|
|
"mitre": "T1047",
|
|
"severity": "HIGH",
|
|
"spl": """index=sysmon EventCode=1
|
|
| where (Image="*\\wmiprvse.exe" AND ParentImage="*\\svchost.exe")
|
|
| where CommandLine!=""
|
|
| stats count by CommandLine, Computer, User
|
|
| sort -count"""
|
|
},
|
|
"rdp_pivoting": {
|
|
"mitre": "T1021.001",
|
|
"severity": "MEDIUM",
|
|
"spl": """index=wineventlog EventCode=4624 Logon_Type=10
|
|
| stats count dc(Computer) as rdp_targets values(Computer) as targets by Source_Network_Address Account_Name
|
|
| where rdp_targets > 3
|
|
| sort -rdp_targets"""
|
|
},
|
|
"smb_lateral": {
|
|
"mitre": "T1021.002",
|
|
"severity": "HIGH",
|
|
"spl": """index=network dest_port=445
|
|
| stats count dc(dest_ip) as smb_targets values(dest_ip) as targets by src_ip
|
|
| where smb_targets > 5
|
|
| sort -smb_targets"""
|
|
},
|
|
"winrm_execution": {
|
|
"mitre": "T1021.006",
|
|
"severity": "HIGH",
|
|
"spl": """index=sysmon EventCode=1
|
|
| where Image="*\\wsmprovhost.exe" OR (ParentImage="*\\winrshost.exe")
|
|
| stats count by Image, CommandLine, Computer, User
|
|
| sort -count"""
|
|
},
|
|
"service_creation": {
|
|
"mitre": "T1543.003",
|
|
"severity": "HIGH",
|
|
"spl": """index=wineventlog EventCode=7045
|
|
| where Service_Type="user mode service"
|
|
| stats count by Service_Name, Service_File_Name, Computer
|
|
| where match(Service_File_Name, "(cmd|powershell|\\\\\\\\|%COMSPEC%)")
|
|
| sort -count"""
|
|
},
|
|
"scheduled_task_remote": {
|
|
"mitre": "T1053.005",
|
|
"severity": "HIGH",
|
|
"spl": """index=sysmon EventCode=1 Image="*\\schtasks.exe"
|
|
| where match(CommandLine, "/create.*/s\\s")
|
|
| stats count by CommandLine, Computer, User
|
|
| sort -count"""
|
|
},
|
|
}
|
|
|
|
|
|
def generate_queries(techniques=None):
|
|
if techniques:
|
|
selected = {k: v for k, v in LATERAL_MOVEMENT_QUERIES.items() if k in techniques}
|
|
else:
|
|
selected = LATERAL_MOVEMENT_QUERIES
|
|
|
|
return [{"technique": name, **details} for name, details in selected.items()]
|
|
|
|
|
|
def parse_splunk_results(filepath):
|
|
findings = []
|
|
with open(filepath, "r") as f:
|
|
try:
|
|
data = json.load(f)
|
|
results = data.get("results", data if isinstance(data, list) else [data])
|
|
except json.JSONDecodeError:
|
|
f.seek(0)
|
|
import csv
|
|
reader = csv.DictReader(f)
|
|
results = list(reader)
|
|
|
|
for row in results:
|
|
target_count = int(row.get("target_count", row.get("dc(Computer)", 0)))
|
|
if target_count >= 3:
|
|
findings.append({
|
|
"source": row.get("Source_Network_Address", row.get("src_ip", "")),
|
|
"user": row.get("Account_Name", row.get("User", "")),
|
|
"target_count": target_count,
|
|
"targets": row.get("targets", row.get("Computer", "")),
|
|
"severity": "CRITICAL" if target_count >= 10 else "HIGH",
|
|
})
|
|
return findings
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Lateral Movement Detector (Splunk SPL)")
|
|
parser.add_argument("--generate-queries", action="store_true", help="Generate SPL queries")
|
|
parser.add_argument("--techniques", nargs="+", choices=list(LATERAL_MOVEMENT_QUERIES.keys()),
|
|
help="Specific techniques to query")
|
|
parser.add_argument("--parse-results", help="Parse Splunk JSON/CSV results file")
|
|
args = parser.parse_args()
|
|
|
|
results = {"timestamp": datetime.utcnow().isoformat() + "Z"}
|
|
|
|
if args.generate_queries:
|
|
results["queries"] = generate_queries(args.techniques)
|
|
results["total_queries"] = len(results["queries"])
|
|
|
|
if args.parse_results:
|
|
findings = parse_splunk_results(args.parse_results)
|
|
results["findings"] = findings
|
|
results["total_findings"] = len(findings)
|
|
|
|
print(json.dumps(results, indent=2))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|