Another day, another Domain Admin

8 min read Original article ↗

Daniel Knight

Daniel Knight, CEO at Vulnetic

With a new State of the Art (SOTA) model coming out every couple of months, hacking ability is improving. Our hacking agent has taken an affinity to Active Directory, and privilege escalation as a whole. We quickly added the capability to use Responder, and the model shows promise both forcing coercion and checking Responder logs for caught hashes and using that as a push off point to further exploit AD networks.

Fast forward to January, we are now suddenly trying to find what our hacking agent can't do.

Responder as the first foothold

The agent runs a few null user NetExec commands before checking /opt/responder/logs and noticing an NTLMv2 capture file for WIN11$. The agent then extracts the hash, sends it to Hashcat, which returns Password1 for user1.

Press enter or click to view image in full size

Our hacking agent is built to periodically check and utilize Responder during AD pentests

Press enter or click to view image in full size

Cracked hash for user1

Press enter or click to view image in full size

Agent checking permissions after cracking the hash

The agent validates user1:Password1 against DC1 and WIN11$, confirms it’s a working domain user, and then tests the same password against service accounts. Both svc_web and svc_sql accept Password1 as well. Three accounts, one reused password, and enough access to start doing real damage.

Sidetracked

The agent did take a detour and discovered that it could perform a forced coercion on DC1, but the machine account password was too complex to crack.

Press enter or click to view image in full size

Forced Coercion

Press enter or click to view image in full size

DC1 machine hash

Just like any human, our hacking agent is not immune to distractions.

MachineAccountQuota and RBCD to local admin

The first move is the MachineAccountQuota and RBCD chain.

The agent queries the domain root and reads ms-DS-MachineAccountQuota. It sees the default value, ten, which means any authenticated user can create up to ten computer accounts.

Press enter or click to view image in full size

With user1, it calls impacket-addcomputer to create a new machine account, ATTACK01$, with a password it controls. There is now an attacker-owned computer object in AD.

Next it pivots to the WIN11$ computer object. Using bloodyAD, it fetches the security descriptor and eventually succeeds in updating msDS-AllowedToActOnBehalfOfOtherIdentity so that ATTACK01$ is allowed to act on behalf of other users to WIN11$. That is textbook resource-based constrained delegation: the target machine now trusts the attacker-controlled machine to impersonate users to it.

Setting RBCD on WIN11$ so ATTACK01$ can impersonate via S4U2Proxy

With that in place, the agent asks the KDC for a ticket as Administrator to cifs/win11.vulnetic.localusing S4U2Self and S4U2Proxy.

Press enter or click to view image in full size

Getting an S4U ticket as Administrator to CIFS on WIN11$

Press enter or click to view image in full size

Listing SMB permissions as Administrator on WIN11$

The resulting ccache is written to disk. The agent exportsKRB5CCNAMEto point at it, runs NetExec against WIN11$ with-k --use-kcache, and executes whoami. The output comes back as vulnetic\administrator.

Press enter or click to view image in full size

Proving Administrative access on WIN11$

All of that started from a single user password captured by Responder. The agent figured out that it could create a machine, configure RBCD, and then use S4U to land as local Administrator on WIN11$ without ever knowing the Administrator password.

LSA secrets and the WIN11$ pivot into the DC

After taking local Administrator on WIN11$, the agent immediately goes after LSA secrets.

Using its Kerberos ticket as Administrator, it runs the LSA dump module and pulls back DPAPI keys, cached credentials, and the NT hash for the machine account WIN11$. That hash is the workstation’s identity in the domain.

Press enter or click to view image in full size

The agent then tries to reuse that machine-account hash against DC1. It authenticates as vulnetic\WIN11$ over SMB and confirms access.

Press enter or click to view image in full size

That alone is a useful pivot: the compromised workstation has just become a valid principal on the domain controller.

Get Daniel Knight’s stories in your inbox

Join Medium for free to get updates from this writer.

Remember me for faster sign in

It even attempts to run secretsdump.py against DC1 with WIN11$ to test whether it can perform DCSync. As expected in a sane domain, that fails with an access error.

Press enter or click to view image in full size

Failed secretsdump.py

The important part is that the model understood the possibility. It chained local admin on WIN11$ into “dump LSA,” turned that into “use the machine account against the DC,” and then checked whether that principal had replication rights.

Path to DA

First thing, the agent validates that svc_web can abuse RBCD directly on DC1 by creating yet another attacker-controlled machine account and delegating it to the DC:

Press enter or click to view image in full size

Failing attempts with bloodyAD set get INSUFF_ACCESS_RIGHTS, so the agent switches to rbcd.py to set RBCD on DC1 for ATTACK03$:

Press enter or click to view image in full size

Then it uses S4U to impersonate Administrator to CIFS on DC1 and drops the ccache:

Press enter or click to view image in full size

The agent then points KRB5CCNAME at the new ccache and hits DC1 over SMB with NetExec.

Press enter or click to view image in full size

The controller answers back as vulnetic\Administrator and lists out ADMIN$, C$, NETLOGON, SYSVOL and the rest.

Press enter or click to view image in full size

At this point there is no ambiguity: the model has turned a service account and a fake computer into real Domain Admin on the domain controller.

From there, it asks for secrets. The output includes the RID 500 Administrator account, its NT hash, and the associated Kerberos keys.

Press enter or click to view image in full size

Once it knows this works, it goes for the full dump. Instead of limiting itself to one user, the agent turns back to NetExec and runs the NTDS module against DC1 using the same Administrator ticket.

Press enter or click to view image in full size

Administrator, Guest, krbtgt and all of the other accounts are there, with the krbtgt NT hash sitting in plain text. At this point, “Domain Admin” has gone from an active session to complete directory disclosure. Every password hash in the forest is now in scope.

Golden Ticket from krbt

With krbtgt in hand, the agent pivots from compromise to persistence. It pulls the krbtgt hash out of the NTDS file, combines it with the domain SID, and feeds both into a Golden Ticket tool. The configuration is simple: domain vulnetic.local, the domain SID it already recovered from LDAP earlier, the krbtgt hash from the NTDS dump, and user-id 500 so the forged ticket will represent Administrator.

Press enter or click to view image in full size

Creation and inspection of ticket

The agent then exports KRB5CCNAME to point at Administrator.ccache and runs klist. The output shows a TGT for Administrator@VULNETIC.LOCAL with a lifetime measured in years, issued by krbtgt/VULNETIC.LOCAL. There is no password involved in this step; the ticket is built entirely from directory data.

To prove that the ticket is not just syntactically valid but accepted by DC1, the agent once again calls NetExec over SMB, this time using only -k — use-kcache. DC1 accepts the Golden Ticket, maps it to Administrator, and returns the same “Pwn3d!” banner and share listing as before. The difference is that this time the agent is not relying on any live username and password; it is authenticating with a forged TGT signed by the krbtgt key it stole from NTDS.

Press enter or click to view image in full size

From here, the distinction between “initial compromise” and “persistence” blurs. As long as the krbtgt key remains unchanged, the agent can mint fresh Administrator tickets at will, return to the domain controller whenever it wants, and re-run any of these steps without touching a real credential again.

Not noted in this writeup, the agent also performed a Silver Ticket attack against WIN11$and a Shadow Credentials attack. The agent also enumerated permissions using Bloodhound JSON data in Event 1, and circled back to it in Event 5, which layed the ground work for its understanding of the network:

Press enter or click to view image in full size

Initial Bloodhound command ran during initial recon after cracking NTLMv2 hash for user1

Press enter or click to view image in full size

The agent using jq to search for permissions in raw Bloodhound JSON

Why this matters

On paper, none of these techniques are new. People have been abusing MachineAccountQuota, RBCD, LSA secrets, and constrained delegation for years. What is new is that a language model is now doing all of this on its own, starting from a Responder hash, and stitching the pieces together into a coherent chain.

In one short session, the agent used Responder and Hashcat to get a foothold, abused MachineAccountQuota and RBCD to become local Administrator on WIN11$, turned that into a machine-account pivot against the domain controller, correctly identified a constrained-delegation service account that would be a direct route to Domain Admin if its key ever fell, then used svc_web to run a second RBCD chain directly against DC1 to log in as Administrator, dump the entire NTDS database (including krbtgt), and mint a long-lived Golden Ticket for persistent control of the domain.

The proposition going forward is simple: if you aren't using these LLMs for hacking, you will be left behind when the adversaries do.

Try our hacking agent for free here

View our website here