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
@@ -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,66 @@
# API Reference: Mapping MITRE ATT&CK Techniques
## mitreattack-python Library
| Method | Description |
|--------|-------------|
| `MitreAttackData(stix_filepath=path)` | Load ATT&CK STIX 2.0 data bundle from file |
| `get_techniques(remove_revoked_deprecated=False)` | Returns `list[AttackPattern]` STIX objects |
| `get_groups(remove_revoked_deprecated=False)` | Returns `list[IntrusionSet]` STIX objects |
| `get_techniques_used_by_group(group_stix_id)` | Returns `list[dict]` with `t["object"]` as AttackPattern |
| `get_attack_id(stix_id=id)` | Resolve STIX ID to ATT&CK ID (e.g., T1059) |
| `get_mitigations(remove_revoked_deprecated=False)` | Returns `list[CourseOfAction]` |
| `get_software(remove_revoked_deprecated=False)` | Returns `list[Malware or Tool]` |
## ATT&CK Navigator API (Layer Format)
| Field | Type | Description |
|-------|------|-------------|
| `techniques[].techniqueID` | string | ATT&CK technique ID (e.g., T1059) |
| `techniques[].score` | number | Coverage score (0=gap, 1=detected) |
| `techniques[].color` | string | Hex color for heatmap visualization |
| `domain` | string | ATT&CK domain: enterprise-attack, mobile-attack, ics-attack |
## MITRE ATT&CK TAXII Server
| Endpoint | Description |
|----------|-------------|
| `cti-taxii.mitre.org/stix/collections/` | List available STIX collections |
| `cti-taxii.mitre.org/stix/collections/{id}/objects/` | Download STIX objects |
## Sigma Rules (Detection Engineering)
| Field | Description |
|-------|-------------|
| `tags` | ATT&CK mapping (e.g., `attack.t1059.001`) |
| `logsource.product` | Target log source (windows, linux, aws) |
| `detection` | Search logic with conditions |
## Key Libraries
- **mitreattack-python** (`pip install mitreattack-python`): Official MITRE ATT&CK Python library
- **stix2**: Parse and create STIX 2.1 objects
- **taxii2-client**: Download ATT&CK data from TAXII server
- **pySigma**: Parse and convert Sigma detection rules
## Configuration
| Variable | Description |
|----------|-------------|
| `ATTACK_STIX_PATH` | Path to local enterprise-attack.json STIX bundle |
| `NAVIGATOR_URL` | ATT&CK Navigator instance URL |
## Data Sources
| Source | URL | Description |
|--------|-----|-------------|
| ATT&CK STIX | `github.com/mitre/cti` | Official STIX bundles |
| ATT&CK Navigator | `github.com/mitre-attack/attack-navigator` | Layer visualization tool |
| Sigma Rules | `github.com/SigmaHQ/sigma` | Community detection rules |
## References
- [MITRE ATT&CK](https://attack.mitre.org/)
- [mitreattack-python Docs](https://mitreattack-python.readthedocs.io/)
- [ATT&CK Navigator](https://mitre-attack.github.io/attack-navigator/)
- [D3FEND](https://d3fend.mitre.org/)
@@ -0,0 +1,205 @@
#!/usr/bin/env python3
"""
MITRE ATT&CK Technique Mapping Agent
Maps detection rules and security alerts to ATT&CK techniques using
the mitreattack-python library. Generates coverage heatmaps and identifies gaps.
"""
import json
import os
import sys
from datetime import datetime, timezone
from mitreattack.stix20 import MitreAttackData
def load_attack_data(stix_path: str = None) -> MitreAttackData:
"""Load MITRE ATT&CK STIX data bundle."""
if stix_path and os.path.exists(stix_path):
return MitreAttackData(stix_filepath=stix_path)
return MitreAttackData(stix_filepath="enterprise-attack.json")
def get_all_techniques(attack_data: MitreAttackData) -> list[dict]:
"""Retrieve all Enterprise ATT&CK techniques with metadata.
Returns list[AttackPattern] (STIX objects supporting dict-like access).
"""
techniques = attack_data.get_techniques(remove_revoked_deprecated=True)
result = []
for tech in techniques:
# Use get_attack_id() to resolve STIX ID -> ATT&CK ID (e.g. T1059)
tech_id = attack_data.get_attack_id(stix_id=tech.id) or ""
platforms = tech.get("x_mitre_platforms", [])
tactics = []
for phase in tech.get("kill_chain_phases", []):
if phase.get("kill_chain_name") == "mitre-attack":
tactics.append(phase.get("phase_name", ""))
result.append({
"id": tech_id,
"name": tech.name,
"tactics": tactics,
"platforms": platforms,
"is_subtechnique": tech.get("x_mitre_is_subtechnique", False),
})
return sorted(result, key=lambda x: x["id"])
def get_techniques_by_group(attack_data: MitreAttackData, group_name: str) -> list[str]:
"""Get techniques used by a specific threat group.
Groups are IntrusionSet STIX objects; techniques retrieved via relationship query.
"""
groups = attack_data.get_groups(remove_revoked_deprecated=True)
target_group = None
for group in groups:
if group.name.lower() == group_name.lower():
target_group = group
break
for alias in group.get("aliases", []):
if alias.lower() == group_name.lower():
target_group = group
break
if not target_group:
return []
# get_techniques_used_by_group returns list of RelationshipEntry dicts
# Each entry has t["object"] = AttackPattern STIX object
techniques = attack_data.get_techniques_used_by_group(target_group.id)
tech_ids = []
for t in techniques:
technique = t["object"]
attack_id = attack_data.get_attack_id(stix_id=technique.id)
if attack_id:
tech_ids.append(attack_id)
return sorted(tech_ids)
def load_detection_rules(rules_file: str) -> list[dict]:
"""Load detection rules with ATT&CK technique tags."""
if os.path.exists(rules_file):
with open(rules_file, "r") as f:
return json.load(f)
return []
def calculate_coverage(all_techniques: list[dict], detected_technique_ids: set) -> dict:
"""Calculate ATT&CK coverage statistics by tactic."""
tactic_coverage = {}
for tech in all_techniques:
if tech["is_subtechnique"]:
continue
for tactic in tech["tactics"]:
if tactic not in tactic_coverage:
tactic_coverage[tactic] = {"total": 0, "covered": 0, "uncovered_techniques": []}
tactic_coverage[tactic]["total"] += 1
if tech["id"] in detected_technique_ids:
tactic_coverage[tactic]["covered"] += 1
else:
tactic_coverage[tactic]["uncovered_techniques"].append(tech["id"])
for tactic, data in tactic_coverage.items():
data["coverage_pct"] = round(data["covered"] / max(data["total"], 1) * 100, 1)
total_techniques = len([t for t in all_techniques if not t["is_subtechnique"]])
covered = len(detected_technique_ids & {t["id"] for t in all_techniques if not t["is_subtechnique"]})
return {
"overall_coverage_pct": round(covered / max(total_techniques, 1) * 100, 1),
"total_techniques": total_techniques,
"covered_techniques": covered,
"by_tactic": tactic_coverage,
}
def generate_navigator_layer(techniques: list[dict], detected_ids: set, layer_name: str) -> dict:
"""Generate ATT&CK Navigator JSON layer for visualization."""
tech_entries = []
for tech in techniques:
score = 1 if tech["id"] in detected_ids else 0
color = "#31a354" if score == 1 else ""
tech_entries.append({
"techniqueID": tech["id"],
"score": score,
"color": color,
"enabled": True,
})
return {
"name": layer_name,
"versions": {"attack": "14", "navigator": "4.9.1", "layer": "4.5"},
"domain": "enterprise-attack",
"description": f"Detection coverage layer generated {datetime.now(timezone.utc).strftime('%Y-%m-%d')}",
"gradient": {"colors": ["#ff6666", "#31a354"], "minValue": 0, "maxValue": 1},
"techniques": tech_entries,
}
def identify_priority_gaps(coverage: dict, group_techniques: list[str]) -> list[dict]:
"""Identify high-priority coverage gaps based on threat group activity."""
gaps = []
all_uncovered = set()
for tactic, data in coverage["by_tactic"].items():
all_uncovered.update(data["uncovered_techniques"])
for tech_id in group_techniques:
if tech_id in all_uncovered:
gaps.append({"technique_id": tech_id, "reason": "Used by target threat group, no detection"})
return gaps
def generate_report(coverage: dict, gaps: list, group_name: str) -> str:
"""Generate ATT&CK mapping report."""
lines = [
"MITRE ATT&CK DETECTION COVERAGE REPORT",
"=" * 50,
f"Report Date: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M UTC')}",
"",
f"Overall Coverage: {coverage['overall_coverage_pct']}%",
f" Techniques Covered: {coverage['covered_techniques']}/{coverage['total_techniques']}",
"",
"COVERAGE BY TACTIC:",
]
for tactic, data in sorted(coverage["by_tactic"].items()):
bar = "#" * int(data["coverage_pct"] / 5) + "." * (20 - int(data["coverage_pct"] / 5))
lines.append(f" {tactic:35s} [{bar}] {data['coverage_pct']}%")
if gaps:
lines.extend(["", f"PRIORITY GAPS (Threat Group: {group_name}):", "-" * 40])
for gap in gaps[:15]:
lines.append(f" [GAP] {gap['technique_id']} - {gap['reason']}")
return "\n".join(lines)
if __name__ == "__main__":
stix_path = sys.argv[1] if len(sys.argv) > 1 else "enterprise-attack.json"
rules_file = sys.argv[2] if len(sys.argv) > 2 else "detection_rules.json"
group_name = sys.argv[3] if len(sys.argv) > 3 else "APT29"
print("[*] Loading MITRE ATT&CK data...")
attack_data = load_attack_data(stix_path)
all_techniques = get_all_techniques(attack_data)
print(f"[*] Loaded {len(all_techniques)} techniques")
rules = load_detection_rules(rules_file)
detected_ids = set()
for rule in rules:
detected_ids.update(rule.get("attack_ids", []))
coverage = calculate_coverage(all_techniques, detected_ids)
group_techs = get_techniques_by_group(attack_data, group_name)
gaps = identify_priority_gaps(coverage, group_techs)
report = generate_report(coverage, gaps, group_name)
print(report)
layer = generate_navigator_layer(all_techniques, detected_ids, "Detection Coverage")
with open("attack_navigator_layer.json", "w") as f:
json.dump(layer, f, indent=2)
print(f"\n[*] Navigator layer saved to attack_navigator_layer.json")