Mientras jugaba con tickets Kerberos, descubrí un problema que me permitía autenticarme en otros dominios dentro de un bosque de Active Directory (AD) a través de confianzas externas no transitivas. Esto significa que, de hecho, no existe una "confianza no transitiva". El término es, en el mejor de los casos, engañoso y ofrece a los administradores de sistemas una falsa sensación de seguridad. Como parte del problema discutido en este post, los atacantes pueden autenticarse en otros dominios a través de una confianza no transitiva y potencialmente elevar privilegios dentro del bosque del dominio de confianza. Este artículo detalla el problema descubierto.
Tras informar de este problema a Microsoft, recibí la siguiente respuesta:
Dado que Microsoft ha determinado que el problema no afecta a la seguridad y, por tanto, no tiene previsto cambiar el comportamiento, no hay forma de evitar el problema, aparte de simplemente no utilizar confianzas externas.
Confinzas y transitividad
Nota: Este artículo presupone un conocimiento básico de las confianzas y su funcionamiento. (Para más información sobre estos temas, sugiero leer el magnífico post de Will Schroedersobre las confianzas). El artículo no cubre las confianzas intra-bosque (es decir, las confianzas dentro de un mismo bosque) -aparte de las que se aplican a la ruta de ataque específica discutida- o las confianzas de autenticación selectiva - que son increíblemente raras en entornos reales.
El resto de confianzas son confianzas de bosque y confianzas externas.
- Las confianzas de bosque son confianzas entre dos bosques. Más exactamente, son confianzas transitivas entre los dominios raíz de dos bosques. Cualquier usuario de cualquier dominio del bosque de confianza puede autenticarse en cualquier dominio del bosque de confianza.
- Las confianzas externas son confianzas entre dos dominios. Estas confianzas no son transitivas. Sólo los usuarios del dominio de confianza pueden autenticarse en el dominio de confianza(Figura 2).
Microsoft describe la transitividad de confianza del siguiente modo:
La transitividad determina si una confianza puede extenderse fuera de los dos dominios con los que se formó.
- Una confianza transitiva puede utilizarse para ampliar las relaciones de confianza con otros dominios.
- Una confianza no transitiva puede utilizarse para denegar relaciones de confianza con otros dominios.
Esta descripción es clara: para las confianzas no transitivas, sólo los dos dominios implicados en la confianza pueden autenticarse entre sí y no más allá.
Por desgracia, como demostraré en este post, no es así.
Configuración de Lab
Para demostrar adecuadamente el problema de la confianza no transitiva, configuré el lab con varios bosques multidominio que comparten confianzas externas(Figura 3).
Esta configuración incluye tres (3) bosques. Dos (2) de los bosques contienen tres (3) dominios. El tercer bosque contiene dos (2) dominios. Los dominios semperis.lab y treetest.lab comparten una confianza externa bidireccional no transitiva(Figura 4).
Los dominios grandchild1.child1.semperis.lab y semperisaz.lab también comparten una confianza externa bidireccional no transitiva(Figura 5).
Esta configuración permite demostrar las implicaciones y limitaciones de la cuestión de la confianza no transitiva.
Funcionamiento de la autenticación cruzada Kerberos
Para autenticarse en un servicio a través de una confianza utilizando Kerberos, necesita un ticket de referencia (también conocido como ticket de concesión de ticket de referencia [TGT]). Se trata de un vale solicitado a su controlador de dominio (DC) local para el dominio extranjero. Para demostrar cómo se realizan las solicitudes de vales a través de las confianzas, esta sección se centra en el bosque semperis.lab. Sin embargo, esta información es aplicable a cualquier ruta de confianza "permitida".
Nota: Este post asume una comprensión básica del flujo normal de autenticación Kerberos. (Para una explicación detallada de ese flujo, véase el post de Sean MetcalfDetección de actividad de Kerberoasting). El resto del artículo utiliza Rubeus para solicitar tickets manualmente.
El ejemplo más sencillo de autenticación de confianza cruzada es la autenticación de un servicio en un dominio que tiene una confianza directa con el dominio local. La confianza que el dominio grandchild1.child1.semperis.lab tiene con child1.semperis.lab(Figura 5) es un ejemplo de este tipo de confianza. En esta situación, después de obtener un TGT inicial, el primer paso para obtener un ticket de servicio para una cuenta en grandchild1.child1.semperis.lab para un servicio en child1.semperis.lab es obtener una referencia para child1.semperis.lab (Figura 6, Figura 7).
La solicitud se realizó a un DC(SGC1DC1.grandchild1.child1.semperis.lab) dentro del dominio (grandchild1.child1.semperis.lab) local del usuario autenticador(lowpriv). La solicitud se realizó para el servicio krbtgt/child1.semperis.lab. El hecho de que el ServiceRealm (srealm) sea el dominio local (grandchild1.child1.semperis.lab) dentro del ticket resultante muestra que este ticket es una referencia.
Esta referencia puede utilizarse ahora para solicitar tickets de servicio (STs) al DC extranjero (SC1DC1.child1.semperis.lab) para el servicio host/SC1DC1.child1.semperis.lab (Figura 8, Figura 9).
Para ir un paso más allá, si se requiere un servicio en el dominio raíz del bosque(semperis.lab), no se puede solicitar directamente una referencia para este dominio desde el dominio local(grandchild1.child1.semperis.lab). Se solicita una referencia para krbtgt/semperis.lab desde el DC local sgc1dc1.grandchild1.child1.semperis.lab. Sin embargo, el DC devuelve un ticket para el servicio krbtgt/niño1.semperis.lab, indicando que esta referencia es para el dominio child1.semperis.lab, no para semperis.lab (Figura 10, Figura 11).
Puede ver este problema intentando utilizar este ticket para solicitar un ST para el dominio semperis.lab. Al hacerlo, se produce un error AP_ERR_BAD_INTEGRITY. Esto se debe a que el ticket de referencia está cifrado con la clave de confianza para la confianza grandchild1.child1.semperis.lab->child1.semperis.lab. Los DC del dominio raíz semperis.lab no conocen esta clave y, por lo tanto, no pueden descifrar el ticket(Figura 12, Figura 13).
Para solicitar un ticket de servicio para el dominio raíz semperis.lab, primero se debe solicitar una referencia para semperis.lab a un DC del dominio child1.semperis.lab, utilizando esta referencia. Las figuras 14 y 15 muestran una solicitud realizada al DC extranjero(sc1dc1.child1.semperis.lab), utilizando la referencia para el dominio child.semperis.lab para solicitar otra referencia para el dominio raíz semperis.lab.
Tenga en cuenta que para solicitar este ticket, el argumento /dominiodestino es necesario. Por defecto, Rubeus utiliza el dominio dentro del ticket que se le ha pasado para rellenar el dominio en la TGS-REQ. En este caso, ese dominio sería grandchild1.child1.semperis.laby produciría un error ERR_WRONG_REALM porque el dominio local del DC es child1.semperis.lab. Esta información será importante en la siguiente sección.
Por último, esta referencia resultante para semperis. lab puede utilizarse para solicitar ST para el dominio semperis.lab. La figura 16 muestra la solicitud de ST realizada desde el usuario lowpriv@grandchild1.child1.semperis.lab al DC SDC1.semperis.lab para el host SPN/SDC1.semperis.lab. Debido a que la ruta de confianza está permitida, esta solicitud tuvo éxito a pesar de que los dos dominios involucrados no tienen una confianza directa(Figura 17).
Este método de solicitud de referencias para dominios de confianza puede seguirse para solicitar ST para cualquier servicio dentro de cualquier dominio para el que se permita la ruta de confianza.
Hacer transitiva la confianza no transitiva
Entonces, ¿cómo es posible atravesar confianzas externas para autenticarse en dominios que deberían estar prohibidos?
Los dominios semperisaz.lab y grandchild1.child1.semperis.lab tienen una confianza externa bidireccional. Por lo tanto, después de recuperar un TGT para cualquier cuenta dentro del dominio semperisaz.lab, es posible solicitar una referencia para grandchild1.child1.semperis.lab(Figura 18, Figura 19).
Esta referencia puede ser utilizada para solicitar STs para servicios en el dominio grandchild1.child1.semperis.lab. Sin embargo, un intento de obtener una referencia a otros dominios dentro del mismo bosque (por ejemplo, child1.semperis.lab) devuelve un error ERR_PATH_NOT_ACCEPTED, como era de esperar(Figura 20).
Este error se produce porque la confianza semperisaz.lab ->granchild1.child1.semperis.lab no es transitiva. Por lo tanto, la ruta de semperisaz.lab a child1.semperis.lab no está permitida(Figura 21).
Sin embargo, puede solicitar un TGT local para grandchild1.child1.semperis.lab. Llamo a esto un TGT local porque, a diferencia de la referencia, que tiene un ServiceRealm (srealm) de semperisaz.lab,el ServiceRealm de este TGT es grandchild1.child1.semperis.lab(Figura 22, Figura 23).
Utilizando este TGT local, ahora se puede solicitar una referencia para child1.semperis.lab(Figura 24, Figura 25).
Ahora tiene una referencia utilizable que se puede utilizar para solicitar ST para child1.semperis.lab, utilizando cualquier cuenta del dominio semperisaz.lab y sin realizar ningún cambio en las confianzas o cuentas dentro de AD. Las figuras 26 y 27 muestran una solicitud de ST desde el DC sc1dc1.child1.semperis.lab para el servicio host/sc1dc1.child1.semperis.lab como el usuario lowpriv@semperisaz.lab.
Además, este método se puede utilizar para saltar por cualquier dominio dentro del mismo bosque en el que existe grandchild1.child1.semperis.lab. Podemos demostrarlo solicitando una referencia al dominio raíz semperis.lab. Se solicitó una referencia para semperis.lab desde el DC sc1dc1.child1.semperis. lab como el usuario lowpriv@semperisaz.lab(Figura 28, Figura 29).
Afortunadamente, saltar a través de más confianzas fuera del bosque (confianzas externas o de bosque) no es posible utilizando este método. Como muestra la Figura 3, el dominio raíz semperis.lab tiene una confianza externa bidireccional con treetest.lab. Esta confianza puede utilizarse para demostrar esta limitación(Figura 30, Figura 31).
Esto al menos evita que un atacante que utilice este método salte de confianza a otro bosque. Aún así, este problema de confianza no transitiva es claramente útil para los atacantes que intentan elevar privilegios dentro de un bosque a través de una confianza. Los atacantes podrían consultar información de dominios supuestamente no permitidos, consultar dominios más sensibles o dominios con una seguridad potencialmente más débil, o realizar ataques Kerberoasting o coerción de autenticación NTLM en dominios que se supone que no están permitidos.
Saltar más lejos
Aunque los atacantes no pueden saltar más allá utilizando sólo el método descrito en este post, el problema podría abrir nuevas vías de ataque. Anteriormente escribí un post demostrando la capacidad de crear cuentas de máquina a través de confianzas y las implicaciones de ello. Al incorporar ese método de salto de dominio con este nuevo método, es posible superar la limitación descrita al final de la sección anterior.
Utilizando la referencia recuperada para semperis.lab (al final de la sección anterior), es posible solicitar un ticket para el servicio LDAP en un DC en semperis.lab. Aquí, se solicitó un ST para ldap/sdc1.semperis. lab utilizando la referencia para semperis.lab como el usuario lowpriv@semperisaz.lab(Figura 32, Figura 33).
Este ST puede ser inyectado y usado para crear una cuenta de máquina directamente en semperis.lab si la configuración permite Usuarios Autenticados, que es el valor por defecto(Figura 34).
Esta acción hace que el DC sdc1.semperis.lab cree la cuenta de máquina TestComp dentro del dominio semperis.lab(Figura 35).
La nueva cuenta de máquina TestComp es una cuenta local dentro del dominio semperis.lab. Ahora, puede recuperar un TGT para esa cuenta de máquina(Figura 36, Figura 37).
A esta cuenta de máquina TGT se le permite solicitar una referencia al dominio de confianza treetest.lab. La cuenta de máquina TGT puede utilizarse para solicitar una referencia para el dominio treetest.lab desde el DC SDC1.semperis.lab (Figura 38, Figura 39).
Por último, el problema descrito en este post se puede utilizar para obtener acceso al dominio inaccesible dsptest.lab. En primer lugar, solicite un TGT local para treetest.lab. El TGT local se solicita utilizando la referencia para treetest.lab como la cuenta TestComp$@semperis.lab del DC TDC1.treetest.lab(Figura 40, Figura 41).
A continuación, utilice este TGT local para solicitar una referencia para dsptest.lab. Las figuras 42 y 43 muestran que se ha solicitado una referencia para el dominio dptest.lab desde el DC TDC1.treetest.lab como el usuario TestComp$@semperis.lab.
Claramente, la combinación de estos dos métodos podría hacer posible saltar muy profundo en las infraestructuras empresariales de AD, utilizando cualquier cuenta de bajo privilegio en un dominio que tiene una confianza externa para cualquier dominio dentro de un bosque.
Detección de la vulnerabilidad de la transitividad de la confianza
Lamentablemente, dada la respuesta de Microsoft, la única forma de evitar el problema es eliminar las confianzas externas.
Si no es posible eliminar todas las confianzas externas, tendrá que supervisar el evento de Windows 4769(Se solicitó un ticket de servicio Kerberos). La primera indicación que debe buscar es que se haya solicitado un ticket de servicio Kerberos local a una cuenta de un bosque diferente(Figura 44).
Aquí, el campo Dominio de cuenta es un dominio que pertenece a un bosque diferente y el Nombre del servicio es krbtgt. A este evento le sigue otro evento 4769, solicitando una referencia(Figura 45).
Aquí, el Dominio de la cuenta es un dominio dentro de un bosque diferente y el Nombre del servicio es otro dominio dentro del bosque local.
Tenga en cuenta que estos dos eventos pueden ocurrir en diferentes DCs dentro del mismo dominio. Los eventos no necesitan ocurrir en el mismo DC. En este punto, cualquier ST solicitado (evento 4769) que utilice esta referencia tendrá un Dominio de cuenta que contiene un dominio al que no se le debe permitir autenticarse en el dominio local.
Busque la supervisión de estos eventos y la detección de este tipo de ataque en una futura versión de Semperis Directory Services Protector (DSP).
¿En quién puede confiar?
Como puede ver, la descripción oficial de las confianzas externas no transitivas es engañosa. Tal y como está, cuando crea una confianza externa no transitiva, debe aceptar que cualquier cuenta dentro del dominio de confianza podrá autenticarse en cualquier dominio dentro de todo el bosque en el que reside el dominio de confianza .
Como se demostró en la sección de este post "Saltar Más Allá", la mejor práctica es no permitir a los Usuarios Autenticados crear cuentas de máquina. No hacerlo no sólo pone los dominios dentro del bosque en mayor riesgo de ataque, sino que también pone cualquier dominio (y el bosque en el que residen) que tienen una confianza externa con cualquier dominio dentro del bosque en mayor riesgo debido a la capacidad de crear cuentas de máquina a través de confianzas y autenticando contra dominios que deben ser desautorizados. (Se puede encontrar más información sobre la cuota de cuentas de máquina y cómo prevenir la creación de cuentas de máquina con pocos privilegios en el excelente post de Kevin Robertson"La cuota de cuentas de máquina es ÚTIL a veces").
Aunque sólo sea eso, espero que este post informe a los administradores de sistemas del riesgo real a nivel de todo el bosque que implica la implementación de confianzas externas.
Cronología
- 4 de mayo de 2022: creación del caso MSRC
- 12 de mayo de 2022: El estado del caso cambia a "Review/Repro".
- 17 de junio de 2022: El estado del caso cambia a "Develop" con un correo electrónico que dice "Hemos confirmado el comportamiento del que nos informó. Continuaremos nuestra investigación y determinaremos cómo abordar este problema".
- 17 de junio de 2022: El estado del caso cambia a "Complete – Resolved".
- 24 de agosto de 2022: Se deja un comentario sobre el caso para conocer su estado.
- 2 de septiembre de 2022: Se deja un comentario de seguimiento del caso para conocer su estado.
- 14 de septiembre de 2022: Envío de correo electrónico de seguimiento para conocer el estado del caso.
- 29 de septiembre de 2022: Recepción de un correo electrónico en el que se explica que no se ha determinado que el problema afecte a la seguridad.
- 7 de marzo de 2023: Divulgación pública
Agradecimientos
- Will Schroeder por la creación de Rubeus, sin el cual esta investigación no habría sido posible
- A todos los que revisaron este post y aportaron sus comentarios, incluidos:
- Elad Shamir
- Harjinder Nijjar
- Andrew Schwartz
- Jonny Johnson
Más información
¿Quiere más investigaciones sobre seguridad de AD? Consulte estos artículos.