← Alle berichten

Kerberoasting na de RC4-uitfasering: waarom je er nog niet vanaf bent

20 oktober 2026 Identiteit en toegang 10 min lezen

Kerberoasting is al jaren een van de eerste dingen die een aanvaller probeert zodra hij een gewoon domeinaccount heeft. Microsoft heeft in 2026 in drie stappen de standaard voor RC4 in Kerberos aangescherpt, en sinds de update van juli 2026 is dat definitief. Het is verleidelijk om te denken dat Kerberoasting daarmee is opgelost. Dat is het niet. In dit artikel leg ik uit wat er precies is veranderd, waar het gat nog zit, en hoe je in je eigen domein controleert of je kwetsbaar bent en of iemand het probeert.

Alle namen en adressen in de voorbeelden zijn fictief (contoso.local, 192.0.2.0/24).

Kort: hoe Kerberoasting werkt

Elk geauthenticeerd domeinaccount mag bij de domeincontroller een serviceticket (TGS) aanvragen voor elke service met een service principal name (SPN). Dat ticket is versleuteld met een sleutel die is afgeleid van het wachtwoord van het account achter die SPN. Draait de service onder een computeraccount, dan is dat wachtwoord lang en willekeurig en valt er weinig te kraken. Draait de service onder een gewoon gebruikersaccount, met een wachtwoord dat een mens ooit heeft bedacht, dan kan de aanvaller het ticket meenemen en offline het wachtwoord raden. Daar merkt de domeincontroller niets van.

Het aanvragen zelf is normaal Kerberos-verkeer. Dat maakt de techniek zo aantrekkelijk: geen exploit, geen verhoogde rechten, alleen een lijst SPN’s en tijd.

RC4 speelt daarin een grote rol. Een RC4-sleutel is een NT-hash van het wachtwoord zonder salt en zonder iteraties, en is daardoor veel sneller te kraken dan een AES-sleutel. Daarom vroegen aanvalstools traditioneel expliciet om een RC4-ticket.

Wat Microsoft heeft veranderd

Volgens KB5073381 (CVE-2026-20833) is de uitfasering in drie fases gegaan:

FaseDatumWat er gebeurt
Initiële fase13 januari 2026Nieuwe auditevents op de domeincontrollers, enforcement optioneel
Enforcement met rollbackapril 2026DefaultDomainSupportedEncTypes wordt standaard 0x18 (alleen AES-SHA1), terugdraaien kan nog
Enforcement definitiefjuli 2026De rollback-instelling RC4DefaultDisablementPhase vervalt

Het belangrijkste woord in die documentatie is standaard. De wijziging raakt accounts waarbij het attribuut msDS-SupportedEncryptionTypes niet is ingevuld. Microsoft schrijft letterlijk dat een configuratie die een beheerder expliciet heeft ingesteld, wordt gerespecteerd.

Waar het gat nog zit

Dit is mijn analyse van wat dat in de praktijk betekent:

  1. Accounts met een expliciete RC4-instelling krijgen nog steeds RC4-tickets. Precies de serviceaccounts die ooit “even” op RC4 zijn gezet om een oude applicatie aan de praat te krijgen, zijn ook de accounts met oude wachtwoorden. En Microsofts eigen advies voor applicaties die RC4 nodig hebben, is RC4 expliciet toe te voegen (0x24). Elke uitzondering die je deze zomer hebt gemaakt om storingen op te lossen, is een kandidaat.
  2. AES-tickets zijn ook te kraken. Langzamer, maar het principe verandert niet: het ticket is versleuteld met een sleutel uit het wachtwoord. Een serviceaccount met wachtwoord Zomer2014! valt ook met AES. De echte verdediging is het wachtwoord, niet het algoritme.
  3. Niet elke domeincontroller is gepatcht. Een DC die de updates van dit jaar mist, gedraagt zich nog op de oude manier. Wie domeincontrollers buiten de patchcyclus houdt, heeft de bescherming dus niet.

RC4 uitzetten verkleint de kans aanzienlijk, en dat is goed. Maar het vervangt niet de basis: weet welke gebruikersaccounts een SPN hebben en zorg dat hun wachtwoorden niet te raden zijn.

Stap 1: inventariseer je kerberoastbare accounts

Begin met de lijst die een aanvaller ook maakt: gebruikersaccounts (geen computeraccounts) met een SPN. Met de ActiveDirectory-module:

# Gebruikersaccounts met een SPN, met de velden die het risico bepalen
$accounts = Get-ADUser -Filter 'ServicePrincipalName -like "*"' -Properties `
    ServicePrincipalName, msDS-SupportedEncryptionTypes, PasswordLastSet, AdminCount, Enabled

$accounts | ForEach-Object {
    $set = $_.'msDS-SupportedEncryptionTypes'
    [pscustomobject]@{
        Account        = $_.SamAccountName
        Enabled        = $_.Enabled
        AdminCount     = $_.AdminCount
        PasswordAgeDays= if ($_.PasswordLastSet) { ((Get-Date) - $_.PasswordLastSet).Days } else { $null }
        EncTypes       = $set
        RC4Expliciet   = [bool]($set -band 0x4)
        AESIngesteld   = [bool]($set -band 0x18)
        SPNs           = ($_.ServicePrincipalName -join '; ')
    }
} | Sort-Object RC4Expliciet, PasswordAgeDays -Descending | Format-Table -AutoSize

krbtgt heeft ook een SPN en komt in deze lijst terug. Die kun je negeren; dat wachtwoord is willekeurig en wordt door het domein beheerd.

Waar je naar kijkt, in volgorde van urgentie:

  • AdminCount = 1: het account zit (of zat) in een beschermde groep zoals Domain Admins. Een kerberoastbaar admin-account is de kortste route naar het hele domein. Haal de SPN of de adminrechten weg, liefst allebei.
  • RC4Expliciet = True: hier geldt de nieuwe standaard niet. Zoek uit waarom het zo is ingesteld en of dat nog nodig is.
  • EncTypes leeg: dit account valt onder de nieuwe standaard (AES). Goed, maar kijk wel naar de wachtwoordleeftijd.
  • Hoge PasswordAgeDays: een wachtwoord van tien jaar oud is gezet in een tijd met andere wachtwoordregels, en wordt waarschijnlijk door meerdere mensen gekend.

De waarden in msDS-SupportedEncryptionTypes zijn een bitmask: 0x4 is RC4, 0x8 AES128, 0x10 AES256. 24 (0x18) betekent dus alleen AES, 28 (0x1C) AES plus RC4. Microsoft heeft een volledige tabel in de documentatie.

Stap 2: lees wat de KDC je al vertelt

Sinds de update van januari logt de KDC in de System-log van elke domeincontroller events over RC4-afhankelijkheden. Volgens KB5073381:

EventBetekenis (verkort)
201 / 203Client adverteert alleen RC4, service heeft geen eigen instelling. 201 in auditfase, 203 als het wordt geblokkeerd
202 / 204Serviceaccount heeft geen AES-sleutels. 202 in auditfase, 204 als het wordt geblokkeerd
205DefaultDomainSupportedEncTypes bevat expliciet onveilige ciphers. Wordt gelogd bij het starten van de KDC
206 / 208Alleen AES ingesteld, maar de client adverteert geen AES
207 / 209Alleen AES ingesteld, maar het account heeft geen AES-sleutels

Event 205 wil je op geen enkele DC zien: dan staat RC4 domeinbreed weer aan en is de hele aanscherping teruggedraaid. Events 202/204 en 207/209 wijzen vaak op accounts waarvan het wachtwoord in jaren niet is gewijzigd, want AES-sleutels ontstaan pas bij een wachtwoordwijziging. Die accounts vallen dus waarschijnlijk ook in de lijst van stap 1.

# KDC-events over RC4 op alle domeincontrollers, laatste 30 dagen
$dcs = (Get-ADDomainController -Filter *).HostName
foreach ($dc in $dcs) {
    Get-WinEvent -ComputerName $dc -FilterHashtable @{
        LogName   = 'System'
        Id        = 201..209
        StartTime = (Get-Date).AddDays(-30)
    } -ErrorAction SilentlyContinue |
        Where-Object ProviderName -match 'Kdc|Key-Distribution' |
        Select-Object @{n='DC';e={$dc}}, TimeCreated, Id, Message
}

Het filter op ProviderName staat erin omdat 201 tot en met 209 in de System-log ook door andere bronnen gebruikt kunnen worden. Microsoft heeft daarnaast twee scripts gepubliceerd in de Kerberos-Crypto-repository (Get-KerbEncryptionUsage.ps1 en List-AccountKeys.ps1) die hetzelfde overzicht uit de Security-log halen.

Stap 3: zie Kerberoasting in event 4769

Elke aanvraag voor een serviceticket levert op de domeincontroller een event 4769 op, mits de auditcategorie Audit Kerberos Service Ticket Operations aan staat. Dat is een groot volume, want normaal gebruik levert er ook duizenden per uur op. Het gaat dus om patronen, niet om losse events.

De velden die ertoe doen:

  • ServiceName: voor welk account het ticket is. Computeraccounts eindigen op $, krbtgt is de TGT-service. Die twee filter je eruit; Kerberoasting richt zich op gebruikersaccounts.
  • TicketEncryptionType: 0x17 is RC4, 0x11 en 0x12 zijn AES. Na de juli-update is 0x17 voor een serviceaccount zonder expliciete RC4-instelling niet meer te verwachten.
  • TargetUserName en IpAddress: wie vroeg het aan, en vanaf welke machine.
  • Status: 0x0 is geslaagd. Na enforcement zie je bij geweigerde RC4-aanvragen 0xE (KDC_ERR_ETYPE_NOTSUPP). Een reeks 0xE-fouten van één account kan dus ook een aanvaller zijn die nog op de oude manier om RC4 vraagt.

Drie signalen, van sterk naar zwak (mijn eigen rangorde):

  1. Eén account vraagt in korte tijd tickets aan voor veel verschillende serviceaccounts. Een gebruiker heeft in een normale werkdag tickets nodig voor de paar services die hij gebruikt, niet voor alle tachtig SQL-, IIS- en applicatieaccounts in het domein.
  2. RC4-tickets (0x17) of RC4-weigeringen (0xE) voor gebruikersaccounts met een SPN.
  3. Aanvragen vanaf een ongebruikelijke machine voor een serviceaccount dat normaal alleen vanaf een paar applicatieservers wordt aangesproken.

Als je de Security-log van je DC’s in Microsoft Sentinel of Log Analytics hebt (tabel SecurityEvent), haalt deze query het eerste en tweede signaal eruit:

let venster = 1h;
let drempel = 10;   // aantal verschillende serviceaccounts per aanvrager; afstemmen op je eigen omgeving
SecurityEvent
| where TimeGenerated > ago(1d)
| where EventID == 4769
| extend ed = parse_xml(EventData)
| mv-apply d = ed.EventData.Data on (
    summarize bag = make_bag(bag_pack(tostring(d['@Name']), tostring(d['#text'])))
  )
| extend ServiceName   = tostring(bag.ServiceName),
         Aanvrager     = tostring(bag.TargetUserName),
         IpAdres       = tostring(bag.IpAddress),
         EncType       = tostring(bag.TicketEncryptionType),
         Status        = tostring(bag.Status)
| where ServiceName !endswith "$" and ServiceName !~ "krbtgt"
| summarize Services   = dcount(ServiceName),
            RC4Tickets = countif(EncType == "0x17"),
            Geweigerd  = countif(Status =~ "0xe"),
            ServiceLijst = make_set(ServiceName, 50),
            IpAdressen   = make_set(IpAdres, 10)
    by Aanvrager, bin(TimeGenerated, venster)
| where Services >= drempel or RC4Tickets > 0 or Geweigerd > 0
| order by Services desc

Een treffer ziet er dan zo uit (fictief):

Aanvrager            TimeGenerated         Services  RC4Tickets  Geweigerd  IpAdressen
j.devries@CONTOSO.LOCAL  2026-10-19 14:00   37        2           0          ["::ffff:192.0.2.45"]

Een helpdeskmedewerker die in één uur tickets vraagt voor 37 serviceaccounts, vanaf een werkplek, is reden om die werkplek te onderzoeken.

Verwacht valse positieven. Monitoringtools, vulnerability scanners en sommige beheerconsoles vragen ook tickets voor veel services aan. Leg die eerst vast als uitzondering op aanvrager en IP-adres, en verlaag daarna pas de drempel. Gebruik je Microsoft Defender for Identity, dan heeft die er een eigen detectie voor: Suspected Kerberos SPN exposure (external ID 2410), en in het nieuwere format daarnaast meldingen over SPN-enumeratie via LDAP en ADWS. Die vullen elkaar aan: de enumeratie gaat aan de ticketaanvragen vooraf.

Stap 4: een lokaas-account

De sterkste detectie is ook de eenvoudigste. Maak een gebruikersaccount aan met een SPN die nergens voor wordt gebruikt, bijvoorbeeld MSSQLSvc/sql-legacy01.contoso.local:1433 op een account svc-sqllegacy. Geef het een lang willekeurig wachtwoord, geen rechten, en een naam die er aantrekkelijk uitziet.

Geen enkele legitieme gebruiker of applicatie vraagt ooit een ticket voor die service aan. Elke 4769 met dat account als ServiceName is dus een alarm, zonder drempels en zonder afstemming. In KQL is dat één regel extra:

SecurityEvent
| where EventID == 4769 and EventData has "svc-sqllegacy"

Let op dat de SPN-host niet bestaat of niet bereikbaar is, zodat er ook echt nooit een reden voor normaal verkeer is.

Stap 5: het gat dichten

Detectie is het vangnet, niet de oplossing. Wat werkelijk helpt:

  • Vervang serviceaccounts door gMSA’s waar het kan. Een group Managed Service Account krijgt een lang, willekeurig gegenereerd wachtwoord dat AD zelf roteert. Kerberoasting levert dan niets bruikbaars op. In mijn artikel over PowerShell scheduled tasks staat meer over gMSA’s.
  • Kan dat niet: een lang, willekeurig wachtwoord. Denk aan 30 tekens of meer uit een wachtwoordgenerator, opgeslagen in je wachtwoordkluis. Dat is het enige dat ook tegen AES-kraken beschermt.
  • Wijzig oude wachtwoorden. Dat levert meteen AES-sleutels op voor accounts die die nog niet hadden. Test het eerst: een serviceaccount waarvan het wachtwoord op vijf plekken hardcoded staat, gaat na een wijziging op vijf plekken stuk.
  • Zet AES expliciet (msDS-SupportedEncryptionTypes = 24) op serviceaccounts die het ondersteunen, en haal expliciete RC4-instellingen weg nadat je hebt getest dat de applicatie zonder kan.
  • Haal SPN’s weg die niet meer nodig zijn. Een SPN op een account van een applicatie die drie jaar geleden is uitgefaseerd, is alleen nog aanvalsoppervlak.
  • Geen SPN’s op beheerdersaccounts. Nooit.

Wat ik eruit meeneem

De RC4-uitfasering is een van de nuttigste standaardwijzigingen die Microsoft in jaren in Active Directory heeft doorgevoerd. Maar ze beschermt vooral accounts die toch al goed waren ingericht. De zwakke plekken in een gemiddeld domein zitten in de uitzonderingen: het oude serviceaccount met RC4, het wachtwoord dat sinds 2015 niet is gewijzigd, de SPN die ooit op een admin-account is gezet. Die vind je niet door af te wachten, maar door de lijst uit stap 1 een keer echt door te lopen.

Bronnen