1. Home
  2. Lab library
  3. IB-AD-SEC

Find Kerberoastable Service Accounts and Move Them to gMSA

Any domain user can request a Kerberos service ticket for an account with a service principal name and crack it offline, an attack known as Kerberoasting. In this lab you list every user account with an SPN, rank them by password age, encryption type and…

Level Intermediate Time about 100 minutes Updated
Quick answer

Any domain user can request a Kerberos service ticket for an account with a service principal name and crack it offline, an attack known as Kerberoasting. In this lab you list every user account with an SPN, rank them by password age, encryption type and privilege, then migrate one service to a group Managed Service Account whose 120 character password rotates automatically.

Key takeaways

  • Every user account with an SPN is a Kerberoasting target for any authenticated user
  • Old passwords, RC4 encryption and admin rights make a service account high risk
  • A gMSA has a long random password that Active Directory rotates every 30 days
  • Event ID 4769 with encryption type 0x17 helps you detect roasting attempts

Why this lab matters

When a client asks for a service ticket, part of the ticket is encrypted with a key derived from the service account's password. Any authenticated user may ask for that ticket. If the password is short or old, an attacker can crack it offline with no failed logons and no lockout. Service accounts set up years ago with a memorable password and Domain Admin rights are exactly what attackers look for.

From Kerberoastable accounts to managed service accounts01Find SPN accountsUsers with a service name02Rank the riskPassword age, RC4, privilege03Create the gMSAKDS root key and group04Migrate the serviceInstall, test, switch05Detect roastingEvent 4769 with RC4
From Kerberoastable accounts to managed service accounts

What you need

  • A lab domain with one domain controller and one member server, at Windows Server 2012 domain functional level or later.
  • The Active Directory PowerShell module and Domain Admin rights in the lab.
  • Test data: create a user svc-legacyapp and give it an SPN with setspn -S HTTP/legacyapp.corp.example svc-legacyapp.

Step 1: Find every user account with an SPN

Import-Module ActiveDirectory

$svc = Get-ADUser -Filter 'ServicePrincipalName -like "*"' -Properties ServicePrincipalName,
         PasswordLastSet, LastLogonTimestamp, adminCount, 'msDS-SupportedEncryptionTypes', MemberOf, Enabled |
  Where-Object SamAccountName -ne 'krbtgt' |
  Select-Object SamAccountName, Enabled, PasswordLastSet,
    @{n='PwdAgeDays';e={ [int]((Get-Date) - $_.PasswordLastSet).TotalDays }},
    @{n='LastLogon';e={ [datetime]::FromFileTime($_.LastLogonTimestamp) }},
    @{n='Privileged';e={ $_.adminCount -eq 1 }},
    @{n='EncTypes';e={ $_.'msDS-SupportedEncryptionTypes' }},
    @{n='SPNs';e={ $_.ServicePrincipalName -join '; ' }}

$svc | Sort-Object PwdAgeDays -Descending | Format-Table SamAccountName, PwdAgeDays, Privileged, EncTypes -AutoSize
$svc | Export-Csv .\spn-accounts.csv -NoTypeInformation

Step 2: Rank the risk

SignalHow to read it
PwdAgeDays over 365The password predates current standards and has had years to leak
Privileged is TrueCracking it gives admin rights. Fix these first
EncTypes empty or includes 4RC4 is allowed, which is much faster to crack. A value of 24 means AES only
No recent logonThe service may be retired. Remove the SPN or disable the account

For accounts you cannot migrate yet, set a random password of 25 characters or more and enforce AES:

Set-ADUser svc-legacyapp -Replace @{ 'msDS-SupportedEncryptionTypes' = 24 }
# then change the password so new AES keys are generated

Step 3: Prepare for gMSA

  1. Create the KDS root key, once per forest. In production it becomes usable after 10 hours so that all domain controllers receive it:
    Add-KdsRootKey -EffectiveImmediately
    For a single domain controller lab only, you can backdate it so it works straight away:
    Add-KdsRootKey -EffectiveTime ((Get-Date).AddHours(-10))
  2. Create a group for the servers allowed to use the account, add the member server and restart that server so it picks up the membership:
    New-ADGroup -Name 'GRP-gMSA-LegacyApp' -GroupScope Global -GroupCategory Security
    Add-ADGroupMember 'GRP-gMSA-LegacyApp' -Members 'APP01$'

Step 4: Create and install the gMSA

New-ADServiceAccount -Name 'gmsa-legacyapp' `
  -DNSHostName 'gmsa-legacyapp.corp.example' `
  -PrincipalsAllowedToRetrieveManagedPassword 'GRP-gMSA-LegacyApp' `
  -KerberosEncryptionType AES128, AES256

On the member server:

Install-WindowsFeature RSAT-AD-PowerShell
Install-ADServiceAccount -Identity 'gmsa-legacyapp'
Test-ADServiceAccount -Identity 'gmsa-legacyapp'   # must return True

Step 5: Switch the service over

  1. Give the gMSA the same file, database and local rights the old account had. Do not add it to an admin group to save time.
  2. Open services.msc, open the service, and on the Log On tab enter CORP\gmsa-legacyapp$ with the password boxes left empty.
  3. Move the SPN to the new account:
    setspn -D HTTP/legacyapp.corp.example svc-legacyapp
    setspn -S HTTP/legacyapp.corp.example gmsa-legacyapp$
  4. Restart the service and test the application. Then disable the old account, and delete it after an agreed waiting period.
Tip

Scheduled tasks can run as a gMSA too, but must be created with PowerShell using New-ScheduledTaskPrincipal -LogonType Password and the account name ending in a dollar sign.

Step 6: Detect roasting

On domain controllers, turn on Audit Kerberos Service Ticket Operations for success. Then look for ticket requests that use RC4:

Get-WinEvent -FilterHashtable @{ LogName = 'Security'; Id = 4769 } -MaxEvents 2000 |
  Where-Object { $_.Properties[5].Value -eq 0x17 -and $_.Properties[2].Value -notlike '*$' } |
  Select-Object TimeCreated, @{n='User';e={$_.Properties[0].Value}}, @{n='Service';e={$_.Properties[2].Value}}

One user requesting RC4 tickets for many different services in a few minutes deserves a closer look.

Verify

The lab is complete when Test-ADServiceAccount returns True, the service runs as the gMSA, the old account is disabled and no longer holds an SPN.

Evidence to keep

  • The SPN account export before and after.
  • The gMSA properties, including which group can retrieve the password.
  • A screenshot of the service running under the gMSA.

Frequently asked questions

What is Kerberoasting?

Kerberoasting is an attack where an authenticated domain user requests Kerberos service tickets for accounts with a service principal name, then cracks the tickets offline to recover the service account password.

How does a gMSA prevent Kerberoasting?

A group Managed Service Account has a 240 byte random password, about 120 characters, that Active Directory generates and changes every 30 days by default. A ticket can still be requested, but the password is not practical to crack.

How do I find Kerberoastable accounts in Active Directory?

Search for user accounts that have a servicePrincipalName value, for example with Get-ADUser -Filter 'ServicePrincipalName -like "*"'. Computer accounts and the krbtgt account can be ignored.

What does msDS-SupportedEncryptionTypes 24 mean?

The value 24 is the sum of 8 for AES128 and 16 for AES256, so the account supports AES Kerberos encryption only and RC4 tickets are not issued for it.

Built and published by Muhammad Rizwan Afzal for Identity Bytes. Run every lab against a disposable test tenant, never production.