
Cross-forest Kerberoasting: how a forest trust lets you roast service accounts in a domain you do not belong to
If you have met Kerberoasting you have met it inside a single domain: one credential, request a service ticket for a service account, crack it offline. This post takes that exact idea and walks it across a forest trust, because the surprising part for most learners is that it works at all. You do not need an account in the target forest. You need an account in a forest that the target forest trusts, and a service account on the other side with a weak password. That is the whole premise, and it is the first link of the over-privileged service-account chain that can end in full forest compromise.
What you will learn
- What a forest trust actually shares, and why "authentication flows across it" is the key fact.
- Why requesting a service ticket is not the same as being authorized to use the service, and why that distinction is what makes roasting possible.
- How to perform a cross-forest roast from Kali, step by step, with the two things that trip people up.
- How to stand up a minimal two-forest lab so you can watch it happen on hardware you own.
- The detection signal and the single durable fix.
Prerequisites and scope: you already hold one valid credential in forest A (any user, no privileges) and there is a trust from the target forest B to forest A. Everything here is a protocol property plus a weak password, not a bug, so it closes to a managed password or an SID-filtered trust, not a patch.
The mental model
Think of two office buildings, A and B, that have signed a mutual access agreement (the trust). The agreement says: a badge issued by building A is recognized at building B's front desk. It does not say building A's staff are managers at building B. It only means the front desk will acknowledge the badge and hand over a visitor pass for a specific room if one is requested.
In Kerberos terms, the "visitor pass for a specific room" is a service ticket (a TGS), and the room is a service account identified by its Service Principal Name. The front desk (the target domain controller) will issue that pass to a recognized badge from the trusted forest. Here is the part that matters: the pass is sealed with a key derived from that room's own lock, which is the service account's password. So when the front desk hands you the sealed pass, it has handed you something encrypted with the service account's password, for an account you have no business using. You walk out with it and pick the lock at your leisure, offline, at home.
That is cross-forest Kerberoasting. The trust got you a recognized badge; Kerberos design did the rest.
Why it works: three facts stacked
- A forest trust makes your badge recognizable. When forest B trusts forest A, B's domain controllers will process Kerberos requests from A's principals. The referral machinery routes your request to the right domain and issues the ticket. Authentication crosses the trust by design; that is what a trust is for.
- Issuing a service ticket is not authorization. The domain controller does not check whether you are allowed to use the service before handing you the ticket. Authorization happens later, at the service itself. So a nobody in forest A can request a ticket for a Domain Admin service account in forest B. The DC issues it without objection.
- The ticket is encrypted with the service account's password, and you crack it with no lockout. Once the TGS is in your hands, forest B's DC is out of the loop. No bad-password counter, no MFA, no alarm on the account. You grind it offline.
Stack those three and the conclusion is forced: a single foothold in a trusted forest can harvest crackable material for privileged service accounts in a forest you were never given an account in. The only thing standing between the attacker and the password is its strength.
How it works from Kali, step by step
You need one credential in forest A and the ability to reach a domain controller in forest B. Impacket's GetUserSPNs understands the -target-domain flag, which is the whole trick: it issues the roast against the other forest.
Step 1: enumerate what is roastable on the other side
# list service accounts (accounts with an SPN) in the TARGET forest,
# authenticating with your credential from forest A
impacket-GetUserSPNs 'CORP.LOCAL/held_user:Password1' \
-target-domain VENDOR.LOCAL -dc-ip 10.10.20.5
Read the output for the accounts worth your time: anything with admincount=1, a name that smells privileged (svc_sql, svc_backup, svc_adm), or an old pwdLastSet. Those are the rooms worth picking.
Step 2: request the tickets
impacket-GetUserSPNs 'CORP.LOCAL/held_user:Password1' \
-target-domain VENDOR.LOCAL -dc-ip 10.10.20.5 \
-request -outputfile roast.hashes
The lines look like $krb5tgs$23$*... (RC4) or $krb5tgs$18$*... (AES). That is the sealed pass.
Step 3: crack offline
hashcat -m 13100 roast.hashes /usr/share/wordlists/rockyou.txt
Mode 13100 covers both etypes. The full cracking workflow, rules, and speed expectations are in cracking with hashcat. If the account used a dictionary word, you have its password in seconds, and you now hold a credential in a forest you never had an account in.
The two things that trip people up
- Clock skew. Kerberos rejects a request whose clock is more than five minutes off the DC's, with
KRB_AP_ERR_SKEW, an error that does not mention clocks. Sync to the target first:sudo ntpdate 10.10.20.5, or wrap the tool infaketimeif you cannot change the host clock. Across a trust you have two forests whose time you may need to agree with; the one you are requesting against is the one that matters. - Name resolution and referrals. Your tooling has to resolve the target forest's domain and find its DC. Add the target domain and DC to
/etc/hostsand set up/etc/krb5.confwith both realms if referrals fail. A roast that "returns nothing" is often a resolution problem, not an empty forest.
Build it in a lab
You learn this best by watching a DC hand you a ticket for an account you cannot use. Minimal setup:
- Two forests. Stand up
CORP.LOCAL(one DC) andVENDOR.LOCAL(one DC) as separate forest roots. Any current Windows Server evaluation ISO works. - A forest trust. On one side, create a forest trust to the other. In an elevated PowerShell on a DC, the Active Directory Domains and Trusts console (
domain.msc) walks you through it; for a lab make it bidirectional so you can test from either side. - A roastable target in VENDOR. Create a service account with an SPN and a deliberately weak password:
New-ADUser svc_sql -Enabled $true -AccountPassword (ConvertTo-SecureString 'Summer2025' -AsPlainText -Force) setspn -s MSSQLSvc/app01.vendor.local:1433 svc_sql - A foothold in CORP. Any ordinary user, no privileges.
- Roast across the trust from Kali using that CORP user and
-target-domain VENDOR.LOCAL, then crackSummer2025from rockyou.
Watch the target DC's Security log while you do it (next section). The lesson lands when you see that the DC issued the ticket to a foreign, unprivileged principal without a murmur.
Detection
- A burst of service-ticket requests, especially RC4, from a foreign principal. Kerberos service-ticket operations are event 4769 on the target DC. The high-signal filter is
Ticket Encryption Type 0x17(RC4) for many distinct SPNs, and across a trust the requesting account belongs to the other forest, which is itself worth noticing. A domain that is otherwise AES-first makes RC4 requests stand out further. - Honeypot service account in the trusting forest. Create a decoy account with an SPN, a long random password, and no real service. Any 4769 for its ticket, particularly from across the trust, is an attacker enumerating SPNs, because nothing legitimate ever requests it. Cheap and close to false-positive-free.
- Enable Kerberos service-ticket auditing on the DCs first; 4769 is not guaranteed on by default at the needed verbosity. Validate in your lab that you actually see the events before trusting their absence.
Prevention and response
- Make the password uncrackable. The one fix that defeats the whole technique, same-domain or cross-forest, is a service-account password that cannot be ground out: 25-plus characters and random, or far better a managed account. Group Managed Service Accounts carry machine-managed passwords that rotate automatically, which removes offline cracking entirely. The caveat is who may read them, covered in ReadGMSAPassword.
- Prefer AES, retire RC4, so there is no NTLM-speed shortcut and RC4 requests become an alarm rather than noise.
- Scope the trust. If forest B does not need forest-wide access from A, configure selective authentication so A's principals can only reach resources you explicitly allow, which shrinks what a foreign roast is worth. Keep forest-trust SID filtering on; it is a different control but part of the same "do not over-trust the other forest" posture, and it is why the tempting forged-ticket shortcut fails (that negative result here).
- Response after a confirmed roast. Treat the service account's password as known: rotate it immediately and audit everywhere it authenticates and what it reaches. If it was privileged, widen the response, because a cross-forest roast means the blast radius already spans two forests.
Check yourself
- Why can you request a ticket for a service account you are not allowed to use?
- What does the forest trust actually contribute to this attack, and what does it not contribute?
- You roast across a trust and get nothing back, no error. What are the two most likely causes before you conclude there are no roastable accounts?
- Why does a managed password defeat this attack when "prefer AES" only slows it down?
Answers:
- Because issuing a TGS is not an authorization decision. The DC hands out the ticket; the service itself decides access later. So a ticket can be minted for any SPN by any recognized principal.
- It contributes recognition: your badge from forest A is honored by forest B's DC, so your request is processed and the ticket issued. It does not contribute privilege: you are still a nobody, you have simply been handed encrypted material to crack.
- Clock skew (sync to the target DC) and name resolution or referral failure (fix
/etc/hostsand/etc/krb5.conffor the target realm). Both look like an empty result. - A managed password is long and random, so there is no wordlist or rule set that cracks it in a useful time, which removes the offline step the whole attack depends on. AES only removes the RC4 speed shortcut; a weak AES-protected password still falls.
Use
Authorized and educational use only: your own lab, a directory you own, or an engagement with written permission. This is a teaching walkthrough with the tools named rather than carried, paired with detection and remediation so defenders can see what a trust exposes and close it. It is not a runbook for use against systems you do not own.
References
- MITRE ATT&CK, Steal or Forge Kerberos Tickets: Kerberoasting (T1558.003): https://attack.mitre.org/techniques/T1558/003/
- Microsoft, How forest trusts work: https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/how-domain-and-forest-trusts-work
- Microsoft, Service Principal Names: https://learn.microsoft.com/en-us/windows/win32/ad/service-principal-names
- Microsoft, Group Managed Service Accounts overview: https://learn.microsoft.com/en-us/windows-server/security/group-managed-service-accounts/group-managed-service-accounts-overview
- Impacket GetUserSPNs: https://github.com/fortra/impacket