Evil-WinRM: a Ruby PSRP shell for WinRM post-exploitation
The ultimate WinRM shell for hacking/pentesting
At a glance
- What is it?
- Evil-WinRM wraps the WinRM Ruby library and PSRP into an interactive shell aimed at pentesters who already hold Windows credentials. It ships as a gem, a git checkout or a Docker image, and its whole value sits in the features it layers on top of the protocol.
- Who is it for?
- Adopt Evil-WinRM if you are doing authorised Windows post-exploitation and already have credentials, a hash or a Kerberos ticket, and you want in-memory script, DLL and assembly loading plus file transfer in one shell. Do not adopt it if you need a programmatic WinRM client inside your own code, or if you have no valid credentials at all: the README states plainly that it only works if you have credentials and permissions.
- Can I use it commercially?
- Yes, with conditions. LGPL-3.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 26 days ago.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Evil-WinRM is for, and who it is actually aimed at
WinRM is Microsoft's implementation of the WS-Management protocol, a SOAP-based standard that the README describes as having been included in Windows so that system administrators have an easier life. Evil-WinRM is a client for that service, written in Ruby, and its stated purpose is to be a WinRM shell for hacking and pentesting. The README is honest about the phase it belongs to: it says the program can be used on any Windows Server with the feature enabled, usually on port 5985, only if you have credentials and permissions, which places it in post-exploitation.
The audience follows from that. A pentester who has already obtained a password, an NTLM hash or a Kerberos ticket uses it to get an interactive session and then load tooling into memory. System administrators can use it for legitimate purposes, and the README says so, but it also says most of the features are focused on hacking and pentesting. That is not false modesty. Pass-the-hash, in-memory DLL loading and AMSI bypass are not administration features. If you want a general-purpose remote management client, the extra surface here is cost with no benefit.
PSRP instead of raw WinRM: what changed under the shell
The README states that the project is based mainly on the WinRM Ruby library, and that this library changed how it works from version 2.0 onward. Instead of speaking the WinRM protocol directly, it now uses PSRP, the PowerShell Remoting Protocol, to initialise runspace pools and to create and process pipelines. That distinction matters when you are debugging. The shell you get is a PowerShell remoting session, not a sequence of WS-Management calls, so the behaviour you observe is PowerShell's behaviour: runspaces, pipelines and their output streams.
The dependencies listed in the README line up with that architecture. Ruby 2.3 or higher is required, along with the gems winrm (at least 2.3.7), winrm-fs (at least 1.3.2), stringio, logger, fileutils, readline and readline-ext. winrm-fs is the piece responsible for file transfer over the same stack. The readline-ext binding is what powers remote path completion, and the README notes that some systems need extra development packages to compile it.
The command-line surface reflects the same design. The help output exposes separate flags for a local PowerShell scripts path (-s), a local executables path (-e), a public key (-c) and private key (-k), a realm for Kerberos (-r), a ticket file (-K), an SPN prefix (--spn, default HTTP), a custom user-agent (-a, default "Microsoft WinRM Client"), and toggles for colours, remote path completion and logging. The default port is 5985 and the default endpoint URL is /wsman.
Installing Evil-WinRM and running a first session
The README documents four installation methods. The gem route is the shortest: it installs the dependencies automatically.
gem install evil-winrmAfter that the executable is on your PATH. A first session against a host where WinRM is enabled takes an IP, a username and a password, and optionally points at local directories holding your PowerShell scripts and C# executables:
evil-winrm -i 192.168.1.100 -u Administrator -p 'MySuperSecr3tPass123!' -s '/home/foo/ps1_scripts/' -e '/home/foo/exe_files/'If you prefer to keep the gems off your system, the bundler route clones the repository and vendors the dependencies:
gem install bundler
git clone https://github.com/Hackplayers/evil-winrm.git
cd evil-winrm && bundle install --path vendor/bundle
bundle exec evil-winrm.rb -i 192.168.1.100 -u Administrator -p 'MySuperSecr3tPass123!' -s '/home/foo/ps1_scripts/' -e '/home/foo/exe_files/'The README also documents a manual clone with `sudo gem install winrm winrm-fs stringio logger fileutils readline readline-ext` followed by `ruby evil-winrm.rb`, and a Docker method with prebuilt images on Docker Hub. The Dockerfile in the repository builds Ruby 4.0.1 from source inside an Alpine base using ruby-install, which tells you the image is not a thin wrapper around a system Ruby. Once connected, the interactive prompt gives you command history, WinRM command completion and local and remote path completion, all of which the README lists as features rather than defaults you have to configure.
The feature list is the real product, and it is Windows-specific
Strip away the shell and what remains is a set of capabilities that the README enumerates. It can load PowerShell scripts in memory, load DLL files in memory, load C# assemblies in memory, and load x64 payloads generated with the donut technique. It has a dynamic AMSI bypass and an ETW bypass. It supports pass-the-hash, Kerberos authentication including ccache and kirbi files, and SSL with certificates. File upload and download show a progress bar. It can list remote machine services without privileges. There is an optional logging flag, a trap that captures Ctrl+C so you do not exit the shell by accident, and a customisable user-agent that defaults to a legitimate Windows one.
Every one of those features assumes a Windows target with WinRM reachable. The README frames the whole tool around "any Microsoft Windows Servers with this feature enabled". So the honest limitation is structural, not a bug: if WinRM is disabled, firewalled off, or the account you hold cannot authenticate to it, none of this helps. The README also says the tool is used only if you have credentials and permissions, which rules out the unauthenticated case entirely. It is a post-exploitation client, and treating it as anything else will waste your time.
A second constraint is environmental. The Kerberos path needs the Kerberos package installed on your own machine, named krb5-user on Debian-based distributions such as Kali and Parrot, krb5 on BlackArch, and possibly something else elsewhere, and the realm has to be set in /etc/krb5.conf. Remote path completion needs the native readline-ext binding and may need development packages to compile. Those are the two places where a working install most often is not.
Where Evil-WinRM is the wrong tool
If you are writing software rather than running an engagement, Evil-WinRM is the wrong layer. It is an interactive shell with a command-line interface, not a library you call from your own code. The README presents it as a program you launch, with a usage block and four ways to install it, and nothing in the README describes an API for embedding. If you need WinRM calls inside an application, you want the underlying winrm Ruby library or an equivalent client in your own language, and you should expect to implement the in-memory loading, AMSI bypass and ticket handling yourself.
The same applies if you want a graphical or cross-platform management console. Evil-WinRM is terminal software. It is compatible with Linux and Windows client systems according to the README, but its interaction model is a prompt, a history buffer and completion, not a UI.
There is also a licensing boundary worth naming. The project is LGPL-3.0. That is a copyleft licence with a linking exception, and what it means for you depends on whether you redistribute the tool, bundle it into an image you ship, or merely run it during an engagement. The repository ships a LICENSE file; read it rather than assuming. Nothing here is legal advice, and the practical answer differs between running it and shipping it.
Evil-WinRM compared with a plain WinRM client
The clearest alternative is the winrm Ruby library that Evil-WinRM itself builds on. The difference is not protocol support. Both speak to the same service, and since the library moved to PSRP the underlying mechanics are the same. The difference is everything layered on top: the interactive readline prompt, command history, local and remote path completion, colourised output, session logging, progress-bar file transfer, in-memory script, DLL and assembly loading, the donut payload path, AMSI and ETW bypasses, pass-the-hash, and Kerberos ticket handling for ccache and kirbi files.
If you use the library directly you get a programming interface and none of that. You would write your own file transfer, your own script loading, and your own handling of hashes and tickets. That is a reasonable choice when you are automating at scale or embedding WinRM in a larger tool. It is a poor choice when you are on an engagement and want a shell in thirty seconds.
The reverse trade-off is that Evil-WinRM's convenience is opinionated. Its defaults, such as the "Microsoft WinRM Client" user-agent and the /wsman endpoint, exist because they look like normal traffic. If your environment requires a different user-agent, the -a flag is there. If your endpoint differs, -U changes it. The tool is flexible about those details without becoming a general framework, and that is the right scope for what it does.
Maintenance, releases and upgrade cost
The repository is not archived. The last push was on 2026-09-04. The most recent release is v4.1, dated 2026-09-03, preceded by v3.9 and v3.8 in December 2025. That cadence suggests the project still receives changes, though the README does not describe a support policy or a deprecation process.
Upgrade cost is mostly a Ruby dependency question. The README pins minimum versions for winrm, winrm-fs, stringio, logger, fileutils and readline, and readline-ext is a native binding that must compile on your system. A gem install will pull those in automatically, but a manually managed install, or a distribution package that freezes Ruby, can leave you resolving conflicts by hand. The Dockerfile avoids that problem by building Ruby 4.0.1 from source in an Alpine image, which is heavier and slower to build but removes the host from the equation.
On licensing, LGPL-3.0 governs the project. If you distribute a modified version, or ship an image containing it, the licence terms apply to that distribution. If you only run it locally, the practical impact is smaller. The repository includes a LICENSE file and a CONTRIBUTING.md; the README does not discuss relicensing, commercial support or an exception for embedding.
Editorial conclusion
Adopt Evil-WinRM if you are doing authorised Windows post-exploitation and already have credentials, a hash or a Kerberos ticket, and you want in-memory script, DLL and assembly loading plus file transfer in one shell. Do not adopt it if you need a programmatic WinRM client inside your own code, or if you have no valid credentials at all: the README states plainly that it only works if you have credentials and permissions. Before relying on it, verify that Ruby 2.3 or higher is present, that the winrm and winrm-fs gems resolve on your system, and that the remote host actually exposes WinRM, usually on port 5985. Confirm your readline-ext build works if you want remote path completion, and check the LGPL-3.0 terms against how you intend to redistribute the tool.
Frequently asked questions
Does Evil-WinRM work on Linux?
Yes. The README lists compatibility with Linux and Windows client systems as a feature, and the installation methods are gem, git clone, bundler and Docker. Kerberos authentication additionally requires the Kerberos package on your own machine, named krb5-user on Debian-based distributions and krb5 on BlackArch.
Which port does Evil-WinRM use by default?
The help output shows -P, --port with a default of 5985, and the README says WinRM is usually enabled at port 5985 on Windows Servers. The default remote URL endpoint is /wsman, changeable with -U.
Does Evil-WinRM support pass-the-hash?
Yes, pass-the-hash support is listed among the features, and the usage block exposes it as -H, --hash for an NTHash. Kerberos authentication is also supported, including ccache and kirbi ticket files via -K.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/hackplayers-evil-winrm)