Charlie Clark

Mientras ayudaba a Andrew Schwartz con su post sobre Kerberos FAST (que tiene más información sobre qué es FAST y cómo funciona, así que léelo), me di cuenta de algo interesante. Las AS-REQs para cuentas de máquina no están blindadas. El blindaje de Kerberos es descrito por Microsoft:

El blindaje Kerberos utiliza un vale de obtención de ticket (TGT) para el dispositivo para proteger los intercambios de servicios de autenticación con el KDC, por lo que el intercambio de servicios de autenticación del ordenador no está blindado. El TGT del usuario se utiliza para proteger sus intercambios de TGS con el KDC.

Esto me hizo preguntarme si era posible solicitar tickets de servicio (ST) al servicio de autenticación (AS). La posibilidad de solicitar ST al servicio de autenticación tiene varias consecuencias, como nuevas vías de ataque, elusión de detecciones y posible debilitamiento de los controles de seguridad. Todos los problemas de los que se habla en este artículo se comunicaron a Microsoft y se consideraron "debidos al diseño"(Figura 1).

Lecturas relacionadas

Resumen de Kerberos

En primer lugar, he aquí un resumen de alto nivel del flujo típico de Kerberos(Figura 2, procedente de ADSecurity):

  1. Una cuenta solicita un TGT al controlador de dominio (DC).
  2. El DC responde con un TGT, que tiene su propia clave de sesión.
  3. El TGT y su clave de sesión se utilizan para solicitar un ticket de servicio (ST) al DC.
  4. El DC responde con una ST, que tiene su propia clave de sesión.
  5. El ST y su clave de sesión se utilizan para autenticarse frente al servicio final.
  6. El servicio final concede o prohíbe el acceso.
Figura 2. Flujo típico de Kerberos Flujo típico de Kerberos (AD Security), que ilustra los pasos de la lista anterior
Figura 2. Flujo típico de Kerberos (ADSecurity) Flujo Kerberos típico (ADSecurity)

El hecho de que se emita una clave de sesión para cada billete es una característica importante para la siguiente investigación. Esta clave de sesión se devuelve a la cuenta solicitante dentro de una sección cifrada de la respuesta; el solicitante ya conoce la clave de cifrado.

Por ejemplo, la clave de sesión TGT se almacena dentro de una sección cifrada con la clave utilizada para demostrar la identidad del solicitante al pedir un TGT. Esta clave es normalmente la clave a largo plazo (hash de la contraseña) de la cuenta. Pero en el caso de la Criptografía de Clave Pública para la Autenticación Inicial (PKINIT) en el protocolo Kerberos, la clave se deriva del certificado. La clave de sesión ST se almacena dentro de una sección cifrada con la clave de sesión TGT.

La clave de sesión del ticket es necesaria para utilizar el ticket en el siguiente paso del flujo Kerberos.

Una solicitud Kerberos tiene dos secciones principales:

  • padata (datos previos a la autenticación)
  • req-body (cuerpo de la solicitud)

El req-body se envía mayoritariamente en texto plano y contiene varios datos:

  • kdc-options: varias opciones
  • cname: nombre de la cuenta solicitante (opcional)
  • dominio: nombre de dominio
  • sname: nombre principal de servicio (SPN) para el ticket resultante (opcional)
  • desde: hora a partir de la cual el cliente desea que el billete sea válido (opcional)
  • hasta: tiempo hasta el que el cliente desea que el billete sea válido
  • rtime: la hora de renovación solicitada (opcional)
  • nonce: número aleatorio
  • etype: lista de tipos de cifrado soportados por el cliente
  • direcciones: lista de direcciones del cliente solicitante (opcional)
  • enc-authorization-data: varias secciones de datos de autorización, cifradas con la clave de sesión que se suele utilizar para los privilegios locales (opcional)
  • additional-tickets: lista de entradas necesarias para la solicitud (opcional)

Una respuesta Kerberos tiene varias secciones y contiene una parte cifrada:

  • pvno: número de versión
  • msg-type: tipo de mensaje (11 AS, 13 TGS)
  • padata: datos de preautenticación (opcional)
  • crealm: nombre de dominio del cliente
  • cname: nombre de la cuenta solicitante
  • ticket: ticket resultante
  • enc-part: datos encriptados para uso del cliente

El problema de los tickets de servicio solicitados por AS

La parte del flujo Kerberos en la que se centra este artículo es AS-REQ/AS-REP, que normalmente se utiliza para solicitar un TGT. En operaciones normales, un AS-REQ tiene uno de dos valores en su campo sname dentro del req-body:

  • krbtgt/domain.local: se utiliza para solicitar un TGT inicial
  • kadmin/changepw: se utiliza para solicitar un ticket de corta duración, que puede utilizarse para restablecer contraseñas mediante un mensaje KRB-PRIV (definido en RFC 3244).

Me di cuenta de que con la autenticación flexible de túnel seguro (FAST) de Kerberos aplicada, las cuentas de máquina seguían enviando sus AS-REQ sin blindaje. Me pregunté si se podría utilizar un AS-REQ para solicitar un ST directamente, en lugar de un TGT. Esto me llevó a modificar Rubeus para determinar si especificar otro SPN dentro del sname de un AS-REQ haría que el DC respondiera con un ST para ese SPN. Resultó que la respuesta era "sí"(Figura 3).

Figura 3. Captura de pantalla de un AS ST solicitado
Figura 3. Billete de servicio solicitado al SV

Utilizando una cuenta de máquina, puedo solicitar un ST sin utilizar el blindaje cuando se aplica FAST. ¿Qué más es posible?

Nuevas formas de Kerberoast

Kerberoasting, descubierto por Tim Medin, es un método para recuperar la contraseña en texto plano o hash NT de una cuenta de servicio, generalmente una cuenta de usuario con un SPN. Kerberoasting es posible porque parte de un ST está cifrado con la clave a largo plazo de la cuenta de servicio (hash de la contraseña). Al extraer la parte cifrada del ticket, es posible formar un hash a partir de varias contraseñas en texto claro e intentar descifrar la parte cifrada. Si el descifrado tiene éxito, entonces el hash utilizado es la clave a largo plazo utilizada para cifrar el billete. Esa clave puede utilizarse en última instancia para autenticarse como cuenta de servicio.

Además, cualquier cuenta puede solicitar una ST para cualquier servicio. Por lo tanto, se requiere la capacidad de autenticarse en Active Directory (AD) para realizar el ataque. Al menos, eso solía ser cierto.

Kerberoasting sin preautenticación

En primer lugar, he intentado utilizar una cuenta que no requería preautenticación(DONT_REQ_PREAUTH) para solicitar un ST. Cuando una cuenta no requiere preautenticación para autenticarse, se puede solicitar un TGT sin requerir datos de preautenticación, que se cifran con algún tipo de credencial (por ejemplo, hash de contraseña, certificado). Si un atacante no ha obtenido una credencial válida para una cuenta, no se puede generar una preautenticación válida. Si no se requiere preautenticación, esto no es un problema.

Cuando se solicita un billete sin autenticación previa, el resultado sigue incluyendo una parte cifrada. Esta parte cifrada se cifra con la clave de credencial utilizada para la autenticación y contiene la clave de sesión para el ticket incluido dentro de la respuesta. Estos son los datos cifrados utilizados en el ataque ASREPRoast de Will Schroeder. El TGT resultante sólo es utilizable con acceso a la clave de las cuentas solicitantes, ya que se requiere la clave de sesión del TGT.

Sin embargo, para Kerberoasting, el acceso a la clave de sesión no es necesario. Sólo se necesita la TS resultante, o más exactamente, la parte cifrada de la TS, que no está asegurada con la clave de la cuenta solicitante. Por lo tanto, si cualquier cuenta está configurada para no requerir pre-autenticación, es posible hacer Kerberoast sin ninguna credencial. Este método de Kerberoasting ha sido implementado en Rubeus dentro de este PR.

Demostración

Dado que aún no se ha conseguido el acceso a una cuenta válida, no se puede consultar LDAP. En su lugar, se requiere una lista de posibles cuentas de servicio. Investigaciones anteriores de Arseniy Sharoglazov demuestran que los ST pueden solicitarse utilizando únicamente el nombre de usuario de la cuenta de servicio en lugar de requerir el SPN real, algo muy útil para esta investigación.

Se puede generar una lista de nombres de usuario de varias formas, incluyendo la enumeración de usuarios utilizando sesiones nulas en un DC, generando una lista de nombres de usuario utilizando inteligencia de código abierto (OSINT), o adivinando nombres de usuario potenciales. Cualquier lista de nombres de usuario potenciales puede verificarse fácilmente enviando una AS-REQ sin preautenticación. Un nombre de usuario válido que requiere preautenticación recibe un error KDC_ERR_PREAUTH_REQUIRED(Figura 4).

Figura 4. Captura de pantalla que muestra un AS-REQ sin pre-auth para un nombre de usuario válido que requiere pre-auth
Figura 4. El usuario requiere autorización previa

Un nombre de usuario válido que no requiere preautenticación recibe un TGT(Figura 5).

Figura 5. Captura de pantalla que muestra la respuesta para un usuario que no requiere pre-autenticación
Figura 5. El usuario no necesita autorización previa

Un nombre de usuario no válido recibe un error KDC_ERR_C_PRINCIPAL_UNKNOWN(Figura 6).

Figura 6. Respuesta para un nombre de usuario no válido
Figura 6. El usuario no existe

Para fines de demostración, se genera una lista utilizando una sesión nula en el DC, utilizando el método de ciclado RID(-R) de enum4linux-ng, como muestra la Figura 7.

Figura 7. Captura de pantalla de la lista generada
Figura 7. Ciclo RID de enum4linux-ng

Utilizando esta lista de nombres de usuario, determinar las cuentas que no requieren preautenticación es fácil en AD(Figura 8).

Figura 8. Resultado de una búsqueda de cuentas que no requieren preautenticación
Figura 8. Búsqueda de cuentas que no requieren preautenticación

Tenga en cuenta que las AS-REQ sin preautenticación no se registran como un evento de Windows a menos que la cuenta no requiera preautenticación.

Con la lista de nombres de usuario y el nombre de usuario de una cuenta que no requiera preautenticación, se puede lanzar el ataque(Figura 9).

Figura 9. Captura de pantalla mostrando Kerberoasting sin pre-auth
Figura 9. Kerberoasting sin autorización previa

El resultado se puede utilizar para intentar descifrar contraseñas sin conexión.

Prueba de concepto: RoastInTheMiddle

Otra consecuencia interesante es la posibilidad de realizar Kerberoast desde una posición MitM ( Man-in-the-Middle ). Este tipo de ataque generalmente no es posible con TGS-REQs porque el campo opcional cksum dentro del autenticador dentro del AP-REQ protege el req-body de la petición y es frecuentemente incluido por clientes Kerberos Windows genuinos. Por lo tanto, modificar el sname de una TGS-REQ sin actualizar la suma de comprobación dentro del autenticador invalida la suma de comprobación del autenticador y devuelve un error KRB_AP_ERR_MODIFIED. Pero esto no es un problema para las AS-REQ porque el cuerpo de la req, y en consecuencia el campo sname, no están protegidos.

Mientras probaba este enfoque, descubrí que las AS-REQ pueden reproducirse muchas veces. Un atacante solo necesita capturar un AS-REQ para enviar muchos AS-REQ con diferentes valores de sname.

Demostración

Para demostrar este enfoque, escribí una prueba de concepto (POC). Este POC, RoastInTheMiddle, implementa un ARP spoof entre DCs y sistemas víctimas para realizar un ataque MitM. A continuación, el POC hace pasar el tráfico mientras escucha AS-REQs. Cuando se encuentra una AS-REQ, el POC realiza un Kerberoast. El POC no está preparado para el ataque, pero demuestra que es posible realizarlo.

En primer lugar, el POC inicia cuatro hilos, un sniffer, un ARP spoofer, un re-ensamblador (para peticiones que se dividen en varios paquetes) y el roaster(Figura 10).

Figura 10. Captura de pantalla que muestra el inicio del POC RoastInTheMiddle
Figura 10. Puesta en marcha de RoastInTheMiddle

Cuando ve una AS-REQ, el POC empieza a intentar hacer Kerberoast con la lista suministrada, que puede contener nombres de usuario o SPN(Figura 11).

Figura 11. Captura de pantalla del POC Kerberoasting
Figura 11. TostadoEnElMedio Kerberoasting

Como muestra la Figura 11, este intento da como resultado que cualquier ST recibido salga en formato hashcat, listo para descifrar contraseñas offline.

La capacidad de MitM AS-REQs, luego modificarlos y reproducirlos, también podría ser útil en el desarrollo de otros ataques. Intenté modificar las kdc-options para incluir la opción proxiable lo que resulta en un ticket con la bandera proxiable activada. Sin embargo, no pude encontrar una ruta de ataque utilizando ese ticket y esa bandera. Este comportamiento también podría permitir el uso de otras cuentas para realizar un Kerberoast, permitiendo a los atacantes evitar quemar una cuenta comprometida.

Mejoras

Algunas mejoras podrían ser posibles para este proceso. En primer lugar, es posible coaccionar una AS-REQ desde una TGS-REQ interceptándola y respondiendo con un error KRB_AP_ERR_BAD_INTEGRITY. Esto obliga al cliente a reautenticarse enviando una AS-REQ.

También debería ser posible realizar este ataque usando inyección de servidor de nombres DHCPv6 (como mitm6 por Dirk-jan Mollema o Inveigh por Kevin Robertson), respondiendo a consultas DNS SRV para el servicio LDAP y luego lidiando con la siguiente conexión LDAP.

El soporte para modificar los etypes dentro de la petición permite ataques de downgrade de tipo de cifrado cuando el entorno lo permite, como describe Will Schroeder aquí.

Por último, el POC requiere la instalación de Npcap en el sistema que ejecuta el POC (que utiliza sharppcap), principalmente para la suplantación de ARP. Si tomas la ruta IPv6 o implementas las respuestas ARP usando sockets raw, puedes eliminar esta dependencia.

Eludir detecciones

Muchas detecciones de Kerberos se basan en eventos 4769(Se ha solicitado un vale de servicio Kerberos). Sin embargo, solicitar un vale de servicio mediante una AS-REQ no produce 4769 eventos, sino 4768 eventos (Se solicitó un vale de autenticación Kerberos (TGT)).

La figura 12 muestra un evento 4768 cuando se solicita un ST utilizando un AS-REQ.

Figura 12. Imagen del suceso 4768
Figura 12. Evento 4768 para un ticket de servicio

Por lo tanto, los atacantes que utilizan este método pueden eludir fácilmente muchas detecciones que se basan en eventos 4769.

Otras consecuencias de los tickets de servicio solicitados por AS

Aunque no he podido solicitar los billetes de S4U2self al AS, los ST recuperados del AS carecen de la suma de comprobación del billete (introducida para proteger los billetes de S4U2self contra el ataque de bits de bronce de Jake Karnes).

Por último, una ST solicitada al TGS suele devolverse con un PAC(Figura 13).

Figura 13. Captura de pantalla de la solicitud de ST (con PAC) del TGS
Figura 13. Solicitud de un ST con un PAC al TGS

Es posible solicitar un ST sin un PAC del TGS, pero para ello es necesario cambiar el bit NO_AUTH_DATA_REQUIRED de las cuentas de servicio en el atributo useraccountcontrol(Figura 14).

Figura 14. Salida que muestra el atributo
Figura 14. atributo useraccountcontrol para SDC1 y pgreen

Con esta configuración, el ST devuelto carece de PAC, como muestra la diferencia de tamaño del billete devuelto(Figura 15).

Figura 15. Captura de pantalla de solicitud ST (sin PAC) de TGS
Figura 15. Solicitud de un ST sin PAC al TGS

Un ST sin PAC puede solicitarse al AS simplemente estableciendo la sección de datos PA-PAC-OPTIONS PA en false añadiendo el interruptor /nopac a Rubeus(Figura 16).

Figura 16. Salida que muestra la solicitud ST (sin PAC) del SV
Figura 16. Solicitud de un ST sin PAC al AS

Este enfoque podría utilizarse como alternativa a la creación de tickets plateados, solicitando un ST sin un PAC, y luego inyectando otro PAC incluyéndolo en la sección enc-authorization-data de la solicitud. También podría proporcionar otras posibles vías de ataque.

Detección de billetes de servicio solicitados por AS

Dado que Microsoft aparentemente no considera que valga la pena solucionar estos problemas, la única opción es la detección desde dentro de su organización. Como se ha mostrado anteriormente, cuando se solicita un ST al AS, se registra el evento 4768(Figura 17).

Figura 17. Captura de pantalla del evento 4768
Figura 17. Evento 4768 para un ticket de servicio

En este caso, se puede ver que el Nombre de Servicio y el ID de Servicio no son krbtgt . Todos los tickets auténticos solicitados al AS, incluidos los tickets kadmin/changepw, tienen un Nombre de Servicio y un ID de Servicio de krbtgt(Figura 18).

Figura 18. Captura de pantalla del evento normal 4768
Figura 18. Evento normal 4768

La comprobación del tráfico de red en busca de AS-REQs que no sean para krbtgt/domain o kadmin/changepw también debería detectar estas peticiones(Figura 19).

Figura 19. Captura de pantalla de la solicitud AS-REQ ST en Wireshark
Figura 19. Solicitud AS-REQ ST en Wireshark

Esta investigación, junto con la respuesta de Microsoft, demuestra la necesidad de una supervisión continua y de medidas de refuerzo adecuadas. La capacidad de eludir las detecciones actuales y realizar ataques eficaces, como Kerberoasting, desde una posición no autenticada es un problema grave que no debe ignorarse. La investigación aquí descrita podría dar lugar a nuevos ataques, lo que podría suponer un mayor riesgo para las organizaciones.

Asegúrese de que existen detecciones cuando se realizan este tipo de solicitudes de entradas.

Agradecimientos

Me gustaría agradecer a las siguientes personas su contribución a esta investigación:

Cronología

  • 25 de mayo de 2022: Informado al MSRC
  • 27 de mayo de 2022: MSRC cambia su estatus a Review/Repro
  • 13 de julio de 2022: MSRC respondió que el comportamiento fue "por diseño"
  • 27 de septiembre de 2022: divulgación pública

Más información sobre Semperis Research