- Escenario 1: Sin dueño y peligroso
- Visión general de la ruta de ataque
- Flujo de ataque
- ¿Por qué es importante conocer la propiedad de las aplicaciones?
- Cómo detectar y defenderse contra el uso indebido de la propiedad principal del servicio
- Solución paso a paso
- Paso 1: Afianzamiento inicial
- Paso 2: Enumeración
- Paso 3: Pivotar hacia el contexto del principal del servicio
- Paso 4: Adquisición de la cuenta: inicio de sesión como administrador global
- Conozca su eslabón más débil
- Acepta tu próximo reto EntraGoat
- Nota final
- Descargo de responsabilidad
Nota del editor
Este escenario forma parte de una serie de ejemplos que demuestran el uso de EntraGoat, nuestro entorno de simulación Entra ID. Puede leer una descripción general de EntraGoat y su valor aquí.
Mal poseído y peligroso: Manual del propietario para la administración global
Comenzamos nuestros ejemplos de uso del EntraGoat con el Escenario 1, que hemos llamado Misowned and Dangerous: Manual del Propietario del Admin Global. Este ejercicio práctico muestra cómo la propiedad legítima de una aplicación en Microsoft Entra ID puede ser aprovechada para escalar privilegios y comprometer una cuenta de Administrador Global, permitiendo la toma completa del tenant.
Partiendo de una cuenta de usuario con pocos privilegios comprometida, el atacante descubre la propiedad sobre una aplicación empresarial (service principal) que tiene asignado un rol privilegiado.
Mediante la adición de un secreto de cliente al principal del servicio, el atacante pivota en la identidad de la aplicación, a continuación, utiliza su papel para restablecer la contraseña del administrador y emitir un pase de acceso temporal (TAP) para obtener acceso interactivo completo al portal de Azure.
Este escenario pone de relieve las consecuencias en el mundo real de una mala gestión de las aplicaciones e ilustra la diferencia de comportamiento, los límites de acceso y la exposición al riesgo entre los flujos de autenticación delegados y los exclusivos de las aplicaciones.
Visión general de la ruta de ataque
- Historia del punto de apoyo inicial: El atacante se autentica como un usuario de finanzas comprometido (
david.martinez
) con credenciales robadas. - Enumeración: Utilizando PowerShell nativo y los cmdlets de Microsoft Graph, el atacante descubre que el usuario posee un servicio principal llamado
Finance Analytics Dashboard
que tiene asignado elPrivileged Authentication Administrator
papel. - Escalada de privilegios: El atacante añade un secreto de cliente a la entidad principal de servicio de la que es propietario y se autentica utilizando credenciales de solo aplicación, pivotando a una identidad de entidad principal de servicio.
- Toma de cuenta: Desde el contexto de solo aplicación con el rol privilegiado, el atacante restablece la contraseña del Administrador Global o agrega un TAP para eludir la autenticación multifactor (MFA), luego inicia sesión de forma interactiva y recupera la bandera, confirmando el compromiso total del inquilino.
Flujo de ataque
La figura 1 muestra el flujo de este ataque.
¿Por qué es importante conocer la propiedad de las aplicaciones?
Cada aplicación en Entra ID tiene dos identidades distintas:
- Registro de la aplicación, un objeto de definición global en el inquilino de origen donde se creó originalmente la aplicación. Este objeto contiene los permisos blueprint-OAuth2 de la aplicación (ámbitos) que la aplicación puede solicitar URI de redirección para flujos de inicio de sesión, metadatos de marca y editor, etc. Esta identidad no representa por sí misma una entidad de seguridad activa en el inquilino.
- Service principal, una instancia local de la aplicación en el tenant que actúa como su identidad de seguridad e impone el control de acceso. Una entidad de seguridad de servicio se crea automáticamente cuando un usuario del inquilino registra una nueva aplicación, da su consentimiento a una aplicación externa, etcétera. La identidad principal de servicio es lo que Entra ID utiliza para asignar roles, aplicar políticas y hacer cumplir los permisos. También es la identidad autenticada cuando la aplicación actúa por su cuenta (contexto de sólo aplicación).
La propiedad de las aplicaciones es una característica administrativa legítima. Este diseño admite la administración descentralizada en grandes organizaciones, lo que permite a los equipos gestionar sus propias aplicaciones empresariales. Permite a los desarrolladores, procesos de automatización y propietarios de servicios gestionar el ciclo de vida y la configuración de sus aplicaciones. Sin embargo, esta característica se convierte en una desventaja cuando:
- Las solicitudes reciben funciones privilegiadas
- La propiedad se asigna a usuarios habituales sin gobernanza
- La higiene de las credenciales es deficiente o no está supervisada
Los principales de servicio mal gobernados permiten la adición de credenciales y el acceso exclusivo a aplicaciones, eludiendo controles de identidad como MFA y el acceso condicional.
Este recorrido destaca por qué los atacantes priorizan el movimiento lateral utilizando los principales de servicio en los entornos de nube modernos y por qué los defensores deben comprender la diferencia entre los contextos de seguridad delegados y los exclusivos de las aplicaciones.
Cómo detectar y defenderse contra el uso indebido de la propiedad principal del servicio
Entender y monitorear la propiedad de la aplicación no es opcional; es un control de seguridad fundamental en cualquier entorno Entra ID. La propiedad de la aplicación otorga la capacidad de gestionar credenciales, configurar permisos y controlar eficazmente la identidad de la aplicación. Sin visibilidad de la propiedad de la aplicación y las asignaciones de permisos, las rutas de escalada de privilegios permanecen ocultas tanto para los defensores como para los auditores.
Los defensores deben vigilar y correlacionar:
- ¿Qué aplicaciones existen en el inquilino?
- ¿A quién pertenecen?
- ¿Qué permisos o funciones de directorio tienen asignados?
- ¿Hay algún usuario sin privilegios que posea un principal de servicio con acceso elevado?
- ¿Qué aplicaciones ya no se utilizan y pueden darse de baja?
Las soluciones de Semperis ayudan a colmar las lagunas en la comprensión de estas cuestiones con múltiples capas de defensa, empezando por los indicadores de exposición (IOE) y los indicadores de compromiso (IOC).
Estos indicadores detectan y alertan automáticamente sobre valores por defecto y configuraciones erróneas peligrosas, como políticas de autorización excesivamente permisivas para configurar aplicaciones, usuarios no administradores que poseen privilegios de servicio y líneas de base de seguridad de aplicaciones débiles.
Escenario en profundidad: Recorrido paso a paso de la solución
Echemos un vistazo a los pasos específicos que seguirás para simular el uso indebido de la propiedad de la aplicación y comprender en qué condiciones permite comprometer la administración global.
Paso 1: Afianzamiento inicial
Comenzamos con el contexto de seguridad de un analista financiero, david.martinez
(Figura 2) que introdujo sus credenciales corporativas durante una campaña de phishing.
Utilización de la Connect-MgGraph
nos autenticamos como el usuario comprometido (Figura 3).
Para comprender nuestras capacidades actuales, empezamos por inspeccionar el contexto de seguridad de la sesión autenticada(Figura 4).
Un método alternativo y bien conocido para autenticarse como usuario de Entra ID y obtener un token de acceso JWT es aprovechar herramientas de automatización como BARK1. El siguiente fragmento de PowerShell demuestra cómo adquirir y utilizar un token de acceso mediante autenticación de nombre de usuario/contraseña desde la CLI:
$userToken = Get-MSGraphTokenWithUsernamePassword -Username $UPN -Password $password -TenantID $tenantId $userAccessToken = $userToken.access_token $SecureToken = ConvertTo-SecureString $userAccessToken -AsPlainText -Force Connect-MgGraph -TokenDeAcceso $TokenSeguro
BARK también incluye funciones para descodificar el JWT resultante, exponiendo metadatos detallados de la sesión, como los permisos delegados (scp
), funciones de directorio (wids
), método de autenticación (amr
), e información sobre los clientes (app_displayname
), como Gráfico 5 espectáculos.
Este paso de descodificación es especialmente útil para una rápida clasificación de privilegios. Por ejemplo, si el token se ha emitido a un usuario con funciones de directorio, la función wids
enumeraría directamente los GUID de las funciones asignadas, como la función de administrador global que Figura 6 sin necesidad de una enumeración adicional de la Graph API.
Sin embargo, este tutorial evita depender de herramientas o abstracciones de terceros. Todos los pasos de enumeración y explotación se ejecutan utilizando PowerShell nativo y llamadas directas a la Graph API para garantizar que cada fase de la ruta de ataque sea totalmente transparente y esté técnicamente explicada.
NOTA: Por defecto, todos los usuarios autenticados en Entra ID pueden consultar los datos básicos del perfil de otros usuarios, y atributos como extensionAttribute1–15
no están clasificados como sensibles. Como resultado, el indicador almacenado en el perfil del administrador puede recuperarse técnicamente de forma inmediata con la siguiente consulta a la API:
$uri = "https://graph.microsoft.com/v1.0/users/EntraGoat-admin-s1@334brf.onmicrosoft.com?`$select=onPremisesExtensionAttributes" $response = Invoke-MgGraphRequest -Uri $uri -Method GET $response.onPremisesExtensionAttributes.extensionAttribute1
Este comportamiento es intencional. El objetivo del EntraGoat no es ocultar la bandera, sino enseñar técnicas realistas de escalada de privilegios en entornos Entra ID. Es posible recuperar el indicador a través de una llamada directa a la API, pero el objetivo real es escalar privilegios, acceder al portal Azure como usuario administrador y ver el indicador en su interfaz de usuario, demostrando el control total sobre una identidad de Administrador Global. El indicador es un artefacto de juego, no el objetivo principal.
Invoke-MgGraphRequest -Uri 'https://graph.microsoft.com/v1.0/me?$select=id,userPrincipalName,onPremisesExtensionAttributes' | Select-Object @{n='UPN';e={$_.userPrincipalName}}, @{n='Id';e={$_.id}}, @{n='Flag';e={$_.onPremisesExtensionAttributes.extensionAttribute1}}
Paso 2: Enumeración
Dado que este es el primer escenario de la serie EntraGoat, recorreremos el proceso de enumeración y destacaremos las técnicas básicas de escalada de privilegios. En nuestros otros escenarios, asumiremos esta línea de base y nos centraremos directamente en la ruta de ataque principal, omitiendo los pasos de reconocimiento estilo CTF.
Con acceso inicial a david.martinez
comenzamos a buscar caminos para la escalada de privilegios. Nuestra primera tarea es entender qué acceso tiene la identidad comprometida.
Comenzamos comprobando si el usuario tiene asignado algún rol en el directorio(Figura 7).
En Get-MgRoleManagementDirectoryRoleAssignment
no revela ninguna función privilegiada, lo que confirma que david.martinez
no tiene acceso elevado por defecto. A continuación, examinamos la pertenencia a grupos (Figura 8).
El usuario sólo forma parte del grupo de inquilinos predeterminado, que se asigna a cada usuario de Entra ID para servicios de colaboración como SharePoint o Teams. No hay ruta de escalada de privilegios aquí tampoco.
También comprobamos si david.martinez
posee algún grupo, ya que los propietarios de grupos pueden añadirse a sí mismos como miembros y heredar los privilegios del grupo (como los roles asignados). Esta comprobación también devuelve un resultado vacío (Figura 9).
Sin embargo, la consulta sobre la titularidad de los principales servicios arroja un resultado(Figura 10).
david.martinez
posee el servicio principal Finance Analytics Dashboard
. Esto es importante porque los propietarios de las entidades de seguridad de servicio pueden gestionar las credenciales, incluida la adición de nuevos secretos para autenticarse como entidad de seguridad de servicio.
Comprobemos si el Finance Analytics Dashboard
tiene asignados permisos (Figura 11).
No hay ninguno configurado. A continuación, comprobamos si tiene asignados roles de directorio(Figura 12).
Vemos una asignación de rol, pero está representada sólo por un GUID. Cada rol incorporado en Entra ID está representado por un GUID, que es global y el mismo en todos los inquilinos de Entra ID. Puede ver todos los roles integrados oficiales y sus GUIDs aquí.
Para resolver el GUID en un nombre de rol legible, podemos canalizar la salida de Get-MgRoleManagementDirectoryRoleAssignment
a Get-MgRoleManagementDirectoryRoleDefinition
(Gráfico 13), que traducirá cada ID de rol asignado en su correspondiente nombre para mostrar.
Privileged Authentication Administrator
es un rol altamente sensible en Entra ID. Permite a su titular administrar los métodos de autenticación para todos los usuarios, incluyendo el restablecimiento de la configuración MFA, la configuración de FIDO2 y las opciones de inicio de sesión sin contraseña, y la modificación de las políticas clave que rigen cómo se autentican los usuarios. Por eso, un atacante, actuando como su propietario, querría sin duda añadirle un secreto de cliente y utilizarlo para influir en la cuenta de administrador global.
NOTA: Si ha seguido de cerca la fase de enumeración, es probable que se haya dado cuenta de la verbosidad y el esfuerzo manual necesarios cuando se utilizan los cmdlets nativos de Microsoft Graph. (¿Qué pasaría si tuviéramos 5[0] aplicaciones Entra en lugar de 1?) Esta es una de las principales limitaciones de depender únicamente de herramientas nativas. Los comandos a menudo devuelven datos de bajo nivel (como GUID) que requieren consultas adicionales para convertirse en información significativa.
Precisamente por eso, muchos marcos de enumeración automatizan estos procesos. Abstraen las consultas repetitivas y racionalizan el resultado, lo que permite agilizar el análisis de privilegios y la toma de decisiones. Por ejemplo, para mejorar la usabilidad podemos escribir funciones envolventes sencillas como Find-OwnedServicePrincipals
y Get-ServicePrincipalRoles
que están diseñados para automatizar el descubrimiento de la propiedad de SP y resolver las asignaciones de roles de directorio de manera más eficiente:
function Find-OwnedServicePrincipals { param([string]$UserId) # Get all service principals in tenant $allSPs = Get-MgServicePrincipal -All Write-Host "Found $($allSPs.Count) service principals in tenant" $ownedSPs = @() $checkCount = 0 # Check ownership of each service principal foreach ($sp in $allSPs) { $checkCount++ if ($checkCount % 50 -eq 0) { Write-Host "Checked $checkCount/$($allSPs.Count) service principals..." } try { $owners = Get-MgServicePrincipalOwner -ServicePrincipalId $sp.Id -ErrorAction SilentlyContinue if ($owners) { foreach ($owner in $owners) { if ($owner.Id -eq $UserId) { $ownedSPs += $sp Write-Host "OWNED SERVICE PRINCIPAL FOUND!" -ForegroundColor Red Write-Host " Name: $($sp.DisplayName)" -ForegroundColor Yellow Write-Host " SP ID: $($sp.Id)" -ForegroundColor Yellow Write-Host " App ID: $($sp.AppId)" -ForegroundColor Yellow break } } } } catch { continue } } return $ownedSPs } function Get-ServicePrincipalRoles { param([object]$ServicePrincipal) Write-Host "Checking roles for: $($ServicePrincipal.DisplayName)" # Check directory role assignments for the SP $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 Cyan } } else { Write-Host " No directory roles assigned" } return $roles }
Ahora, para descubrir todos los principales de servicio propiedad del usuario comprometido y enumerar sus roles asignados, podemos simplemente ejecutar Find-OwnedService Principals
como Figura 14 espectáculos.
Paso 3: Pivotar hacia el contexto del principal del servicio
Este paso resalta la razón central por la cual creamos este escenario y lo posicionamos primero en la serie: Los principales de servicio dan forma al panorama de la escalada de privilegios en Entra ID. El movimiento lateral hacia el contexto de seguridad de un Service Principal y su aprovechamiento para realizar operaciones privilegiadas es una técnica fundamental con la que todo defensor, atacante e investigador que trabaje con Entra ID debería estar familiarizado.
Añadamos un secreto de cliente al Finance Analytics Dashboard
principal de servicio para establecer el acceso de puerta trasera y autenticarse como el SP:
$secretDescription = "EntraGoat-Secret-$(Get-Date -Format 'yyyyMMdd-HHmmss')" $contraseñaCredencial = @{ DisplayName = $secretDescription EndDateTime = (Get-Date).AddYears(1) } $newSecret = Add-MgServicePrincipalPassword -ServicePrincipalId $SP.Id -PasswordCredential $passwordCredential # Guardar los detalles del secreto añadido $clientSecret = $newSecret.SecretText
A continuación, desconecte la sesión de usuario actual con Disconnect-MgGraph
construye las credenciales del cliente y se autentica utilizando la identidad de la entidad de seguridad del servicio a través de Connect-MgGraph
:
$secureSecret = ConvertTo-SecureString -String $clientSecret -AsPlainText -Force $credential = Nuevo objeto -TypeName System.Management.Automation.PSCredential -ArgumentList $SP.AppId, $secureSecret Connect-MgGraph -TenantId $tenantId -ClientSecretCredential $credential
Y efectivamente, ahora estamos autentificados como la Finance Analytics Dashboard
servicio principal (Figura 15).
En Get-MgContext
revela información sobre cómo se autentica la sesión actual de Microsoft Graph, lo que determina directamente el contexto de seguridad, el nivel de acceso y el modelo de permisos que se aplica. Centrémonos en los campos AuthType
y TokenCredentialType
ya que exponen la semántica central de identidad en Entra ID.
Tras autenticarse como david.martinez
, estos valores aparecieron como:
AuthType : Delegado TokenCredentialType : NavegadorInteractivo
Esto indica una sesión delegada, donde el token emitido representa una identidad de usuario. El acceso se rige por los roles asignados al usuario y los permisos delegados, y todas las operaciones se realizan en nombre del usuario. El contexto de la sesión se limita a lo que la identidad del usuario tiene acceso, ya que hereda las políticas de acceso condicional, la aplicación de MFA y las restricciones de PIM.
Por el contrario, un contexto de aplicación exclusiva, como el iniciado por una entidad de seguridad de servicio utilizando credenciales de cliente (AppId
+ Secret
+ TenantId
) funciona como una identidad no humana. Cualquier cliente (script, trabajo en segundo plano, demonio) que utilice esas credenciales puede autenticarse como la aplicación e invocar las API de Microsoft Graph basándose en sus permisos de aplicación, independientemente del contexto del usuario. Las políticas de acceso condicional, MFA y PIM no son aplicables ni se aplican en este flujo.
Esta distinción es fundamental en el diseño de seguridad de identidades y explica por qué el comportamiento de la API, los ámbitos de acceso y los privilegios de los tokens difieren bajo los mismos cmdlets, dependiendo del contexto de la sesión.
Y como era de esperar, esta distinción tiene un gran impacto en la superficie de ataque y el potencial de abuso. Los flujos delegados están limitados por el contexto del usuario, mientras que los flujos exclusivos de aplicaciones funcionan con confianza a nivel de servicio y, a menudo, con límites de privilegios más amplios y menos controlados. Para los agresores, comprometer el secreto o el certificado de una aplicación suele suponer un acceso persistente y con privilegios elevados que elude los mecanismos de aplicación centrados en la identidad.
Paso 4: Adquisición de la cuenta: inicio de sesión como administrador global
Ahora que nos hemos autenticado como una identidad con el Privileged Authentication Administrator
tenemos la posibilidad de restablecer contraseñas (Figura 16) para cualquier usuario de la tenencia, incluido el Administrador global.
Con este nivel de acceso, también podemos asignar un TAP(Figura 17) como método de autenticación, lo que nos permite omitir MFA e iniciar sesión directamente en el portal de Azure:
A continuación, iniciamos sesión con el TAP(Figura 18).
A continuación, recuperamos la bandera del escenario(Figura 19).
Una vez completado el escenario, ejecutamos el script de limpieza para restaurar el inquilino EntraGoat a su estado original(Figura 20).
Conozca su eslabón más débil
Este escenario demuestra cómo configuraciones aparentemente legítimas y comunes, como asignar la propiedad de la aplicación a un usuario estándar, pueden abrir la puerta a un compromiso total del inquilino cuando se combinan con roles privilegiados.
Aprovechando la propiedad sobre un servicio principal, los atacantes pueden escalar privilegios, eludir las defensas centradas en el usuario, como MFA y el acceso condicional, y, en última instancia, obtener acceso de administrador global a través de un flujo exclusivo de aplicaciones.
Este ejercicio subraya la importancia crítica de una gobernanza sólida en torno a los permisos de las aplicaciones, la propiedad de los principales de servicio y la asignación de funciones. En los entornos de nube modernos, los principales de servicio son a menudo el eslabón más débil, y comprender su modelo de identidad dual, los límites de acceso y el potencial de abuso es esencial tanto para los atacantes como para los defensores.
El Escenario 1 de EntraGoat sienta las bases para seguir explorando, y para nuestros próximos escenarios. Así que ¡sigue hackeando!
Acepta tu próximo reto EntraGoat
- GitHub - Semperis/EntraGoat
- ¿Qué es EntraGoat? Un entorno de simulación de Entra ID deliberadamente vulnerable
- Primeros pasos con EntraGoat: Descifrar Entra ID de forma inteligente
- Escenario 2: Explotación de Permisos de App-Only Graph en Entra ID
Nota final
- https://github.com/BloodHoundAD/BARK
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.