mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-28 23:20:58 +03:00
Add 55 new skills across 3 new domains + 6 undercovered areas (762 -> 817)
Demand-driven expansion targeting the fastest-growing 2025-2026 threat and
skills categories (ISC2/WEF/CrowdStrike/Mandiant signals):
- AI Security (NEW domain, 12 skills): LLM red-teaming with garak/PyRIT,
prompt injection (direct/indirect/RAG), MCP tool-poisoning, agentic tool
invocation, guardrails, model/data poisoning, system-prompt leakage,
embedding/vector weaknesses, model extraction, continuous red-teaming
- Supply Chain Security (NEW domain, 5 skills): SBOMs, dependency confusion,
malicious-npm triage, typosquatting, SLSA/Sigstore provenance
- Hardware & Firmware Security (NEW domain, 4 skills): CHIPSEC/UEFI audit,
Secure Boot bypass, TPM measured-boot attestation, ESP bootkit hunting
- Identity (10): Entra ID/ROADtools, GraphRunner, AADInternals, ADCS/Certipy,
shadow credentials, coercion, BloodHound CE, device-code phishing, SSO abuse
- Cloud-native (8): Stratus, Pacu, CloudFox, container escape, K8s RBAC,
Falco, Trivy, kube-bench
- Offensive C2 (6): Sliver, Havoc, NetExec, DPAPI, NTLM relay ESC8, redirectors
- DFIR (6): Hayabusa, Chainsaw, KAPE, Velociraptor, EZ Tools, Plaso
- Backfill (4): OpenCTI, MISP, honeytokens, post-quantum crypto migration
Each skill follows the repo taxonomy (SKILL.md + references/{standards,api-reference}.md
+ scripts/agent.py + LICENSE), with researched real tool commands (no placeholders),
complete frontmatter, and ATT&CK/ATLAS + NIST CSF mappings. Updates README domain
table, skill count, and index.json.
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
MISP feed operationalization helper.
|
||||
|
||||
Connects to a MISP instance with PyMISP, searches for fresh, actionable
|
||||
(to_ids, published, warninglist-enforced) IOCs, and writes detection artifacts:
|
||||
- Suricata rules (via REST returnFormat:suricata)
|
||||
- a Wazuh CDB list (domains + IPs)
|
||||
- a Sigma rule (DNS contact to malicious domains)
|
||||
|
||||
Defensive threat-intelligence use. Handle exported IOCs per their TLP marking.
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
from pymisp import PyMISP
|
||||
except ImportError:
|
||||
print("[error] pymisp not installed: pip install pymisp", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
import urllib.request
|
||||
import ssl
|
||||
|
||||
IOC_TYPES = ["ip-dst", "ip-src", "domain", "hostname", "url", "md5", "sha256"]
|
||||
|
||||
|
||||
def connect(url: str, key: str, insecure: bool) -> PyMISP:
|
||||
return PyMISP(url, key, ssl=not insecure)
|
||||
|
||||
|
||||
def search_iocs(misp: PyMISP, last: str) -> list:
|
||||
try:
|
||||
return misp.search(
|
||||
controller="attributes",
|
||||
type_attribute=IOC_TYPES,
|
||||
to_ids=True,
|
||||
published=True,
|
||||
last=last,
|
||||
enforce_warninglist=True,
|
||||
pythonify=True,
|
||||
)
|
||||
except Exception as exc: # noqa: BLE001
|
||||
print(f"[error] MISP search failed: {exc}", file=sys.stderr)
|
||||
return []
|
||||
|
||||
|
||||
def export_suricata(url: str, key: str, last: str, insecure: bool, out: Path) -> bool:
|
||||
endpoint = (
|
||||
f"{url.rstrip('/')}/attributes/restSearch/returnFormat:suricata/"
|
||||
f"to_ids:1/type:domain%7Cip-dst%7Curl/last:{last}"
|
||||
)
|
||||
ctx = ssl.create_default_context()
|
||||
if insecure:
|
||||
ctx.check_hostname = False
|
||||
ctx.verify_mode = ssl.CERT_NONE
|
||||
req = urllib.request.Request(
|
||||
endpoint, headers={"Authorization": key, "Accept": "application/json"}
|
||||
)
|
||||
try:
|
||||
with urllib.request.urlopen(req, context=ctx, timeout=120) as resp:
|
||||
out.write_bytes(resp.read())
|
||||
return True
|
||||
except Exception as exc: # noqa: BLE001
|
||||
print(f"[warn] suricata export failed: {exc}", file=sys.stderr)
|
||||
return False
|
||||
|
||||
|
||||
def write_wazuh_cdb(attrs: list, out: Path) -> int:
|
||||
n = 0
|
||||
with out.open("w", encoding="utf-8") as fh:
|
||||
for a in attrs:
|
||||
if a.type in ("domain", "hostname", "ip-dst", "ip-src"):
|
||||
fh.write(f"{a.value}:\n")
|
||||
n += 1
|
||||
return n
|
||||
|
||||
|
||||
def write_sigma(attrs: list, out: Path) -> int:
|
||||
domains = sorted({a.value for a in attrs if a.type in ("domain", "hostname")})
|
||||
if not domains:
|
||||
return 0
|
||||
rule = {
|
||||
"title": "MISP feed malicious domain contact",
|
||||
"status": "experimental",
|
||||
"description": "DNS query to a domain flagged malicious in MISP feeds",
|
||||
"logsource": {"category": "dns"},
|
||||
"detection": {"selection": {"query|contains": domains}, "condition": "selection"},
|
||||
"level": "high",
|
||||
"tags": ["attack.command_and_control", "attack.t1071.004"],
|
||||
}
|
||||
try:
|
||||
import yaml
|
||||
out.write_text("", encoding="utf-8")
|
||||
with out.open("w", encoding="utf-8") as fh:
|
||||
yaml.safe_dump(rule, fh, sort_keys=False, default_flow_style=False)
|
||||
except ImportError:
|
||||
out.write_text(json.dumps(rule, indent=2), encoding="utf-8")
|
||||
print("[warn] pyyaml missing; wrote Sigma rule as JSON", file=sys.stderr)
|
||||
return len(domains)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
ap = argparse.ArgumentParser(description="MISP feed -> detections pipeline")
|
||||
ap.add_argument("--url", required=True, help="MISP base URL")
|
||||
ap.add_argument("--key", required=True, help="MISP Auth Key")
|
||||
ap.add_argument("--last", default="7d", help="time window (e.g. 7d, 24h)")
|
||||
ap.add_argument("--outdir", default="./detections")
|
||||
ap.add_argument("--insecure", action="store_true", help="skip TLS verification (lab)")
|
||||
args = ap.parse_args()
|
||||
|
||||
outdir = Path(args.outdir)
|
||||
outdir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
try:
|
||||
misp = connect(args.url, args.key, args.insecure)
|
||||
except Exception as exc: # noqa: BLE001
|
||||
print(f"[error] cannot connect to MISP: {exc}", file=sys.stderr)
|
||||
return 2
|
||||
|
||||
attrs = search_iocs(misp, args.last)
|
||||
print(f"[+] {len(attrs)} actionable IOC(s) retrieved (last {args.last})")
|
||||
|
||||
suricata_ok = export_suricata(
|
||||
args.url, args.key, args.last, args.insecure, outdir / "misp_suricata.rules"
|
||||
)
|
||||
if suricata_ok:
|
||||
print(f"[+] Suricata rules -> {outdir / 'misp_suricata.rules'}")
|
||||
|
||||
cdb_n = write_wazuh_cdb(attrs, outdir / "misp_iocs.cdb")
|
||||
print(f"[+] Wazuh CDB list ({cdb_n} entries) -> {outdir / 'misp_iocs.cdb'}")
|
||||
|
||||
sig_n = write_sigma(attrs, outdir / "misp_domains.yml")
|
||||
print(f"[+] Sigma rule ({sig_n} domains) -> {outdir / 'misp_domains.yml'}")
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user