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:
mukul975
2026-03-10 21:02:12 +01:00
parent c74d52fa30
commit 27c6414ca5
1390 changed files with 106806 additions and 0 deletions
+21
View File
@@ -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,63 @@
# API Reference: Triaging Security Incidents
## requests Library (Threat Intel APIs)
### VirusTotal API v3
```python
headers = {"x-apikey": "<API_KEY>"}
# IP lookup
requests.get(f"https://www.virustotal.com/api/v3/ip_addresses/{ip}", headers=headers)
# File hash lookup
requests.get(f"https://www.virustotal.com/api/v3/files/{sha256}", headers=headers)
# Domain lookup
requests.get(f"https://www.virustotal.com/api/v3/domains/{domain}", headers=headers)
```
### Response Fields
| Field | Description |
|-------|-------------|
| `last_analysis_stats.malicious` | Vendors detecting as malicious |
| `last_analysis_stats.undetected` | Vendors with no detection |
| `meaningful_name` | File name (for hash lookups) |
| `reputation` | Community reputation score |
## NIST SP 800-61r3 Incident Categories
| Category | Examples |
|----------|----------|
| Unauthorized Access | Credential compromise, privilege escalation |
| Denial of Service | DDoS, resource exhaustion |
| Malicious Code | Malware, ransomware, cryptominer |
| Improper Usage | Policy violation, insider threat |
| Reconnaissance | Port scan, directory enumeration |
| Web Application Attack | SQLi, XSS, SSRF |
## Severity Matrix
| Priority | Label | ACK SLA | Containment SLA |
|----------|-------|---------|-----------------|
| P1 | Critical | 15 min | 1 hour |
| P2 | High | 30 min | 4 hours |
| P3 | Medium | 2 hours | 24 hours |
| P4 | Low | 8 hours | 72 hours |
## SANS PICERL Framework
1. **Preparation** - Tools, playbooks, team readiness
2. **Identification** - Detection and triage (this skill)
3. **Containment** - Isolate affected systems
4. **Eradication** - Remove threat from environment
5. **Recovery** - Restore systems to normal operation
6. **Lessons Learned** - Post-incident review
## MITRE ATT&CK Mapping
| Technique | ID | Common Alert |
|-----------|----|--------------|
| Brute Force | T1110 | Multiple failed logins |
| PowerShell | T1059.001 | Encoded PS execution |
| Valid Accounts | T1078 | Anomalous authentication |
| Phishing | T1566 | Malicious email attachment |
| Exploit Public App | T1190 | Web attack detected |
## References
- NIST SP 800-61r3: https://csrc.nist.gov/pubs/sp/800/61/r3/final
- SANS Incident Response: https://www.sans.org/white-papers/33901/
- VirusTotal API: https://docs.virustotal.com/reference/overview
- MITRE ATT&CK: https://attack.mitre.org/
@@ -0,0 +1,264 @@
#!/usr/bin/env python3
"""Agent for triaging security incidents using NIST SP 800-61 and SANS PICERL frameworks."""
import requests
import json
import sys
import argparse
import hashlib
from datetime import datetime, timezone
NIST_CATEGORIES = {
"unauthorized_access": "Unauthorized Access",
"dos": "Denial of Service",
"malicious_code": "Malicious Code",
"improper_usage": "Improper Usage",
"reconnaissance": "Reconnaissance",
"web_attack": "Web Application Attack",
}
SEVERITY_MATRIX = {
"P1": {"label": "Critical", "ack_sla": "15 min", "contain_sla": "1 hour",
"criteria": "Crown jewel compromise, active exfiltration, ransomware spreading"},
"P2": {"label": "High", "ack_sla": "30 min", "contain_sla": "4 hours",
"criteria": "Production compromise, confirmed malware, privileged account takeover"},
"P3": {"label": "Medium", "ack_sla": "2 hours", "contain_sla": "24 hours",
"criteria": "Non-production compromise, failed exploitation, single endpoint malware"},
"P4": {"label": "Low", "ack_sla": "8 hours", "contain_sla": "72 hours",
"criteria": "Reconnaissance, policy violation, benign true positive"},
}
def classify_incident(alert_data):
"""Classify incident type based on alert indicators."""
print("[*] Classifying incident type...")
alert_name = alert_data.get("alert_name", "").lower()
process = alert_data.get("process", "").lower()
event_code = alert_data.get("event_code", "")
if any(kw in alert_name for kw in ["malware", "ransomware", "trojan", "cryptominer"]):
category = "malicious_code"
elif any(kw in alert_name for kw in ["brute force", "credential", "password spray"]):
category = "unauthorized_access"
elif any(kw in alert_name for kw in ["dos", "flood", "resource exhaustion"]):
category = "dos"
elif any(kw in alert_name for kw in ["sql injection", "xss", "ssrf", "xxe"]):
category = "web_attack"
elif any(kw in alert_name for kw in ["scan", "enum", "recon", "discovery"]):
category = "reconnaissance"
elif "powershell" in process and "encoded" in alert_name.lower():
category = "malicious_code"
else:
category = "unauthorized_access"
classification = NIST_CATEGORIES.get(category, "Unknown")
print(f" [+] Classification: {classification} ({category})")
return category, classification
def assess_severity(alert_data, asset_criticality="medium"):
"""Calculate incident severity based on threat and asset context."""
print("\n[*] Assessing severity...")
threat_score = 0
alert_severity = alert_data.get("severity", "").lower()
if alert_severity in ("critical", "high"):
threat_score += 3
elif alert_severity == "medium":
threat_score += 2
else:
threat_score += 1
confidence = alert_data.get("confidence", 50)
if confidence >= 80:
threat_score += 2
elif confidence >= 50:
threat_score += 1
asset_scores = {"critical": 3, "high": 2, "medium": 1, "low": 0}
asset_score = asset_scores.get(asset_criticality, 1)
total = threat_score + asset_score
if total >= 7:
priority = "P1"
elif total >= 5:
priority = "P2"
elif total >= 3:
priority = "P3"
else:
priority = "P4"
sev_info = SEVERITY_MATRIX[priority]
print(f" [+] Priority: {priority} - {sev_info['label']}")
print(f" [+] ACK SLA: {sev_info['ack_sla']} | Containment SLA: {sev_info['contain_sla']}")
return priority, sev_info
def check_virustotal(api_key, indicator, indicator_type="ip"):
"""Check an indicator against VirusTotal."""
print(f"\n[*] Checking VirusTotal for {indicator_type}: {indicator}...")
base_urls = {
"ip": f"https://www.virustotal.com/api/v3/ip_addresses/{indicator}",
"hash": f"https://www.virustotal.com/api/v3/files/{indicator}",
"domain": f"https://www.virustotal.com/api/v3/domains/{indicator}",
}
url = base_urls.get(indicator_type)
if not url:
return {}
try:
headers = {"x-apikey": api_key}
resp = requests.get(url, headers=headers, timeout=15)
if resp.status_code == 200:
data = resp.json().get("data", {}).get("attributes", {})
if indicator_type in ("ip", "domain"):
malicious = data.get("last_analysis_stats", {}).get("malicious", 0)
total = sum(data.get("last_analysis_stats", {}).values())
print(f" [+] VT Result: {malicious}/{total} vendors flagged as malicious")
return {"malicious": malicious, "total": total}
elif indicator_type == "hash":
malicious = data.get("last_analysis_stats", {}).get("malicious", 0)
name = data.get("meaningful_name", "Unknown")
print(f" [+] VT Result: {name} - {malicious} detections")
return {"name": name, "malicious": malicious}
elif resp.status_code == 404:
print(f" [-] Not found in VirusTotal")
else:
print(f" [-] VT API error: {resp.status_code}")
except requests.RequestException as e:
print(f" [-] VT request failed: {e}")
return {}
def build_mitre_mapping(category, process_info=""):
"""Map incident to MITRE ATT&CK techniques."""
mappings = {
"malicious_code": [
{"technique": "T1059.001", "name": "PowerShell"},
{"technique": "T1204.002", "name": "User Execution: Malicious File"},
],
"unauthorized_access": [
{"technique": "T1110", "name": "Brute Force"},
{"technique": "T1078", "name": "Valid Accounts"},
],
"reconnaissance": [
{"technique": "T1046", "name": "Network Service Discovery"},
{"technique": "T1595", "name": "Active Scanning"},
],
"web_attack": [
{"technique": "T1190", "name": "Exploit Public-Facing Application"},
],
}
techniques = mappings.get(category, [])
if techniques:
print(f"\n[*] MITRE ATT&CK mapping:")
for t in techniques:
print(f" - {t['technique']}: {t['name']}")
return techniques
def generate_triage_record(alert_data, classification, priority, sev_info,
ti_results, mitre, output_path):
"""Generate a structured incident triage report."""
triage_time = datetime.now(timezone.utc)
alert_time = alert_data.get("timestamp", triage_time.isoformat())
record = {
"ticket_id": f"INC-{triage_time.strftime('%Y')}-{hash(str(alert_data)) % 10000:04d}",
"triage_analyst": alert_data.get("analyst", "automated"),
"triage_time": triage_time.isoformat(),
"alert_time": alert_time,
"classification": {
"type": classification[1],
"category": classification[0],
"priority": priority,
"severity_label": sev_info["label"],
"confidence": alert_data.get("confidence", "Unknown"),
},
"affected_scope": {
"assets": alert_data.get("affected_hosts", []),
"users": alert_data.get("affected_users", []),
"business_unit": alert_data.get("business_unit", "Unknown"),
},
"evidence": {
"alert_source": alert_data.get("source", "Unknown"),
"alert_name": alert_data.get("alert_name", "Unknown"),
"raw_indicators": alert_data.get("indicators", {}),
},
"enrichment": {
"threat_intel": ti_results,
"mitre_attack": mitre,
},
"recommended_actions": [],
"sla": {
"acknowledge_by": sev_info["ack_sla"],
"contain_by": sev_info["contain_sla"],
},
}
if priority in ("P1", "P2"):
record["recommended_actions"] = [
"Isolate affected endpoint via EDR",
"Disable compromised user account",
"Preserve volatile evidence (memory dump)",
"Escalate to Tier 2 IR team",
]
else:
record["recommended_actions"] = [
"Monitor for additional indicators",
"Review related alerts for the past 7 days",
"Document findings and close if benign",
]
with open(output_path, "w") as f:
json.dump(record, f, indent=2)
print(f"\n[*] Triage record saved to {output_path}")
print(f"[*] Ticket: {record['ticket_id']} | Priority: {priority} ({sev_info['label']})")
return record
def main():
parser = argparse.ArgumentParser(description="Security Incident Triage Agent")
parser.add_argument("--alert-name", required=True, help="Name of the triggering alert")
parser.add_argument("--source", default="SIEM", help="Alert source system")
parser.add_argument("--severity", default="high", help="Alert severity")
parser.add_argument("--confidence", type=int, default=75, help="Alert confidence (0-100)")
parser.add_argument("--host", help="Affected hostname")
parser.add_argument("--src-ip", help="Source IP address")
parser.add_argument("--user", help="Affected username")
parser.add_argument("--process", default="", help="Suspicious process name")
parser.add_argument("--asset-criticality", default="medium",
choices=["critical", "high", "medium", "low"])
parser.add_argument("--vt-key", help="VirusTotal API key for threat intel")
parser.add_argument("--indicator", help="IOC to check (IP, hash, or domain)")
parser.add_argument("--indicator-type", default="ip", choices=["ip", "hash", "domain"])
parser.add_argument("-o", "--output", default="triage_record.json")
args = parser.parse_args()
alert_data = {
"alert_name": args.alert_name,
"source": args.source,
"severity": args.severity,
"confidence": args.confidence,
"affected_hosts": [args.host] if args.host else [],
"affected_users": [args.user] if args.user else [],
"process": args.process,
"indicators": {"src_ip": args.src_ip},
"timestamp": datetime.now(timezone.utc).isoformat(),
}
print("[*] Security Incident Triage\n")
classification = classify_incident(alert_data)
priority, sev_info = assess_severity(alert_data, args.asset_criticality)
mitre = build_mitre_mapping(classification[0], args.process)
ti_results = {}
if args.vt_key and args.indicator:
ti_results = check_virustotal(args.vt_key, args.indicator, args.indicator_type)
generate_triage_record(alert_data, classification, priority, sev_info,
ti_results, mitre, args.output)
if __name__ == "__main__":
main()