mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-09-03 23:10:50 +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,144 @@
|
||||
#!/usr/bin/env python3
|
||||
"""kube-bench helper.
|
||||
|
||||
Runs kube-bench with JSON output, parses the CIS Kubernetes Benchmark
|
||||
results, summarises PASS/FAIL/WARN/INFO totals per section, lists failing
|
||||
checks with their remediation, and optionally exits non-zero when failures
|
||||
exist (for CI/CD compliance gating).
|
||||
|
||||
Requires the `kube-bench` binary on PATH (or run inside the aquasec/kube-bench
|
||||
container). See https://github.com/aquasecurity/kube-bench
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from collections import Counter
|
||||
from datetime import datetime, timezone
|
||||
|
||||
|
||||
def ensure_kube_bench() -> str:
|
||||
"""Return the kube-bench path or exit with install guidance."""
|
||||
path = shutil.which("kube-bench")
|
||||
if not path:
|
||||
print("[!] kube-bench not found on PATH. Install: "
|
||||
"https://github.com/aquasecurity/kube-bench/releases",
|
||||
file=sys.stderr)
|
||||
sys.exit(2)
|
||||
return path
|
||||
|
||||
|
||||
def run_kube_bench(binary: str, targets: str, benchmark: str, timeout: int) -> dict:
|
||||
"""Execute kube-bench with JSON output and return the parsed report."""
|
||||
cmd = [binary, "run", "--targets", targets, "--json"]
|
||||
if benchmark:
|
||||
cmd += ["--benchmark", benchmark]
|
||||
print(f"[*] running: {' '.join(cmd)}")
|
||||
try:
|
||||
proc = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
|
||||
except subprocess.TimeoutExpired:
|
||||
print(f"[!] kube-bench timed out after {timeout}s", file=sys.stderr)
|
||||
sys.exit(3)
|
||||
# kube-bench may exit non-zero when checks fail; results are still on stdout.
|
||||
if not proc.stdout.strip():
|
||||
print(f"[!] kube-bench produced no output (rc={proc.returncode}): "
|
||||
f"{proc.stderr.strip()}", file=sys.stderr)
|
||||
sys.exit(proc.returncode or 4)
|
||||
try:
|
||||
return json.loads(proc.stdout)
|
||||
except json.JSONDecodeError:
|
||||
print("[!] Could not parse kube-bench JSON output.", file=sys.stderr)
|
||||
print(proc.stderr.strip(), file=sys.stderr)
|
||||
sys.exit(4)
|
||||
|
||||
|
||||
def iter_checks(report: dict):
|
||||
"""Yield (section_id, section_text, check) tuples across all controls."""
|
||||
# kube-bench JSON: top-level "Controls" -> "tests" -> "results".
|
||||
controls = report.get("Controls")
|
||||
if controls is None and isinstance(report, list):
|
||||
controls = report
|
||||
for control in controls or []:
|
||||
for section in control.get("tests", []) or []:
|
||||
sid = section.get("section", "")
|
||||
stext = section.get("desc", "")
|
||||
for check in section.get("results", []) or []:
|
||||
yield sid, stext, check
|
||||
|
||||
|
||||
def summarise(report: dict):
|
||||
"""Return overall Counter, per-section Counters, and failing checks."""
|
||||
overall = Counter()
|
||||
per_section = {}
|
||||
failures = []
|
||||
for sid, stext, check in iter_checks(report):
|
||||
state = (check.get("status") or "").upper()
|
||||
overall[state] += 1
|
||||
per_section.setdefault(sid, [stext, Counter()])
|
||||
per_section[sid][1][state] += 1
|
||||
if state in ("FAIL", "WARN"):
|
||||
failures.append({
|
||||
"section": sid,
|
||||
"id": check.get("test_number"),
|
||||
"desc": check.get("test_desc"),
|
||||
"status": state,
|
||||
"remediation": (check.get("remediation") or "").strip(),
|
||||
})
|
||||
return overall, per_section, failures
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description="kube-bench CIS compliance helper")
|
||||
parser.add_argument("--targets", default="master,node",
|
||||
help="Comma list: master,node,etcd,policies,controlplane")
|
||||
parser.add_argument("--benchmark", default="", help="Pin benchmark, e.g. cis-1.8")
|
||||
parser.add_argument("--timeout", type=int, default=300, help="Run timeout (s)")
|
||||
parser.add_argument("--show-remediation", action="store_true",
|
||||
help="Print remediation text for each failing check")
|
||||
parser.add_argument("--fail-on-warn", action="store_true",
|
||||
help="Treat WARN as gating in addition to FAIL")
|
||||
parser.add_argument("--gate", action="store_true",
|
||||
help="Exit non-zero when failing checks exist")
|
||||
parser.add_argument("--output", help="Write JSON summary to file")
|
||||
args = parser.parse_args()
|
||||
|
||||
binary = ensure_kube_bench()
|
||||
report = run_kube_bench(binary, args.targets, args.benchmark, args.timeout)
|
||||
overall, per_section, failures = summarise(report)
|
||||
|
||||
print(f"\n=== kube-bench summary {datetime.now(timezone.utc).isoformat()} ===")
|
||||
for state in ("PASS", "FAIL", "WARN", "INFO"):
|
||||
print(f" {state:<5}: {overall.get(state, 0)}")
|
||||
|
||||
print("\n--- Per section ---")
|
||||
for sid in sorted(per_section):
|
||||
text, counts = per_section[sid]
|
||||
print(f" [{sid}] {text}: "
|
||||
f"PASS={counts.get('PASS',0)} FAIL={counts.get('FAIL',0)} "
|
||||
f"WARN={counts.get('WARN',0)}")
|
||||
|
||||
print(f"\n--- Findings requiring action ({len(failures)}) ---")
|
||||
for f in failures:
|
||||
print(f" {f['status']} {f['id']}: {f['desc']}")
|
||||
if args.show_remediation and f["remediation"]:
|
||||
print(f" -> {f['remediation']}")
|
||||
|
||||
if args.output:
|
||||
with open(args.output, "w", encoding="utf-8") as fh:
|
||||
json.dump({"overall": dict(overall), "failures": failures}, fh, indent=2)
|
||||
print(f"[+] Summary written to {args.output}")
|
||||
|
||||
if args.gate:
|
||||
blocking = overall.get("FAIL", 0)
|
||||
if args.fail_on_warn:
|
||||
blocking += overall.get("WARN", 0)
|
||||
if blocking > 0:
|
||||
print(f"[!] GATE FAILED: {blocking} non-compliant checks", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
print("[+] Done.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user