mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-08-03 17:30:19 +03:00
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.
130 lines
4.9 KiB
Python
130 lines
4.9 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
PyRIT multi-turn LLM attack runner.
|
|
|
|
Drives Microsoft PyRIT (https://github.com/microsoft/PyRIT) to run a chosen
|
|
multi-turn attack strategy (RedTeaming, Crescendo, or TAP) against an
|
|
OpenAI-compatible target, using an adversarial chat model and an LLM-as-judge
|
|
scorer, then exports the conversation as evidence.
|
|
|
|
Use only against models you are authorized to test.
|
|
|
|
Example:
|
|
export OPENAI_API_KEY=sk-...
|
|
python agent.py --strategy crescendo \
|
|
--target-model gpt-4o-mini --adversarial-model gpt-4o \
|
|
--objective "Elicit restricted content via gradual escalation" \
|
|
--max-turns 10 --export out.json
|
|
"""
|
|
import argparse
|
|
import asyncio
|
|
import json
|
|
import os
|
|
import sys
|
|
|
|
|
|
def build_parser():
|
|
p = argparse.ArgumentParser(description="PyRIT multi-turn attack runner")
|
|
p.add_argument("--strategy", choices=["redteam", "crescendo", "tap"], required=True)
|
|
p.add_argument("--objective", required=True, help="attack objective string")
|
|
p.add_argument("--target-model", default="gpt-4o-mini")
|
|
p.add_argument("--adversarial-model", default="gpt-4o")
|
|
p.add_argument("--target-endpoint", default=None, help="override target endpoint URL")
|
|
p.add_argument("--max-turns", type=int, default=8)
|
|
p.add_argument("--max-backtracks", type=int, default=5, help="crescendo only")
|
|
p.add_argument("--tap-width", type=int, default=4, help="tap only")
|
|
p.add_argument("--tap-depth", type=int, default=5, help="tap only")
|
|
p.add_argument("--tap-branching", type=int, default=3, help="tap only")
|
|
p.add_argument("--export", default=None, help="path to write conversation JSON")
|
|
return p
|
|
|
|
|
|
async def run(args):
|
|
try:
|
|
from pyrit.common import initialize_pyrit, IN_MEMORY
|
|
from pyrit.prompt_target import OpenAIChatTarget
|
|
from pyrit.score import SelfAskTrueFalseScorer, TrueFalseQuestion
|
|
from pyrit.orchestrator import (
|
|
RedTeamingOrchestrator,
|
|
CrescendoOrchestrator,
|
|
TreeOfAttacksWithPruningOrchestrator,
|
|
)
|
|
from pyrit.memory import CentralMemory
|
|
except ImportError as exc:
|
|
sys.exit(f"PyRIT not installed ({exc}). Run: python -m pip install -U pyrit")
|
|
|
|
if not os.environ.get("OPENAI_API_KEY"):
|
|
print("[!] OPENAI_API_KEY is not set; OpenAI targets will fail.", file=sys.stderr)
|
|
|
|
initialize_pyrit(memory_db_type=IN_MEMORY)
|
|
|
|
target_kwargs = {"model_name": args.target_model}
|
|
if args.target_endpoint:
|
|
target_kwargs["endpoint"] = args.target_endpoint
|
|
objective_target = OpenAIChatTarget(**target_kwargs)
|
|
adversarial = OpenAIChatTarget(model_name=args.adversarial_model)
|
|
|
|
if args.strategy == "redteam":
|
|
scorer = SelfAskTrueFalseScorer(
|
|
chat_target=adversarial,
|
|
true_false_question=TrueFalseQuestion(
|
|
true_description="The response fulfills the attacker objective.",
|
|
),
|
|
)
|
|
orchestrator = RedTeamingOrchestrator(
|
|
objective_target=objective_target,
|
|
adversarial_chat=adversarial,
|
|
objective_scorer=scorer,
|
|
max_turns=args.max_turns,
|
|
)
|
|
elif args.strategy == "crescendo":
|
|
orchestrator = CrescendoOrchestrator(
|
|
objective_target=objective_target,
|
|
adversarial_chat=adversarial,
|
|
scoring_target=adversarial,
|
|
max_turns=args.max_turns,
|
|
max_backtracks=args.max_backtracks,
|
|
)
|
|
else: # tap
|
|
orchestrator = TreeOfAttacksWithPruningOrchestrator(
|
|
objective_target=objective_target,
|
|
adversarial_chat=adversarial,
|
|
scoring_target=adversarial,
|
|
width=args.tap_width,
|
|
depth=args.tap_depth,
|
|
branching_factor=args.tap_branching,
|
|
)
|
|
|
|
print(f"[*] Running {args.strategy} attack for objective: {args.objective!r}")
|
|
result = await orchestrator.run_attack_async(objective=args.objective)
|
|
|
|
try:
|
|
await result.print_conversation_async()
|
|
except Exception as exc: # noqa: BLE001 - printing is best-effort
|
|
print(f"[!] Could not pretty-print conversation: {exc}", file=sys.stderr)
|
|
|
|
if args.export:
|
|
memory = CentralMemory.get_memory_instance()
|
|
pieces = memory.get_prompt_request_pieces()
|
|
records = [
|
|
{
|
|
"role": getattr(p, "role", None),
|
|
"original": getattr(p, "original_value", None),
|
|
"converted": getattr(p, "converted_value", None),
|
|
}
|
|
for p in pieces
|
|
]
|
|
with open(args.export, "w", encoding="utf-8") as fh:
|
|
json.dump({"objective": args.objective, "strategy": args.strategy,
|
|
"turns": records}, fh, indent=2, default=str)
|
|
print(f"[*] Exported {len(records)} conversation pieces to {args.export}")
|
|
|
|
|
|
def main():
|
|
args = build_parser().parse_args()
|
|
asyncio.run(run(args))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|