Skip to main content
  1. Blog/

From RCE on a controller to domain admin

·3 mins·

Today, we’ll share another instructive story from our pentesting practice.

Once, on a project, we created a task for ourselves: we had RCE as SYSTEM on a domain controller, but we didn’t want to create new accounts or add existing ones to the domain administrators. And we needed to get admin privileges. We came up with several solutions, and although not all of them worked, it was an interesting experience.

Task conditions:

— We have execution on a domain host as SYSTEM and the NT hash of the password of this host.

— We have domain administrator privileges in the root domain in another AD forest (two-way trust).

— We have RCE on a domain controller (vulnerability in Veritas Backup Exec Agent). It’s not very convenient to execute commands (no output), but we can read and write files, and writing through the exploit is very slow.

— We have the ability to connect via SSH to a Linux host (without root).

— The goal is to make as few changes as possible and minimize the need for cleanup for the customer.

Solution options:

1. Run Mythic agent

— from SYSVOL on the domain controller in another forest. Result: Access Denied error.

— load the file with the Mythic agent through the exploit. Result: we were able to run it, but the firewall rules didn’t allow us to establish either bind or reverse connection.

2. Get a certificate

— export a certificate with a private key from the storage (using the Get-ChildItem -Path Cert:\CurrentUser\My\ cmdlet to get the list and Export-PfxCertificate to export). Result: there were no certificates that allowed exporting the private key.

— request a new certificate. Result: we analyzed the certificate templates and didn’t find one that would allow the controller to request a certificate, use it for authentication, and export the private key.

3. Unconstrained delegation

Since we already had domain administrator privileges in another forest, and the domain controllers had unconstrained delegation enabled, we could have tried. But the trustAttributes didn’t have the flag that allows delegation. So, we didn’t even try.

4. Read the LAPS password

Some computer accounts had many privileges (e.g., Exchange servers or certification centers), and getting admin privileges on these hosts could have helped us move forward. But the modules with the Get-LapsADPassword and Get-AdmPwdPassword cmdlets were not installed.

5. Relays

This was rather an abstract idea. There were no Linux hosts with root, and we didn’t want to free up port 445 on the domain host. And the WebClient service for coercing to another port on the controller was not installed. Additionally, LDAP required signing, and there were no certificate templates that fit the ESC8 requirements.

6. Save credentials from the registry

Using reg save or Silent Harvester, we could have obtained credentials from the registry. We would have gotten the NT hash of the domain controller and could have done DCSync. But we would have had to save the files to SYSVOL to access them with the available account.

7. Resource-based Constrained Delegation

Since we had a compromised host account (its NT hash), we were able to conduct an attack on resource-based constrained delegation. First, modify the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of the controller’s account:

Set-ADComputer -Identity DC_Name -Properties PrincipalsAllowedToDelegateToAccount owned$

And then generate a TGS with impersonation of the domain administrator account or another domain controller. Result: success!

8. Rubeus and others

We could have uploaded Rubeus or other utilities for dumping Kerberos tickets to the controller, but after checking idea (1), we realized that uploading a file would not be easy.

Moral:

Even a very simple (at first glance) task “from RCE on a controller to domain admin” can have many solutions if you don’t go down the first path that comes to mind.

Related