mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-13 19:05:17 +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,140 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Secure Boot bypass / bootkit detection helper (Linux + Windows-aware).
|
||||
|
||||
Collects:
|
||||
- Secure Boot enabled state
|
||||
- dbx (revocation list) entry count and freshness signal
|
||||
- SHA-256 hashes of EFI boot binaries on the ESP
|
||||
- CHIPSEC secureboot.variables result (optional, requires root + chipsec)
|
||||
|
||||
Emits a JSON report and a human-readable summary. Read-only by default.
|
||||
Authorized assessment use only; run from a trusted/live environment.
|
||||
"""
|
||||
import argparse
|
||||
import glob
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import platform
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ESP_PATHS = ["/boot/efi/EFI", "/boot/EFI", "/efi/EFI"]
|
||||
|
||||
|
||||
def run(cmd: list[str], timeout: int = 300) -> tuple[int, str, str]:
|
||||
try:
|
||||
p = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
|
||||
return p.returncode, p.stdout, p.stderr
|
||||
except FileNotFoundError:
|
||||
return 127, "", f"not found: {cmd[0]}"
|
||||
except subprocess.SubprocessError as exc:
|
||||
return 1, "", str(exc)
|
||||
|
||||
|
||||
def secure_boot_state() -> dict:
|
||||
state = {"platform": platform.system()}
|
||||
if platform.system() == "Linux":
|
||||
if shutil.which("mokutil"):
|
||||
rc, out, _ = run(["mokutil", "--sb-state"])
|
||||
state["mokutil_sb_state"] = out.strip() or "unknown"
|
||||
state["enabled"] = "enabled" in out.lower()
|
||||
else:
|
||||
# Fall back to reading the EFI variable directly
|
||||
var = glob.glob("/sys/firmware/efi/efivars/SecureBoot-*")
|
||||
if var:
|
||||
try:
|
||||
data = Path(var[0]).read_bytes()
|
||||
state["enabled"] = bool(data and data[-1] == 1)
|
||||
state["efivar_raw"] = data.hex()
|
||||
except OSError as exc:
|
||||
state["error"] = f"efivar read failed: {exc}"
|
||||
else:
|
||||
state["error"] = "no mokutil and no SecureBoot efivar"
|
||||
elif platform.system() == "Windows":
|
||||
rc, out, err = run(
|
||||
["powershell", "-NoProfile", "-Command", "Confirm-SecureBootUEFI"]
|
||||
)
|
||||
state["confirm_secureboot"] = out.strip()
|
||||
state["enabled"] = out.strip().lower() == "true"
|
||||
return state
|
||||
|
||||
|
||||
def dbx_status() -> dict:
|
||||
info = {}
|
||||
if shutil.which("dbxtool"):
|
||||
rc, out, err = run(["dbxtool", "--list"])
|
||||
# Each revocation is one line; count non-empty lines as an approximation
|
||||
lines = [l for l in out.splitlines() if l.strip()]
|
||||
info["dbxtool_entries"] = len(lines)
|
||||
info["sample"] = lines[:5]
|
||||
if len(lines) < 50:
|
||||
info["warning"] = "low dbx entry count; platform may be behind on revocations"
|
||||
elif shutil.which("efi-readvar"):
|
||||
rc, out, err = run(["efi-readvar", "-v", "dbx"])
|
||||
info["efi_readvar_dbx_excerpt"] = out[:800]
|
||||
else:
|
||||
info["error"] = "neither dbxtool nor efi-readvar available"
|
||||
return info
|
||||
|
||||
|
||||
def hash_esp_binaries() -> list[dict]:
|
||||
results = []
|
||||
base = next((p for p in ESP_PATHS if os.path.isdir(p)), None)
|
||||
if not base:
|
||||
return [{"error": "no ESP path found (run as root with EFI mounted)"}]
|
||||
for path in Path(base).rglob("*.efi"):
|
||||
try:
|
||||
digest = hashlib.sha256(path.read_bytes()).hexdigest()
|
||||
results.append({"file": str(path), "sha256": digest, "size": path.stat().st_size})
|
||||
except OSError as exc:
|
||||
results.append({"file": str(path), "error": str(exc)})
|
||||
return results
|
||||
|
||||
|
||||
def chipsec_secureboot() -> dict:
|
||||
if not shutil.which("chipsec_main"):
|
||||
return {"error": "chipsec_main not installed"}
|
||||
rc, out, err = run(["chipsec_main", "-m", "common.secureboot.variables"], timeout=600)
|
||||
verdict = "PASSED" if "PASSED" in out else "FAILED" if "FAILED" in out else "UNKNOWN"
|
||||
return {"verdict": verdict, "tail": out[-1200:]}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
ap = argparse.ArgumentParser(description="Secure Boot / bootkit assessment")
|
||||
ap.add_argument("--check-chipsec", action="store_true", help="Run CHIPSEC secureboot module (root)")
|
||||
ap.add_argument("--output", help="Write JSON report")
|
||||
args = ap.parse_args()
|
||||
|
||||
if platform.system() == "Linux" and os.geteuid() != 0:
|
||||
print("[warn] not running as root; some checks may be incomplete", file=sys.stderr)
|
||||
|
||||
report = {
|
||||
"secure_boot": secure_boot_state(),
|
||||
"dbx": dbx_status(),
|
||||
"esp_binaries": hash_esp_binaries(),
|
||||
}
|
||||
if args.check_chipsec:
|
||||
report["chipsec_secureboot_variables"] = chipsec_secureboot()
|
||||
|
||||
sb = report["secure_boot"]
|
||||
print(f"[+] Secure Boot enabled: {sb.get('enabled')}")
|
||||
if not sb.get("enabled"):
|
||||
print("[!] Secure Boot is NOT enabled — platform is unprotected against bootkits")
|
||||
if "warning" in report["dbx"]:
|
||||
print(f"[!] dbx: {report['dbx']['warning']}")
|
||||
print(f"[+] {len([b for b in report['esp_binaries'] if 'sha256' in b])} EFI binaries hashed")
|
||||
if args.check_chipsec:
|
||||
print(f"[+] CHIPSEC secureboot.variables: {report['chipsec_secureboot_variables'].get('verdict')}")
|
||||
|
||||
if args.output:
|
||||
Path(args.output).write_text(json.dumps(report, indent=2), encoding="utf-8")
|
||||
print(f"[+] report written to {args.output}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user