Security Considerations for PowerShell Remoting using WinRM
PowerShell Remoting is the recommended way to manage Windows systems. PowerShell Remoting is enabled by default in Windows Server 2012 R2 and higher. This document covers security concerns, recommendations, and best practices when using PowerShell Remoting.
What is PowerShell Remoting?
PowerShell Remoting uses Windows Remote Management (WinRM) to allow users to run PowerShell commands on remote computers. WinRM is the Microsoft implementation of the Web Services for Management (WS-Management) protocol. You can find more information about using PowerShell Remoting at Running Remote Commands.
PowerShell Remoting isn't the same as using the ComputerName parameter of a cmdlet to run it on a remote computer, which uses Remote Procedure Call (RPC) as its underlying protocol.
PowerShell Remoting default settings
PowerShell Remoting (and WinRM) listen on the following ports:
- HTTP: 5985
- HTTPS: 5986
By default, PowerShell Remoting only allows connections from members of the Administrators group. Sessions are launched under the user's context, so all operating system access controls applied to individual users and groups continue to apply to them while connected over PowerShell Remoting.
On private networks, the default Windows Firewall rule for PowerShell Remoting accepts all connections. On public networks, the default Windows Firewall rule allows PowerShell Remoting connections only from within the same subnet. You have to explicitly change that rule to open PowerShell Remoting to all connections on a public network.
Warning
The firewall rule for public networks is meant to protect the computer from potentially malicious external connection attempts. Use caution when removing this rule.
Process isolation
PowerShell Remoting uses WinRM for communication between computers. WinRM runs as a service under the Network Service account, and spawns isolated processes running as user accounts to host PowerShell instances. An instance of PowerShell running as one user has no access to a process running an instance of PowerShell as another user.
Event logs generated by PowerShell Remoting
FireEye has provided a good summary of the event logs and other security evidence generated by PowerShell Remoting sessions, available at Investigating PowerShell Attacks.
Encryption and transport protocols
It's helpful to consider the security of a PowerShell Remoting connection from two perspectives: initial authentication, and ongoing communication.
Regardless of the transport protocol used (HTTP or HTTPS), WinRM always encrypts all PowerShell remoting communication after initial authentication.
Initial authentication
Authentication confirms the identity of the client to the server - and ideally - the server to the client.
When a client connects to a domain server using its computer name, the default authentication protocol is Kerberos. Kerberos guarantees both the user identity and server identity without sending any sort of reusable credential.
When a client connects to a domain server using its IP address, or connects to a workgroup server, Kerberos authentication isn't possible. In that case, PowerShell Remoting relies on the NTLM authentication protocol. The NTLM authentication protocol guarantees the user identity without sending any sort of delegable credential. To prove user identity, the NTLM protocol requires that both the client and server compute a session key from the user's password without ever exchanging the password itself. The server typically doesn't know the user's password, so it communicates with the domain controller, which does know the user's password and calculates the session key for the server.
The NTLM protocol doesn't, however, guarantee server identity. As with all protocols that use NTLM for authentication, an attacker with access to a domain-joined computer's machine account could invoke the domain controller to compute an NTLM session-key and thereby impersonate the server.
NTLM-based authentication is disabled by default, but may be permitted by either configuring SSL on the target server, or by configuring the WinRM TrustedHosts setting on the client.
Using SSL certificates to validate server identity during NTLM-based connections
Since the NTLM authentication protocol can't ensure the identity of the target server (only that it already knows your password), you can configure target servers to use SSL for PowerShell Remoting. Assigning a SSL certificate to the target server (if issued by a Certificate Authority that the client also trusts) enables NTLM-based authentication that guarantees both the user identity and server identity.
Ignoring NTLM-based server identity errors
If deploying a SSL certificate to a server for NTLM connections is infeasible, you may suppress the resulting identity errors by adding the server to the WinRM TrustedHosts list. Please note that adding a server name to the TrustedHosts list shouldn't be considered as any form of statement of the trustworthiness of the hosts themselves - as the NTLM authentication protocol can't guarantee that you are in fact connecting to the host you are intending to connect to. Instead, you should consider the TrustedHosts setting to be the list of hosts for which you wish to suppress the error generated by being unable to verify the server's identity.
Ongoing Communication
Once initial authentication is complete, the WinRM encrypts the ongoing communication. When connecting over HTTPS, the TLS protocol is used to negotiate the encryption used to transport data. When connecting over HTTP, message-level encryption is determined by initial authentication protocol used.
- Basic authentication provide no encryption.
- NTLM authentication uses an RC4 cipher with a 128-bit key.
- Kerberos authentication encryption is determined by the
etype
in the TGS ticket. This is AES-256 on modern systems. - CredSSP encryption is uses the TLS cipher suite that was negotiated in the handshake.
Making the second hop
By default, PowerShell Remoting uses Kerberos (if available) or NTLM for authentication. Both of these protocols authenticate to the remote machine without sending credentials to it. This is the most secure way to authenticate, but because the remote machine doesn't have the user's credentials, it can't access other computers and services on the user's behalf. This is known as the "second hop problem".
There are several ways to avoid this problem. For descriptions of these methods, and the pros and cons of each, see Making the second hop in PowerShell Remoting.