> For the complete documentation index, see [llms.txt](https://docs.stoik.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.stoik.io/cyber-best-practices/nl/gidsen-voor-het-verhelpen-van-kwetsbaarheden/ad-scan-vulnerability-remediation-guide/privileged-accounts.md).

# Geprivilegieerde accounts

## P-Kerberoasting

#### Wat het betekent

In Active Directory zijn sommige accounts geregistreerd om services uit te voeren zoals een SQL Server of een webtoepassing. Deze accounts hebben een **Service Principal Name (SPN)**, wat in wezen een label is dat zegt "dit account voert een netwerkservice uit."

Het beveiligingsrisico is: **elke geauthenticeerde gebruiker** in het domein kan een Kerberos-ticket aanvragen voor elk account met een SPN. Dat ticket wordt versleuteld met het wachtwoord van het account, en de aanvaller kan het vervolgens offline proberen te kraken, zonder een alarm te activeren.

Dit heet een **Kerberoasting** aanval. Het is vooral gevaarlijk wanneer het account met de SPN ook een **Domain Admin**, want het kraken van dat wachtwoord betekent volledige controle over het domein.

#### Wat de scan controleert

De AD-scan markeert accounts die aan **alle drie** voorwaarden voldoen:

1. Het account is lid van een **bevoorrechte groep** (Domain Admins, Enterprise Admins, enz.)
2. Het account heeft een **Service Principal Name (SPN)**
3. Het wachtwoord van het account **wachtwoord is al meer dan 40 dagen niet gewijzigd** (waardoor aanvallers meer tijd krijgen om het te kraken)

#### Waarom de waarschuwing kan blijven bestaan

Je moet **alle drie** voorwaarden. Veelvoorkomende onvolledige oplossingen:

* **Wachtwoord gewijzigd maar de SPN behouden:** De waarschuwing verdwijnt tijdelijk, maar keert na 40 dagen terug.
* **SPN verwijderd maar het account zit nog steeds in Domain Admins:** De waarschuwing verdwijnt, maar het onderliggende risico blijft bestaan.

#### Hoe te diagnosticeren

```powershell
$privilegedGroups = @("Domain Admins", "Enterprise Admins", "Schema Admins", "Administrators")
$threshold = (Get-Date).AddDays(-40)

foreach ($group in $privilegedGroups) {
  Get-ADGroupMember -Identity $group -Recursive |
    Where-Object { $_.objectClass -eq "user" } |
    ForEach-Object { Get-ADUser $_ -Properties ServicePrincipalName, PasswordLastSet } |
    Where-Object { $_.ServicePrincipalName.Count -gt 0 -and $_.PasswordLastSet -lt $threshold } |
    Select-Object SamAccountName,
      @{N="PasswordAge (days)"; E={[math]::Round(((Get-Date) - $_.PasswordLastSet).TotalDays)}},
      @{N="SPNs"; E={$_.ServicePrincipalName -join "; "}}
}
```

#### Hoe dit op te lossen

**Beste optie: verwijder het account uit bevoorrechte groepen.** Servicerekeningen hoeven zelden Domain Admins te zijn. Maak een specifiek, niet-bevoorrecht account met alleen de rechten die de service werkelijk nodig heeft:

```powershell
Remove-ADGroupMember -Identity "Domain Admins" -Members "svc_account" -Confirm:$false
```

**Als je het niet uit de beheerdersgroep kunt verwijderen:** Stel in elk geval het wachtwoord regelmatig opnieuw in (elke 30 dagen of minder):

```powershell
Set-ADAccountPassword -Identity "svc_account" `
  -NewPassword (ConvertTo-SecureString "YourNewStr0ngP@ssw0rd!" -AsPlainText -Force) -Reset
```

**Beste langetermijnoplossing:** Converteer naar een **Group Managed Service Account (gMSA)**, dat zijn wachtwoord automatisch elke 30 dagen wijzigt:

```powershell
New-ADServiceAccount -Name "gMSA_SQLService" `
  -DNSHostName "gmsa_sqlservice.yourdomain.com" `
  -PrincipalsAllowedToRetrieveManagedPassword "SQLServersGroup"
```

## P-AdminLogin

#### Wat het betekent

Elk Active Directory-domein heeft een **ingebouwde Administrator-account** dat automatisch wordt aangemaakt wanneer het domein wordt ingesteld. Dit account heeft volledige controle over het hele domein en kan niet worden vergrendeld.

Vanwege zijn macht en voorspelbaarheid (aanvallers weten dat het altijd bestaat) moet het worden gereserveerd voor **alleen noodgevallen**, zoals herstel na een ramp. Dagelijks beheer moet gebruikmaken van persoonlijke beheerdersaccounts (bijv., `adm_john`) zodat acties aan individuen kunnen worden herleid.

#### Wat de scan controleert

De AD-scan controleert of het ingebouwde Administrator-account is ingelogd op een domeincontroller in de **afgelopen 35 dagen**. Als dat zo is, wordt de waarschuwing geactiveerd, wat aangeeft dat het account wordt gebruikt voor routinetaken in plaats van voor noodgevallen te worden bewaard.

#### Waarom de waarschuwing kan blijven bestaan

* **Het hernoemen van het account helpt niet.** De scan identificeert de ingebouwde Administrator aan de hand van zijn interne identifier (RID-500), niet aan de hand van zijn naam.
* **Het wijzigen van het wachtwoord helpt niet.** De scan controleert inlogactiviteit, niet de leeftijd van het wachtwoord.
* **Geautomatiseerde scripts of geplande taken** die worden uitgevoerd als de ingebouwde Administrator blijven de waarschuwing activeren.
* **Je hoeft alleen maar te wachten.** Nadat je het account niet meer gebruikt, verdwijnt de waarschuwing automatisch na 35 dagen.

#### Hoe te diagnosticeren

```powershell
# Controleer wanneer de ingebouwde Administrator voor het laatst heeft ingelogd op elke DC
$domainSID = (Get-ADDomain).DomainSID
$adminSID = "$domainSID-500"

Get-ADDomainController -Filter * | ForEach-Object {
  $dc = $_
  $admin = Get-ADUser -Identity $adminSID -Server $dc.HostName -Properties LastLogon
  $lastLogon = [DateTime]::FromFileTime($admin.LastLogon)
  $daysAgo = [math]::Round(((Get-Date) - $lastLogon).TotalDays, 1)

  [PSCustomObject]@{
    DC        = $dc.HostName
    LastLogon = $lastLogon
    DaysAgo   = $daysAgo
    Status    = if ($daysAgo -le 35) { "WAARSCHUWING - Onlangs gebruikt" } else { "OK" }
  }
} | Format-Table -AutoSize
```

Controleer ook op geplande taken die mogelijk de ingebouwde Administrator gebruiken:

```powershell
Get-ADDomainController -Filter * | ForEach-Object {
  Invoke-Command -ComputerName $_.HostName -ScriptBlock {
    Get-ScheduledTask | Where-Object {
      $_.Principal.UserId -match "Administrator"
    } | Select-Object TaskName, @{N="RunAs"; E={$_.Principal.UserId}}
  }
}
```

#### Hoe dit op te lossen

1. **Maak persoonlijke beheerdersaccounts aan** voor elke beheerder (bijv., `adm_john`, `adm_jane`)
2. **Werk alle geplande taken bij** zodat ze een speciaal service-account gebruiken in plaats van de ingebouwde Administrator
3. **Stop met inloggen** met de ingebouwde Administrator voor routinetaken
4. De waarschuwing zal automatisch verdwijnen **35 dagen** na de laatste inlog

## P-AdminNum

#### Wat het betekent

Hoe meer accounts met beheerdersrechten in je domein, hoe groter het aanvalsoppervlak. Elk beheerdersaccount is een mogelijke ingang voor een aanvaller. Veel organisaties eindigen na verloop van tijd met te veel beheerdersaccounts: tijdelijke toegang die nooit is ingetrokken, serviceaccounts die voor het gemak aan Domain Admins zijn toegevoegd, enz.

#### Wat de scan controleert

De AD-scan telt het totale aantal **unieke gebruikers** over alle bevoorrechte groepen (Domain Admins, Enterprise Admins, Administrators, Account Operators, Server Operators, Backup Operators, enz.). Als dezelfde gebruiker in meerdere groepen zit, wordt die slechts één keer geteld.

De waarschuwing wordt geactiveerd als:

* Meer dan **10%** van de actieve gebruikers bevoorrecht zijn, OF
* Meer dan **50** er bevoorrechte accounts bestaan

> Deze controle wordt overgeslagen voor kleine organisaties met minder dan 100 actieve gebruikers.

#### Hoe te diagnosticeren

```powershell
$privilegedGroups = @(
  "Domain Admins", "Enterprise Admins", "Schema Admins", "Administrators",
  "Account Operators", "Server Operators", "Backup Operators", "Print Operators"
)

$uniqueMembers = @{}
foreach ($group in $privilegedGroups) {
  try {
    Get-ADGroupMember -Identity $group -Recursive |
      Where-Object { $_.objectClass -eq "user" } |
      ForEach-Object { $uniqueMembers[$_.DistinguishedName] = $_.SamAccountName }
  } catch {}
}

$activeUsers = (Get-ADUser -Filter "Enabled -eq `$true" | Measure-Object).Count
$pct = [math]::Round(($uniqueMembers.Count / $activeUsers) * 100, 1)

Write-Host "Bevoorrechte accounts: $($uniqueMembers.Count)"
Write-Host "Actieve gebruikers: $activeUsers"
Write-Host "Verhouding: $pct% (waarschuwing bij >10% of >50 accounts)"
Write-Host ""
$uniqueMembers.Values | Sort-Object | ForEach-Object { Write-Host "  - $_" }
```

#### Hoe dit op te lossen

Bekijk de lijst en verwijder accounts die echt geen admin-toegang nodig hebben:

```powershell
Remove-ADGroupMember -Identity "Domain Admins" -Members "username" -Confirm:$false
```

Beste praktijken:

* Gebruik **aparte beheerdersaccounts** (`adm_john`) die verschillen van accounts voor dagelijks gebruik
* **Verwijder serviceaccounts** uit beheerdersgroepen en geef alleen de specifieke rechten die ze nodig hebben
* **Controleer het lidmaatschap van bevoorrechte groepen** regelmatig

## P-ProtectedUsers

#### Wat het betekent

De **Protected Users** groep is een speciale beveiligingsgroep die is geïntroduceerd in Windows Server 2012 R2. Leden van deze groep krijgen extra bescherming:

* Ze kunnen **zich alleen verifiëren met Kerberos** (het veiligere protocol), niet met het oudere NTLM-protocol
* Hun **referenties worden niet gecachet** op computers waarop ze inloggen: een aanvaller die een werkstation compromitteert, kan hun referenties niet uit het geheugen stelen
* **Delegatie is uitgeschakeld:** hun account kan niet door services worden geïmiteerd

Deze beschermingen zijn cruciaal voor beheerdersaccounts, die in de meeste aanvallen het primaire doelwit zijn.

#### Wat de scan controleert

De AD-scan verifieert dat alle **ingeschakelde beheerdersaccounts** (leden van Domain Admins, Enterprise Admins, enz.) ook lid zijn van de **Protected Users** groep.

#### Waarom de waarschuwing kan blijven bestaan

* **Gebruikers die via geneste groepen zijn toegevoegd** worden mogelijk niet gedetecteerd. Voeg gebruikers toe **rechtstreeks** aan de Protected Users-groep.
* **Replicatievertragingen** tussen domeincontrollers kunnen tijdelijke inconsistenties veroorzaken.
* **Beheerde serviceaccounts (gMSA)** worden van deze controle uitgesloten: ze hoeven niet in Protected Users te staan.

#### Hoe te diagnosticeren

```powershell
$protectedUsers = (Get-ADGroupMember -Identity "Protected Users").DistinguishedName
$privilegedGroups = @("Domain Admins", "Enterprise Admins", "Schema Admins", "Administrators")

$notProtected = foreach ($group in $privilegedGroups) {
  Get-ADGroupMember -Identity $group -Recursive |
    Where-Object { $_.objectClass -eq "user" } |
    ForEach-Object { Get-ADUser $_ -Properties Enabled } |
    Where-Object { $_.Enabled -and $_.DistinguishedName -notin $protectedUsers }
}

$notProtected | Select-Object -Unique SamAccountName, Name | Format-Table -AutoSize
```

#### Hoe dit op te lossen

```powershell
Add-ADGroupMember -Identity "Protected Users" -Members "adm_john", "adm_jane"
```

> **Belangrijk:** Het toevoegen van accounts aan Protected Users dwingt **alleen Kerberos-verificatie af**. Sommige oudere toepassingen die NTLM vereisen, kunnen voor deze accounts niet meer werken. **Test eerst met één account** voordat je alle beheerders toevoegt.
>
> Best practice: beheerdersaccounts moeten worden gebruikt **alleen voor beheerstaken** (niet voor e-mail, web browsen of het uitvoeren van zakelijke toepassingen), dus NTLM-compatibiliteit is zelden een zorg.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.stoik.io/cyber-best-practices/nl/gidsen-voor-het-verhelpen-van-kwetsbaarheden/ad-scan-vulnerability-remediation-guide/privileged-accounts.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
