mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-30 16:06:52 +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.
179 lines
5.8 KiB
Python
179 lines
5.8 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Havoc C2 team-server operator helper.
|
|
|
|
Automates common operator setup tasks around the Havoc Framework binary
|
|
(https://github.com/HavocFramework/Havoc):
|
|
|
|
* validate a Yaotl profile for required blocks before launch
|
|
* build the team server / client via `make ts-build` / `make client-build`
|
|
* launch the team server with a profile (subprocess wrapper)
|
|
* scaffold a starter Yaotl profile
|
|
|
|
Havoc exposes a binary (`./havoc`) rather than a stable Python library, so this
|
|
helper wraps the real CLI via subprocess with the documented flags.
|
|
|
|
Authorized red-team / lab use only.
|
|
"""
|
|
|
|
import argparse
|
|
import os
|
|
import re
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
|
|
|
|
REQUIRED_BLOCKS = ["Teamserver", "Operators", "Listeners", "Demon"]
|
|
|
|
|
|
def validate_profile(path):
|
|
"""Check a Yaotl profile contains the blocks Havoc requires to start."""
|
|
if not os.path.isfile(path):
|
|
raise FileNotFoundError(f"profile not found: {path}")
|
|
text = open(path, "r", encoding="utf-8", errors="replace").read()
|
|
missing = []
|
|
for block in REQUIRED_BLOCKS:
|
|
# Yaotl block opens like: BlockName {
|
|
if not re.search(rf"\b{re.escape(block)}\b\s*\{{", text):
|
|
missing.append(block)
|
|
# Basic sanity: at least one operator password and one listener port
|
|
has_password = re.search(r"Password\s*=", text) is not None
|
|
has_port = re.search(r"Port(Bind|Conn|)\s*=", text) is not None
|
|
if missing:
|
|
print(f"[!] profile missing block(s): {', '.join(missing)}")
|
|
if not has_password:
|
|
print("[!] no operator Password = ... found")
|
|
if not has_port:
|
|
print("[!] no listener Port/PortBind/PortConn found")
|
|
ok = not missing and has_password and has_port
|
|
print("[+] profile looks valid" if ok else "[!] profile incomplete")
|
|
return ok
|
|
|
|
|
|
def scaffold_profile(path, host, listener_host, port):
|
|
"""Write a minimal working Yaotl profile."""
|
|
if os.path.exists(path):
|
|
raise FileExistsError(f"refusing to overwrite existing file: {path}")
|
|
profile = f'''Teamserver {{
|
|
Host = "{host}"
|
|
Port = 40056
|
|
|
|
Build {{
|
|
Compiler64 = "/usr/bin/x86_64-w64-mingw32-gcc"
|
|
Nasm = "/usr/bin/nasm"
|
|
}}
|
|
}}
|
|
|
|
Operators {{
|
|
user "operator1" {{
|
|
Password = "CHANGE_ME_Str0ng!"
|
|
}}
|
|
}}
|
|
|
|
Listeners {{
|
|
Http {{
|
|
Name = "https-listener"
|
|
Hosts = ["{listener_host}"]
|
|
HostBind = "0.0.0.0"
|
|
PortBind = {port}
|
|
PortConn = {port}
|
|
Secure = true
|
|
}}
|
|
}}
|
|
|
|
Demon {{
|
|
Sleep = 30
|
|
Jitter = 25
|
|
Injection {{
|
|
Spawn64 = "C:\\\\Windows\\\\System32\\\\notepad.exe"
|
|
Spawn32 = "C:\\\\Windows\\\\SysWOW64\\\\notepad.exe"
|
|
}}
|
|
}}
|
|
'''
|
|
with open(path, "w", encoding="utf-8") as fh:
|
|
fh.write(profile)
|
|
print(f"[+] wrote starter profile: {path}")
|
|
print("[!] change the operator Password before use.")
|
|
|
|
|
|
def run_make(havoc_dir, target):
|
|
"""Run a make build target inside the Havoc repo."""
|
|
if shutil.which("make") is None:
|
|
raise RuntimeError("`make` not found on PATH")
|
|
if not os.path.isdir(havoc_dir):
|
|
raise NotADirectoryError(f"Havoc dir not found: {havoc_dir}")
|
|
print(f"[*] running: make {target} (cwd={havoc_dir})")
|
|
return subprocess.call(["make", target], cwd=havoc_dir)
|
|
|
|
|
|
def launch_server(havoc_bin, profile, verbose, debug):
|
|
"""Launch the Havoc team server with the documented flags."""
|
|
if not os.path.isfile(havoc_bin):
|
|
raise FileNotFoundError(f"havoc binary not found: {havoc_bin}")
|
|
if not validate_profile(profile):
|
|
print("[!] profile failed validation; aborting launch")
|
|
return 2
|
|
cmd = [havoc_bin, "server", "--profile", profile]
|
|
if verbose:
|
|
cmd.append("--verbose")
|
|
if debug:
|
|
cmd.append("--debug")
|
|
print(f"[*] launching: {' '.join(cmd)}")
|
|
try:
|
|
return subprocess.call(cmd)
|
|
except KeyboardInterrupt:
|
|
print("\n[*] team server interrupted by operator")
|
|
return 0
|
|
|
|
|
|
def build_parser():
|
|
p = argparse.ArgumentParser(description="Havoc C2 operator helper.")
|
|
sub = p.add_subparsers(dest="action", required=True)
|
|
|
|
v = sub.add_parser("validate", help="validate a Yaotl profile")
|
|
v.add_argument("profile")
|
|
|
|
s = sub.add_parser("scaffold", help="write a starter Yaotl profile")
|
|
s.add_argument("profile")
|
|
s.add_argument("--host", default="0.0.0.0", help="team server bind host")
|
|
s.add_argument("--listener-host", default="c2.example.com",
|
|
help="Demon callback host")
|
|
s.add_argument("--port", type=int, default=443, help="listener port")
|
|
|
|
b = sub.add_parser("build", help="run make ts-build / client-build")
|
|
b.add_argument("--dir", default=".", help="path to cloned Havoc repo")
|
|
b.add_argument("--target", choices=["ts-build", "client-build"],
|
|
default="ts-build")
|
|
|
|
r = sub.add_parser("serve", help="launch the team server")
|
|
r.add_argument("--bin", default="./havoc", help="path to havoc binary")
|
|
r.add_argument("--profile", required=True, help="Yaotl profile path")
|
|
r.add_argument("--verbose", action="store_true")
|
|
r.add_argument("--debug", action="store_true")
|
|
|
|
return p
|
|
|
|
|
|
def main():
|
|
args = build_parser().parse_args()
|
|
try:
|
|
if args.action == "validate":
|
|
sys.exit(0 if validate_profile(args.profile) else 1)
|
|
elif args.action == "scaffold":
|
|
scaffold_profile(args.profile, args.host, args.listener_host,
|
|
args.port)
|
|
elif args.action == "build":
|
|
sys.exit(run_make(args.dir, args.target))
|
|
elif args.action == "serve":
|
|
sys.exit(launch_server(args.bin, args.profile, args.verbose,
|
|
args.debug))
|
|
except (FileNotFoundError, FileExistsError, NotADirectoryError,
|
|
RuntimeError) as exc:
|
|
sys.stderr.write(f"[!] {exc}\n")
|
|
sys.exit(2)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|