🛡️ Methodology Checklist

  • RDP detection: nmap -p 3389 --script rdp-enum-encryption [TARGET]
  • RDP brute-force: hydra -L users.txt -P pass.txt rdp://[TARGET]
  • BlueKeep check: nmap --script rdp-vuln-ms12-020 -p 3389 [TARGET]
  • WinRM detection: port 5985 (HTTP) or 5986 (HTTPS)
  • WinRM auth test: evil-winrm -i [TARGET] -u [USER] -p [PASS]
  • WMI via NXC: nxc wmi [TARGET] -u [USER] -p [PASS] --query "SELECT Name FROM Win32_Service"
  • Check for NLA enforcement on RDP target

🎯 Operational Context

Think Dumber First: WinRM (5985) before RDP (3389) — WinRM gives you a full PowerShell session with less logging, easier scripting, and no GUI overhead. Evil-WinRM adds file upload/download, in-memory assembly loading, and pass-the-hash/pass-the-ticket support. WMI is the stealthiest option for lateral movement without a full shell.

When you land here: Port 5985, 5986, 3389, or 47001 open with valid credentials. Try Evil-WinRM first. If WinRM fails, try RDP with xfreerdp. WMI for command execution without a full shell: impacket-wmiexec [DOMAIN]/[USER]:[PASS]@[TARGET].


⚡ Tactical Cheatsheet

CommandTactical Outcome
nmap -sV -sC [TARGET_IP] -p3389 --script rdp*Detect RDP version, OS, hostname, NLA status
nmap -sV -sC [TARGET_IP] -p3389 --packet-trace --disable-arp-ping -nRDP packet trace (detect scan signatures)
./rdp-sec-check.pl [TARGET_IP]Check RDP encryption and protocol settings
sudo cpan install Encoding::BERInstall rdp-sec-check dependency
xfreerdp3 /u:[USER] /p:"[PASS]" /v:[TARGET_IP]Connect to RDP from Linux
nmap -sV -sC [TARGET_IP] -p5985,5986 --disable-arp-ping -nDetect WinRM service
evil-winrm -i [TARGET_IP] -u [USER] -p [PASS]Get interactive PowerShell shell via WinRM
wmiexec.py [USER]:"[PASS]"@[TARGET_IP] "[COMMAND]"Execute command via WMI (Impacket)
/usr/share/doc/python3-impacket/examples/wmiexec.py [USER]:"[PASS]"@[TARGET_IP] "hostname"Full path wmiexec

🔬 Deep Dive & Workflow

Initial Enumeration

  • RDP check: nmap -sV -sC [TARGET_IP] -p3389 --script rdp*
    • Note Product_Version (Windows build), Target_Name (hostname)
    • Check CredSSP (NLA) — if enabled, creds needed before GUI access
  • WinRM check: nmap -sV -sC [TARGET_IP] -p5985,5986
    • Look for Microsoft-HTTPAPI/2.0 on port 5985
  • WMI check: nmap -p135 [TARGET_IP] — DCOM/RPC endpoint
  • Check RDP security: ./rdp-sec-check.pl [TARGET_IP]

Attacks

  • RDP: If NLA off → direct brute-force or attempt BlueKeep (CVE-2019-0708) if unpatched
  • RDP: Connect with found creds: xfreerdp3 /u:[USER] /p:"[PASS]" /v:[TARGET_IP]
  • WinRM: If port 5985 open and creds known → evil-winrm -i [TARGET_IP] -u [USER] -p [PASS]
  • WMI: Stealthier shell: wmiexec.py [USER]:"[PASS]"@[TARGET_IP] "whoami"
  • Self-signed RDP cert → extract hostname from cert for further enumeration

Three Pillars of Windows Remote Management

RDP (Port 3389 TCP/UDP)

  • GUI-based access. Since Vista: TLS/SSL with (often self-signed) certs.
  • NLA (Network Level Authentication): If enabled, full credentials required before GUI rendered.
  • Self-signed cert → reveals hostname during enumeration.

WinRM (Ports 5985 HTTP / 5986 HTTPS)

  • CLI-based — PowerShell Remoting backend. Uses SOAP protocol.
  • Enabled by default on Windows Server 2012+.
  • Port 5985 is preferred attack path → evil-winrm = fully interactive PS shell.

WMI (Port 135 + dynamic high port)

  • Read/write access to system settings.
  • Connection on 135, then dynamic high port.
  • wmiexec.py = stealthier than RDP, generates specific event logs.

Decision Priority (Exam)

  1. Check 3389 (RDP) — NLA status
  2. Check 5985 (WinRM) — best path for stable shell via evil-winrm
  3. Check 135 (WMI) — use wmiexec.py as fallback or for stealth

🛠️ Troubleshooting & Edge Cases

ProblemCauseFix
evil-winrm fails ‘connection refused’WinRM not enabled or port blockedVerify 5985/5986 open; enable remotely via RCE: Enable-PSRemoting -Force; check Windows Firewall status
Kerberos auth fails ‘KRB_AP_ERR_SKEW’Clock skew >5 minutessudo ntpdate [DC_IP]; add --realm [DOMAIN] flag to evil-winrm; set system time manually if ntpdate fails
RDP login screen freezes after credentialsNLA (Network Level Authentication) mismatchAdd /sec:rdp for non-NLA: xfreerdp /v:[TARGET] /u:[USER] /p:[PASS] /sec:rdp /cert:ignore
WMI queries time out consistentlyWMI service not running or namespace wrongCheck Get-Service winmgmt; restart WMI: net stop winmgmt && net start winmgmt; use default namespace root\cimv2
RDP disconnects every few minutesHTB VPN bandwidth saturation or idle timeoutAdd /bpp:16 /compression-level:2 to reduce bandwidth; set /idle-timeout:0 to prevent disconnection

📝 Reporting Trigger

Finding Title: Windows Remote Management (WinRM) Accessible with Valid Credentials Impact: Interactive PowerShell session enabling lateral movement, in-memory tool execution, credential dumping, and persistent access. No additional exploitation required with valid credentials. Root Cause: WinRM enabled on port 5985 without network-level access restrictions. Credentials obtained via prior exploitation (password spray, LSASS dump, etc.). Recommendation: Restrict WinRM listener to authorized management IPs. Implement Just-Enough-Administration (JEA) to limit PowerShell commands available via WinRM. Enable PowerShell logging and script block logging. Disable RDP where not operationally required; enforce NLA.