# GPOs

A Group Policy Object (GPO) is a collection of policy settings defining the appearance and behavior of systems for a specific group of users or computers within an organization. Instead of configuring each computer individually, administrators use the Group Policy Management Console (GPMC) which enables the centralization of these configurations and their application based on specific computer or user attributes.

For instance, through GPMC, administrators can modify desktop backgrounds, set specific security settings, and apply configurations typically done manually on each Windows machine. Group Policy Objects (GPOs) facilitate this centralized management.

GPOs consist of two main components that facilitate their implementation:

* `Group Policy Container (GPC)`: This LDAP object represents the GPO itself, including its configuration and permissions settings. The GPC's distinguished name contains a `GUID`, which is unique to the GPO and helps identify it within the directory, for example, `CN={GUID},CN=Policies,CN=System,DC=inlanefreight,DC=local`.
* `Group Policy Template (GPT)`: Unlike the GPC that holds configuration metadata, the GPT contains the actual settings and configurations as files within the SYSVOL directory on a domain controller. These files dictate the policies to be applied and are fetched by the client machines. The path typically looks like `\\dc02.inlanefreight.local\SysVol\inlanefreight.local\Policies\{GUID}`.

GPOs are applied to users and computers in an Active Directory environment, mostly through Organizational Units (OUs). Administrators structure the organization into different OUs to tailor specific policies for defined groups of users or machines. For example, consider an administrator in a retail company: they might set up one OU for point-of-sale (POS) systems and others for departments such as HR, IT, C-level, etc. This structure allows the application of targeted policies that meet the specific needs of each group.

#### GPO Delegation

To delegate permissions to link GPOs to a site, domain, or OU, you must have `Modify Permissions` on that site, domain, or OU. By default, only `Domain Administrators` and `Enterprise Administrators` have this permission. Administrators often delegate those rights to other departments, such as technical support, so they can apply the required policies to the computers they manage. Administrators can do that by specifying which GPO a specified group can modify.

If we are the Administrator and we want to delegate rights for a GPO, we need to open `Group Policy Management` using the command `gpmc.msc`; within the GPMC, we can navigate to the selected GPO `Default Security Policy - WKS` go into the `Delegation` tab and Add the group or account we want to assigns the rights to `Edit settings` or `Edit settings, delete and modify security`.

From a high-level perspective, here's what any of those rights can do:

* `Edit settings` allows the user or group to modify the GPO properties or settings.
* `Edit settings, delete and modify security` allows the modification of the GPO settings, the elimination of the GPO, and the delegation of other users to manage the GPO.

#### GPO Links

A GPO is essentially a set of rules we've put together to manage computer and user accounts effectively. However, creating a GPO doesn't automatically apply it. It exists in isolation until we link it to parts of our Active Directory (AD) structure, such as sites, domains, or Organizational Units (OUs). This linking activates the GPO's rules for the users and computers in those containers.

We begin by deciding where these policies should apply. If we have settings that should affect the entire network, we link the GPO to the `domain level`. For more specific settings, like those affecting only the marketing department or a regional office, we'd link the GPO to the respective `OU` or `site`. This flexibility allows us to apply the same policies across different areas of our organization without recreating the GPO multiple times.

It is essential to understand the order in which GPOs are processed, especially when multiple GPOs are linked to the same AD container. If there's a conflict between policies (for example, one GPO disables a setting while another enables it), the GPO processed last will have precedence. This order is determined first by the `location` (Local, Site, Domain, OU) and within those levels by `Link Order`, which specifies the hierarchy of GPO applications at each level.

We can link GPOs to Sites, Domains, or OUs. When we link a GPO, it follows a specific sequence, ensuring that policies applied closer to the user or computer have the highest priority. Here's the order on which GPOs are applied:

* Local
* [Site](../forest-trust-abuse/intra-forest-attacks/gpo-on-site-attack)
* Domain
* Organization Units (OUs)

Additionally, if we have multiple GPOs applied to the sites, Domains, or OUs, those GPOs have a `Link Order`, meaning that at each level, we can specify the order of hierarchy in which each policy will be applied.

For example this is the order in which different GPOs would be enumerated in

* `Local GPO Application`: The computer first applies the Local GPO as it starts up. According to our setup, this GPO enables the Windows Firewall.
* `Site GPO Application`: Next, if there are any GPOs linked to the site that encompass this computer, those GPOs are applied. Site-linked GPOs can modify settings applied by the Local GPO.
* `Domain GPO Application`: After site-linked GPOs, any GPOs linked to the domain and encompassing this computer are applied. These also can override settings from both the Local and Site-linked GPOs.
* `OU GPO Application`: The GPOs linked to the OU are applied. In our scenario, this GPO disables the Windows Firewall. Since OU-linked GPOs are processed last (among the GPOs from Local, Site, and Domain), they have the highest precedence in this context unless a higher-level GPO is enforced.

#### GPO Enumeration

When working with GPOs, we need to be aware of their names, the OUs (the common location to link GPOs), where they are linked, and the DACL associated with them.

As an attacker, when we are targetting GPOs, we want to enumerate four (4) specific things:

* Which nonadmin users can modify GPOs? We do this to filter the GPO we want to attack and the accounts we want to target
* Where are those GPOs linked? As we learned, a GPO is applied when linked; we need to understand where the GPO is linked to identify which devices we can compromise using those GPOs
* Which nonadmin users can link GPOs? We are interested in understanding where we can apply GPOs we have control over by searching if we have rights to link to a Site, Domain, or OU
* Which nonadmin users can create GPOs

To get the GPOs in the domain we can use `Get-DomainGPO` - on linux we use [GPOwned](https://github.com/X-C3LL/GPOwned) or [pywerview](https://github.com/the-useless-one/pywerview)

```powershell
Import-Module .\PowerView.ps1
Get-DomainGPO
```

```
python3 GPOwned.py -u otter -p 'SomethingSecure123!' -d domain.com -dc-ip 10.10.10.10 -gpcmachine -listgpo
```

This returns different attributes

| Property       | Description                                                                                                                                                                                                   |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| displayname    | The name displayed for the GPO in tools like the Group Policy Management Console (GPMC). This is the name that administrators use to identify the GPO in the domain.                                          |
| name           | The unique identifier (ID) for the GPO, which is typically a GUID. This ID is used internally by Active Directory and GPMC to identify the GPO uniquely.                                                      |
| gpcfilesyspath | The file system path to the folder that contains the GPO's data within the SYSVOL share on the domain controllers. This path is critical for the replication of GPO data across the domain.                   |
| objectguid     | A globally unique identifier assigned to the GPO used across the Active Directory to uniquely reference the GPO. This GUID is crucial for applications and services that interact programmatically with GPOs. |

and we can filter for them

```powershell
Get-DomainGPO -Properties displayname
```

To understand where those GPOs are linked we query for the `gplink` attribute

```powershell
Get-DomainObject -SearchScope Base -Properties gplink
```

```
python3 GPOwned.py -u otter -p 'SomethingSecure123!' -d domain.com -dc-ip 10.10.10.10 -gpcmachine -listgplink
```

The output gives us an LDAP path that has the `GUID` of `Default Domain Policy`, which indicates that this GPO is linked to the domain level. The GPO's location within Active Directory objects is the `cn=policies,cn=system,DC=inlanefreight,DC=local`. The number following the semicolon represents the link options. The options determine how the GPO is applied based on the state of this link. Here are possible values and their meanings:

* 0 - The GPO is enabled
* 1 - The GPO is disabled
* 2 - The GPO link is enforced
* 3 - The GPO link is enforced, but the GPO is disabled

To enumerate which users have the right to modify this GPO we query for the ACL of each GPO and convert the returned SID

```powershell
Get-DomainGPO | Select-Object -First 1 | Get-DomainObjectAcl -ResolveGUIDs | where { $_.ActiveDirectoryRights -match "CreateChild|WriteProperty|DeleteChild|DeleteTree|WriteDacl|WriteOwner" -and $_.SecurityIdentifier -match '^S-1-5-.*-[1-9]\d{3,}$' }

ConvertFrom-SID <SID>
Get-DomainGroupMember "Group" | select MemberName
```

```
# search for all the GUIDs
python3 GPOwned.py -u otter -p 'SomethingSecure123!' -d domain.com -dc-ip 10.10.10.10 -gpcmachine -listgpo | grep " Name:"
# identify the rights over the GPOs
dacledit.py domain.com/otter:'SomethingSecure123!' -target-dn "CN={<GUID>},CN=Policies,CN=System,DC=domain,DC=com" -dc-ip 10.10.10.10
```

We can apply the same logic to search for `gplink` attribute in the Sites and OUs. To search for `gplink` in the Site we can use `Get-DomainSite`

```powershell
Get-DomainSite -Properties gplink
Get-DomainOU | select name, gplink
```

Based on the OU information, we can query which computers are located within those OU with the following PowerView command

```powershell
Get-DomainOU | foreach { $ou = $_.distinguishedname; Get-DomainComputer -SearchBase $ou -Properties dnshostname | select @{Name='OU';Expression={$ou}}, @{Name='FQDN';Expression={$_.dnshostname}} }
```

#### Create and Link GPOs

Once we enumerate the GPOs, we need to identify who can create GPOs and who can link GPOs to Sites, Domains, or OUs.

To identify which users can create GPOs, we need to enumerate the location where GPOs are stored in the domain, which is `CN=Policies,CN=System,DC=domain,DC=com`. Any user or group that has `Create groupPolicyContainer objects` will be able to create new GPOs. We can use the Get-DomainGPO to extract the distinguishedname of location where GPOs are stored and use Get-DomainObjectAcl to search for `CreatedChild` rights. Finally, we convert the SID to their corresponding principal name.

```powershell
$identity = (Get-DomainGPO).distinguishedname -replace 'CN=\{[A-F0-9-]+\},',''; Get-DomainObjectACL -Identity $identity -ResolveGUIDs | where { $_.ActiveDirectoryRights -contains "CreateChild" -and $_.SecurityIdentifier -match '^S-1-5-.*-[1-9]\d{3,}$' } | foreach { ConvertFrom-SID $_.SecurityIdentifier }
```

To create a new GPO, we can use the Windows module [GroupPolicy](https://learn.microsoft.com/en-us/powershell/module/grouppolicy/?view=windowsserver2022-ps), which is part of the [Remote Server Administration Tools (RSAT) for Windows](https://learn.microsoft.com/en-us/troubleshoot/windows-server/system-management-components/remote-server-administration-tools) commonly found on servers. Alternatively, we can use [PowerGPOAbuse](https://github.com/rootSySdk/PowerGPOAbuse).

```powershell
New-GPO -Name TestGPO -Comment "Just testing"
```

GPOs can be linked to three (3) different locations: sites, Domains, and OUs and we can enumerate which users have rights to link a GPO

```powershell
Get-DomainSite -Properties distinguishedname | foreach { Get-DomainObjectAcl -SearchBase $_.distinguishedname -ResolveGUIDs | where { $_.ObjectAceType -eq "GP-Link" -and $_.ActiveDirectoryRights -match "WriteProperty" } | select ObjectDN, @{Name='ResolvedSID';Expression={ConvertFrom-SID $_.SecurityIdentifier}} | Format-List }

Get-DomainObjectAcl -SearchScope Base -ResolveGUIDs | where { $_.ObjectAceType -eq "GP-Link" -and $_.ActiveDirectoryRights -match "WriteProperty" } | select ObjectDN, @{Name='ResolvedSID';Expression={ConvertFrom-SID $_.SecurityIdentifier}} | Format-List

Get-DomainOU | Get-DomainObjectAcl -ResolveGUIDs | where { $_.ObjectAceType -eq "GP-Link" -and $_.ActiveDirectoryRights -match "WriteProperty" } | select ObjectDN, @{Name='ResolvedSID';Expression={ConvertFrom-SID $_.SecurityIdentifier}} | Format-List
```

Aditionally we can use the tool [Get-GPOEnumeration](https://github.com/juliourena/plaintext/blob/master/Powershell/Get-GPOEnumeration.ps1)

```powershell
Import-Module .\Get-GPOEnumeration.ps1
Get-GPOEnumeration
```

To link a GPO, we can use the GroupPolicy module and use the command [New-GPLink](https://learn.microsoft.com/en-us/powershell/module/grouppolicy/new-gplink)

```powershell
New-GPLink -Name TestGPO -Target "OU=TestOU,DC=domain,DC=com"
```

To look at how we abuse GPOs check out [GPO Attacks](../dacl-abuse/gpo-attacks).
