Descubriendo rutas de ataque indirectas a controladores de dominio virtualizados en Azure
Descubriendo rutas de ataque indirectas a controladores de dominio virtualizados en Azure
Sep 24, 2026
En Netwrix Security Research, ayudamos a un cliente con una evaluación de Entra ID y sabíamos que ya habían hecho la segmentación de AD localmente. También sabíamos que tenían controladores de dominio virtualizados en Azure, pero era difícil identificar cuál servidor Windows era realmente un DC. Descubrimos que Azure Run Command permite ejecutar comandos como SYSTEM, así que lo usamos para hacer reconocimiento e identificar los DC.
Todo lo mostrado en esta publicación (capturas de pantalla, nombres de máquinas, nombres de usuario) proviene de un entorno de laboratorio que reconstruimos después para demostrar la técnica. Ninguno es dato de clientes.
Para contexto, la propia documentación de Microsoft describe Run Command como una forma de ejecutar scripts de PowerShell dentro de una VM de Windows a través del agente de VM, principalmente para tareas generales de gestión como solucionar problemas de acceso o de red en una máquina. Sin embargo, no verifica qué tipo de VM está usando. Funciona igual de bien en un controlador de dominio que en cualquier otra VM.
Decidimos crear un script de PowerShell con Claude que nos permite ejecutar un comando en varias máquinas Windows a la vez, en lugar de usar la consola Ejecutar comando una VM a la vez. Solo necesitas el permiso Microsoft.Compute/virtualMachines/runCommand/action, que se incluye con Virtual Machine Contributor o superior.
El truco es ejecutar cada llamada a Invoke-AzVMRunCommand dentro de un ThreadJob en lugar del habitual Start-Job. Start-Job inicia un proceso PowerShell nuevo por cada VM y recarga el módulo Az cada vez, por lo que se ralentiza rápido al superar unas pocas máquinas. ThreadJob se ejecuta en un hilo dentro del mismo proceso, así que lanzar varios a la vez apenas añade coste. Mantenemos una cola con todas las VMs encontradas y la llenamos hasta un número fijo en ejecución simultánea (20 por defecto). Reponemos una plaza en cuanto termina una, sin esperar a que acabe todo un lote para empezar el siguiente.
Así es como se ve ejecutar whoami a través del portal para una máquina a la vez:
Ahora este mismo comando se ejecuta en todas las máquinas virtuales de la suscripción a la vez, mediante el script de PowerShell:
Con eso funcionando, el siguiente paso fue encontrar los DC. La verificación es simple: ejecutar Get-Service NTDS en cada VM de Windows activa mediante Run Command. NTDS es el servicio que administra la base de datos AD DS, así que si está presente y activo, esa máquina es un controlador de dominio.
Una máquina virtual estaba claramente en funcionamiento, pero Run Command falló al intentar acceder a ella, mientras que todas las demás máquinas virtuales en la suscripción respondieron correctamente. El nombre ya era una pista clara. El fallo de Run Command encaja perfectamente con lo que esperarías de un controlador de dominio bien protegido, con herramientas de seguridad más estrictas interfiriendo. Tomar ese error al pie de la letra y continuar habría significado reportar cero controladores de dominio en la suscripción.
En lugar de confiar en el error, preguntamos directamente a AD. Cualquier VM unida al dominio que Run Command aún pueda alcanzar se usa para consultar AD vía LDAP. No se necesita módulo de Active Directory, solo [adsisearcher], un acelerador de tipo PowerShell incorporado que ya funciona en cualquier equipo unido al dominio.
La verificación es un bit userAccountControl llamado SERVER_TRUST_ACCOUNT, valor 8192. AD solo lo establece una vez que un equipo ha sido promovido a DC. Añadimos dos verificaciones más: grupo principal 516 (el grupo "Domain Controllers") y un objeto NTDS Settings correspondiente en la partición de Configuración.
Una cosa: un nombre de host coincidente por sí solo no prueba que sea esta VM, ni siquiera que esté en Azure. Los nombres cambian, se truncan y a veces se reutilizan. Por eso primero verificamos la IP, resolviendo el nombre del DC a una IP desde dentro del dominio y comparándola con la IP privada que Azure reporta para esa VM. Esa IP solo existe si la máquina realmente está en Azure, así que una coincidencia ahí es lo más fiable. Cuando DNS no resuelve, comparamos nombres de host, aunque consideramos esa opción menos fiable porque los nombres pueden cambiar de formas que las IP no.
Una vez que pudimos confirmar con certeza que la máquina que había fallado antes era un controlador de dominio, la verdadera pregunta fue quién podía ejecutar comandos arbitrarios como SYSTEM en ella, ya que ese tipo de acceso es de nivel Tier-0, punto. No es quien tiene Domain Admin; el cliente ya había revisado eso con su jerarquía. Es quien tiene permisos de Azure en esa VM específica, porque Run Command no se preocupa por nada en AD. Solo le importa Azure RBAC.
Así es como se ve. Un puñado de usuarios aparece más de una vez (una fila por rol), junto con un grupo y dos principales de servicio, todos con Owner o Contributor en algún lugar de la cadena, la mayoría heredados de la Suscripción y no asignados directamente en la VM. Cada uno de ellos puede invocar Run Command contra un controlador de dominio y ejecutar código como SYSTEM. Nada de esto tiene que ver con quiénes están realmente en Domain Admins on-prem.
En este punto, el script también pregunta si deseas generar un gráfico al estilo BloodHound a partir de estos datos para visualizar qué principales de seguridad tienen un camino, directo o indirecto, hacia un controlador de dominio virtualizado en Azure. En nuestro laboratorio, son 12 principales con camino al DC, la mayoría heredados de la suscripción y no asignados directamente a la VM. Haz clic en cualquier nodo y la barra lateral detalla exactamente qué es y cómo llegó allí, incluyendo la membresía de grupo, así que un nodo de Grupo que muestra "3 miembros" no es solo un conteo. Puedes ver realmente quién está dentro.
Recomendación
Etiqueta tus Controladores de Dominio en Azure con algo como Tier-0-OnPrem-AD en el recurso de la VM. Parece obvio, pero la mayoría de los entornos que hemos visto no lo hacen, por eso identificarlos requirió un trabajo real en lugar de solo filtrar por etiqueta. Una vez etiquetados, puedes crear una política: negar nuevas asignaciones de Propietario o Colaborador en cualquier cosa con esa etiqueta, o alertar cuando cambie.
Sin embargo, el etiquetado solo te indica lo que sucede en adelante. No corrige lo que ya existe. Todos los entornos que hemos revisado han acumulado permisos en estas máquinas virtuales con el tiempo, la mayoría heredados del grupo de recursos o suscripción, no asignados directamente. Por eso es fácil pasarlo por alto.Revisa quién tiene acceso actualmente y pregunta, para cada persona y principal de servicio, si todavía necesitan ser Propietario o Colaborador en una máquina que es un controlador de dominio.
Una vez configurado, filtrar es solo añadir la columna de nivel o escribir Tier-0-OnPrem-AD en la barra de filtro, y aparecerán todos los DC. No se necesita script. Lo que nos tomó toda una tubería de enumeración ahora es un filtro de dos clics para cualquiera del equipo.
Referencias
- Microsoft Learn: Ejecute scripts en una VM de Windows en Azure usando la acción Ejecutar comandos
https://learn.microsoft.com/en-us/azure/virtual-machines/windows/run-command - Microsoft Learn: Servicio de metadatos de instancia de Azure para máquinas virtuales
https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service
Compartir en
Aprende más
Acerca del autor
Huy Kha
Director de Investigación de Seguridad
Aprende más sobre este tema
Intune todavía no puede hacer una imagen bare-metal de un dispositivo, y otras cosas que nadie le dijo a IT
Leyes de Privacidad de Datos por Estado: Diferentes Enfoques para la Protección de la Privacidad
¿Qué es la gestión de registros electrónicos?
Crear usuarios de AD en masa y enviar sus credenciales por correo electrónico usando PowerShell
Cómo crear, cambiar y probar contraseñas usando PowerShell