Ghost

Ghost es una máquina Windows Active Directory de dificultad Insane que comienza con una inyección LDAP que un atacante puede aprovechar para filtrar las credenciales de una instancia de Gitea.

Analizando el código fuente de los repositorios, el atacante puede combinar una vulnerabilidad de lectura arbitraria de archivos con una vulnerabilidad de ejecución remota de código (RCE) para obtener acceso a un servidor Linux conectado al entorno de Active Directory.

Enumerando el sistema Linux, el atacante logra extraer un ticket Kerberos de un usuario de dominio, lo que le permite obtener acceso al propio Active Directory.

Dentro del dominio, el atacante puede crear una entrada DNS maliciosa para capturar el hash de otro usuario de dominio. Con este nuevo usuario comprometido, puede leer la contraseña GMSA de una cuenta de servicio relacionada con los servicios ADFS.

Comprometiendo esta cuenta de servicio, el atacante puede forjar una respuesta Golden SAML y conseguir acceso a un panel de gestión de bases de datos. Desde allí, explotando una base de datos MSSQL vinculada a un dominio diferente, puede ejecutar código en una máquina de ese segundo dominio.

Finalmente, elevando privilegios y aprovechando la relación de confianza bidireccional entre los dos dominios, el atacante puede crear un Golden Ticket Kerberos válido para ambos dominios, logrando así comprometer completamente todo el bosque de Active Directory.


Reconnaissance

Realizaremos un reconocimiento con nmap para ver los puertos que están expuestos en la máquina Ghost. Este resultado lo almacenaremos en un archivo llamado allPorts.

A través de la herramienta de extractPorts, la utilizaremos para extraer los puertos del archivo que nos generó el primer escaneo a través de Nmap. Esta herramienta nos copiará en la clipboard los puertos encontrados.

Lanzaremos scripts de reconocimiento sobre los puertos encontrados y lo exportaremos en formato oN y oX para posteriormente trabajar con ellos. Verificamos a través del resultado obtenido de que la máquina se trata de un Domain Controller (DC) por los puertos y servicios que se encuentran expuestos.

Transformaremos el archivo generado targetedXML para transformar el XML en un archivo HTML para posteriormente montar un servidor web y visualizarlo.

Accederemos a http://localhost y verificaremos el resultado en un formato más cómodo para su análisis.

A través de la herramienta de netexec y ldapsearch enumeraremos el equipo para localizar más información. Entre la información obtenida, verificamos el hostname, versión del SO y el nombre del dominio.

Añadiremos en nuestro archivo /etc/hosts las entradas correspondientes para que a la hora de hacer referencia al dominio o el equipo nos responda correctamente a la dirección IP del equipo.

Web Enumeration

Realizaremos una enumeración de las tecnologías presentes en las diferentes páginas web que hemos encontrado en diferentes puertos.

Al acceder a http://ghost.htb y https://ghost.htb verificamos que no muestra ningún tipo de contenido.

Cuando accedimos a http://ghost.htb:8008 nos mostró una página web del CMS Ghost.

Basado en NodeJS, Ghost es un software de gestión de contenidos enfocado a blogs, con multitud de integraciones y que permite una completa personalización del aspecto. En su conjunto, es una solución que resulta muy amigable para cualquier desarrollador.

Al acceder a https://ghost.htb:8443 se nos mostraba una página web de inicio de sesión con un botón el cual nos redirigía a federation.ghost.htb.

Añadiremos esta nueva entrada en nuestro archivo /etc/hosts.

Al tratar de acceder a https://federation.ghost.htb verificamos un panel de inicio de sesión del sitio web.

Realizaremos una enumeración de subdominios a través de la herramienta de ffuf con diferentes diccionarios, nos encontramos con los siguientes subdominios.

Después de una enumeración de subdominios de la página web, añadiremos las siguientes entradas en nuestro archivo /etc/hosts.

Al tratar de acceder a http://intranet.ghost.htb:8008 nos muestra un panel de inicio de sesión a lo que parece ser la Intranet del sitio web.

Al acceder a http://gitea.ghost.htb:8008 nos encontramos con el siguiente sitio web de la plataforma de Gitea.

Al investigar más en la página web de Gitea nos encontramos con dos nombres de usuarios que probablemente sean del Directorio Activo (AD).

Shell as Root

LDAP Injection

Interceptaremos la solicitud al intentar acceder al panel de intranet.ghost.htb y verificamos que al enviar la solicitud con el usuario test/test. Nos devuelve el siguiente mensaje en la respuesta del servidor. También verificamos que los campos del username y password tienen de nombre la variable algo relacionado con LDAP. Lo cual nos hace pensar que por detrás realiza una consulta en LDAP para validar el acceso a la Intranet.

Probaremos de inyectar el siguiente carácter ) para cerrar la query de LDAP y al enviar la solicitud, el servidor nos devuelve un mensaje informando que ha ocurrido un error.

Probaremos de realizar un Authenticacion Bypass indicándole el nombre de usuario cassandra.shelton que encontramos en el Gitea e indicándole como contraseña el carácter * con lo cual si no está bien configurado, se utilizará como comodín y rellenará el campo de la contraseña.

Al enviar esta solicitud, verificamos que se nos ha generado un Token en la respuesta del servidor, lo cual parece indicarnos que efectivamente hemos podido realizar el Bypass correctamente.

A través de la extensión de Cookie Editor añadiremos este nuevo Token en la página de http://intranet.ghost.htb:8008.

Al actualizar la página se nos muestra el acceso correspondiente a la Intranet. En la sección de noticias se nos indica lo siguiente.

En la sección News de intranet.ghost.htb, encontramos información sobre la migración de Gitea a Bitbucket. Los inicios de sesión con credenciales de dominio están deshabilitados, pero mencionan una cuenta gitea_temp_principal con un token almacenado en LDAP. También indican que, temporalmente, el acceso a la intranet requiere un token secreto en lugar de la contraseña de dominio.

Al acceder a la sección de Users, verificamos la existencia de los diferentes usuarios del dominio.

Nos guardaremos en un archivo, el listado de usuarios del dominio que hemos encontrado en la Intranet.

En la sección de Forums nos encontramos con la siguiente información.

En la sección News, encontramos que la migración de publicaciones desde la antigua intranet aún está en proceso, por lo que no es posible publicar o responder por el momento.

También identificamos una conversación donde un usuario intenta conectar con bitbucket.ghost.htb, pero recibe un error. Según una respuesta, el problema se debe a que la migración no ha finalizado y la entrada DNS aún no está configurada.

Además, hay publicaciones internas sobre logros del equipo y reconocimientos a investigadores, lo que indica una cultura organizativa activa en la intranet.

Recordando que en la sección de News habían indicado que el usuariogitea_temp_principal disponía de un token almacenado en LDAP. Por lo cual, lo que realizamos es un script de LDAP Injection para intentar obtener las credenciales válidas del usuario indicado a través de iniciar sesión en la Intranet que vimos anteriormente que era vulnerable a LDAP Injection.

Al ejecutar el script, verificamos que a través de fuerza bruta, logra encontrar carácter por carácter, lo que parece ser la contraseña del usuario mencionado.

Accederemos nuevamente a http://gitea.ghost.htb:8008 de autenticarnos con el usuario encontrado para verificar si disponemos del acceso que indicaban en la sección de News.

Verificamos que hemos logrado acceder correctamente al Gitea con el usuario gitea_temp_principal.

Ghost Blog Vulnerabilities

En los repositorios que dispone el usuario actual, verificamos de la existencia de los repositoris blog y intranet.

Al acceder al repositorioghost-dev/blog se nos indica en el archivoREADME.md lo siguiente.

En el README.md del repositorio en Gitea, encontramos información clave sobre el Ghost Blog, que utiliza Ghost CMS en un contenedor Docker.

Mencionan una futura integración con la intranet, donde algunas publicaciones serán destacadas o escaneadas. Para ello, han implementado una clave API compartida entre la intranet y el blog, almacenada como variable de entorno con el nombre DEV_INTRANET_KEY.

También han modificado el código fuente de Ghost CMS, en particular el archivo posts-public.js, para extraer más información de las publicaciones. Indican que, en el futuro, estos datos deberían almacenarse en una base de datos para evitar pérdidas al recrear los contenedores.

Además, han dejado expuesta una clave API pública que permite acceso a datos públicos en Ghost API, lo que podría ser útil para obtener más información del sistema.

Al acceder a revisar el archivo Dockerfile nos encontramos con el siguiente contenido.

Por otro lado, el archivo docker-compose.yml contiene la siguiente configuración.

Revisamos el último archivo que disponemos en el repositorio del Blog posts-public.js y nos encontramos con el siguiente resultado.

Using the Ghost API to retrieve Path Traversal vulnerability information

El siguiente paso será hacer uso de la API de Ghost, ya que según la información que recopilamos del Gitea, podíamos hacer uso de esta API a través de la API KEY que nos proporcionaron. Verificaremos el funcionamiento de la API a través de la documentación oficial del CMS.

En la documentación, comprobamos que nos aparece un ejemplo de como utilizar esta API.

Interceptaremos la solicitud en BurpSuite y verificaremos que si podemos hacer uso de la API correctamente.

Le pasamos al ChatGPT el contenido del archivo posts-public.js para verificar si tenía alguna vulnerabilidad y nos indicó que existía la posibilidad de realizar un Path Traversal a través del valor extra.

Trataremos de verificar si podemos revisar el contenido del /etc/passwd del equipo a través de la vulnerabilidad en combinación de la API de Ghost. Verificamos que hemos logrado leer el archivo indicado, por lo tanto, tenemos una vía para enumerar archivos del sistema.

Si volvemos a mirar el Gitea, recordaremos que se mos menciona que hay una API compartida entre la Intranet y el blog, almacenada como variable de entorno con el nombre de DEV_INTRANET_KEY.

/proc/self/environ es un archivo especial en sistemas Linux que contiene las variables de entorno del proceso que lo lee. Detalles clave:

Se encuentra en el sistema de archivos proc (/proc/), que es una interfaz al kernel. self es un enlace simbólico al directorio del proceso que lo accede. Contiene las variables de entorno en formato KEY=VALUE, separadas por \0 (carácter nulo).

Ejemplo de uso:

Si ejecutamos:

cat /proc/self/environ

Veremos algo como:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\0HOME=/root\0USER=root\0...

(Algunos valores pueden no verse bien porque están separados por \0).

Posibles riesgos

Si un proceso con permisos elevados expone su /proc/self/environ, un atacante podría leer variables sensibles como AWS_SECRET_KEY, DATABASE_PASSWORD, etc.

A través del Path Traversal revisaremos las variables de entorno al directorio del proceso que lo accede. Verificamos que nos muestra el contenido en la respuesta por parte del servidor.

Desde Cyberchef descodificaremos el contenido recibido y verificamos que logramos obtener la variable de entorno DEV_INTRANET_KEY que mencionaban en Gitea.

Using the Ghost API to perform command injection and gain access to the Docker machine

Revisaremos el repositorio de ghost-dev/intranet el cual contiene la siguiente información en el README.md.

Hemos encontrado información en el archivo README.md que indica que la intranet y el blog están en proceso de integración. Mientras el desarrollo continúa, han expuesto una API de desarrollo en http://intranet.ghost.htb/api-dev, lo que podría ser un punto de interés para futuras pruebas.

Nos descargaremos el repositorio de Intranet para revisar el contenido del repositorio de Intranet.

Del archivo comprimido .zip que nos hemos descargado, lo descomprimiremos y accederemos al directorio creado.

A través del comando tree visualizaremos la estructura de los archivos descargados del repositorio ghost-dev/intranet.eeeeeeeeeeeee

Realizaremos una búsqueda recursiva en todos los archivos para buscar en dónde hacen uso de la DEV_INTRANET_KEY. Verificamos que se hace uso de esta clave en el archivo dev.rs.

Este código implementa un guardia de acceso en Rocket, un framework web de Rust. La estructura DevGuard se utiliza para verificar si una solicitud tiene un encabezado específico, X-DEV-INTRANET-KEY, y si el valor de este encabezado coincide con la variable de entorno DEV_INTRANET_KEY.

Si la clave es correcta, se permite el acceso, y el guardia devuelve un Outcome::Success. Si la clave es incorrecta o no se proporciona, se devuelve un Outcome::Error con un estado de Unauthorized (401).

Este guardia protege las rutas que requieren una clave de autenticación para acceder.

Por otro lado, nos encontramos con el siguiente archivo scan.rs que se utiliza para lo siguiente.

Este código implementa una ruta en Rocket que permite escanear URLs en publicaciones de un blog. La ruta scan recibe una solicitud POST con una URL en formato JSON, utilizando la estructura ScanRequest.

El flujo de funcionamiento es el siguiente:

  1. Autenticación: Primero, se verifica que la solicitud tenga una clave válida de acceso (DevGuard).

  2. Comando Bash: Luego, se ejecuta un comando en Bash con la URL proporcionada. Este comando intenta llamar a un script (intranet_url_check) que debería verificar si la URL es segura.

  3. Respuesta: Dependiendo del resultado de la ejecución del comando, la función responde con un JSON que contiene:

    • is_safe: Indica si la URL es segura (actualmente siempre es true).

    • temp_command_success: Informa si el comando se ejecutó correctamente.

    • temp_command_stdout y temp_command_stderr: Muestran las salidas estándar y de error del comando ejecutado.

Este endpoint está diseñado para ser utilizado por el blog para verificar la seguridad de las URLs de los posts.

Le pasaremos el archivo scan.rs al ChatGPT para verificar si existen algunas vulnerabilidades en el archivo. En el resultado obtenido, verificamos que podemos realizar un Command Injection a través de la entrada de data.url.

Por lo tanto, lo que probaremos es de acceder al sistema a través de una Reverse Shell, para ello nos ponemos en escucha con nc.

Ejecutamos el siguiente comando para aprovecharnos de la vulnerabilidad descubierta para enviarnos una Reverse Shell.

Verificamos que hemos ganado acceso al Docker del sistema que levanta la página de Intranet.

Shell as Florence.Ramirez

Information leaked in environment variables (env)

Al acceder al equipo, verificamos que nos encontramos como usuario root. Verificando las variables de entorno que tenemos, nos encontrams con una variable LDAP_BIND_PASSWORD que parecen ser unas credenciales de LDAP.

Realizaremos un Password Spraying para verificar si estas credenciales son válidas para algún usuario que disponemos. Verificamos que son las credenciales válidas del usuario intranet_principal.

Realizaremos una exportación del BloodHound para verificar posibles vectores de ataque para elevar nuestros privilegios, de momento no logramos encontrar nada interesante.

Session Hijacking via SSH Control Socket

Volviendo al equipo de Docker, analizamos los archivos y directorios de la raíz. Entre los cuales, nos encontramos con un archivo docker-entrypoint.sh en el cual al analizar el script, vemos que mencionan un directorio en /root/.ssh/controlmaster.

Accederemos a /root/.ssh/controlmaster y verificaremos que existe de un Socket de SSH del usuario florence.ramirez al equipo dev-workstation.

Un socket es un punto de comunicación que permite el intercambio de datos entre dos procesos en una red o en un sistema local. Es un concepto clave en la programación de redes y permite que aplicaciones en diferentes máquinas o en la misma máquina se comuniquen entre sí.

En este caso específico, el archivo florence.ramirez@ghost.htb@dev-workstation:22 parece ser un socket de red. Los sockets se utilizan para establecer conexiones entre clientes y servidores, y se manejan mediante direcciones IP y puertos. Los detalles del nombre del archivo sugieren que es un socket Unix, que generalmente se utiliza para la comunicación entre procesos dentro de la misma máquina.

¿Qué hace un socket?

  • Enlace entre procesos: Un socket permite que dos aplicaciones, ya sea en la misma máquina o en máquinas diferentes, se comuniquen a través de la red.

  • Tipos de sockets:

    • Sockets de flujo (TCP): Utilizados para una conexión fiable.

    • Sockets de datagramas (UDP): Utilizados para comunicación sin conexión y más rápida, aunque menos fiable.

En este caso, el archivo indica que se trata de un socket Unix que está siendo utilizado por el servicio en el puerto 22, lo que sugiere que se está manejando alguna comunicación interna relacionada con SSH o un servicio similar entre procesos en la máquina.

Por tanto, este archivo de socket podría estar facilitando una comunicación entre aplicaciones o servicios relacionados con el sistema florence.ramirez@ghost.htb y dev-workstation.

Al ejecutar el comando ssh -O check, revisamos si existe una conexión SSH multiplexada activa. La respuesta Master running (pid=24) confirma que la conexión principal está activa. Luego, con hostname -I, obtuvimos la dirección IP de la máquina remota, que es 172.18.0.2. Finalmente, al usar id, vimos que el usuario conectado es florence.ramirez (UID 50), y pertenece a los grupos staff e it.

Reusing a Valid TGT for Lateral Movement

Al analizar nuevamente las variables de entorno de este nuevo usuario, verificamos que parece haber un Ticket Granting Ticket (TGT) del usuario que disponemos. Este ticket se encuentra almacenado enla variable KRB5CCNAME en el directorio /tmp/krb5cc_50.

Accederemos al directorio mencionado, y comprobaremos de la existencia del TGT.

En nuestro equipo atacante, nos pondremos en escucha para recibir el archivo mencionado.

Desde el equipo víctima, enviaremos el archivo a través del /dev/tcp.

Verificamos que disponemos de este archivo en nuestro equipo local correctamente.

Exportaremos el TGT en la variable KRB5CCNAME y verificaremos que el ticket es válido y lo podemos utilizar.

A través de nxc, validaremos que el TGT es válido y podemos hacer uso de este para autenticarnos como el usuario florence.ramirez sin disponer de sus credenciales.

Shell as justin.bradley

DNS Spoofing to Capture NTLMv2 Hash from User Attempting to Access Bitbucket

Después de investigar en BloodHound para verificar las acciones posibles con el usuario florence.ramirez, no encontramos ninguna vulnerabilidad clara. Sin embargo, recordamos que en la Intranet, el usuario justin.bradley mencionaba que estaba teniendo problemas para acceder a bitbucket.ghost.htb.

Esto nos llevó a pensar que podríamos revisar si esa entrada está registrada en el servidor DNS del Domain Controller. Si no lo está, una opción sería verificar si tenemos permisos para agregar una nueva entrada y redirigir el subdominio a nuestro servidor web, lo que nos permitiría realizar un ataque de DNS Spoofing.

A través de la herramienta de bloodyAD realizaremos una consulta de los registros DNS del servidor.

Dado que el resultado era bastante extenso, lo que realizamos es reenviar la salida del comando a un archvo llamado dnsDump.txt, para posteriormente filtrar por bitbucket en el archivo para comprobar si existía esta entrada. En este caso, verificamos que no hay la existencia de este subdominio en los registros del servidor DNS del DC.

Mediante la herramienta de bloodyAD lo que probamos es de intentar añadir un registro DNS llamado bitbucket para que apuntáse hacía nuestro servidor web. Comprobamos que se ha podido añadir correctamente el registro, alparecer disponíamos de los permisos necesarios con el usuario florence.ramirez.

Utilizaremos el responder para levantar los servicios. Después de un tiempo, verificamos que nos llega el hash NTLMv2 del usuario justin.bradley, lo cual nos confirma del éxito del DNS Spoofing.

Trataremos de crackear el hash obtenido y comprobamos que logramos crackear el hash y obtener las credenciales del usuario mencionado.

Trataremos de validar a través de nxc de si las credenciales son válidas para el usuario, comprobamos que podemos autenticarnos con dichas credenciales y además tenemos permisos para acceder al DC mediante WinRM dado que tenemos de los permisos necesarios.

Abusing WinRM -EvilWinRM

Nos conectaremos al Domain Controller a través de evil-winrm y logramos visualizar la flag de user.txt.

BloodHound Enumeration

Revisaremos en BloodHound los Domain Admins existentes en el dominio, en este caso, solamente se muestra al usuarioAdministrator.

Por otro lado, verificamos que el usuario ADFS_GMSA$ es Kerberoastable. Tratamos de crackear su hash obtenido, pero no logramos crackear el hash para obtener la contraseña del usuario.

Shell as ADFS_GMSA$

Abusing ReadGMSAPassword (PowerView.py)

Revisando nuevamente en BloodHound, comprobamos que el usuario actual justin.bradley dispone de privilegios de ReadGMSAPassword sobre el objeto ADFS_GMSA$.

Los privilegios de ReadGMSAPassword permiten a usuarios o grupos recuperar la contraseña de una Group Managed Service Account (gMSA) en un entorno de Active Directory. Estos privilegios se asignan para que ciertos servicios, servidores o aplicaciones puedan autenticarse automáticamente utilizando la cuenta sin necesidad de gestión manual de contraseñas. Sin embargo, si son otorgados a usuarios no autorizados, podrían permitir el acceso a servicios críticos o realizar ataques de escalación de privilegios.

Para recuperar la contraseña GMSA decidimos utillizar la herramienta de PowerView.py, al realizar la consulta de Get-GMSA logramos obtener el hash NTLM del objeto ADFS_GMSA$.

Validaremos que el hash NTLM del usuario nos sirve para autenticarnos correctamente en el dominio.

Verificamos que el usuario ADFS_GMSA$ dispone del privilegio de CanPSRemote sobre el Domain Controller, con lo cual, podríamos conectarnos remotamente al DC.

Nos conectaremos al DC mediante evil-winrm, verificamos el acceso correctamente.

Shell as mssqlserver

Active Directory Federation Services (ADFS) - Golden SAML Attack

Por el nombre del equipo, pensamos que quizás esté relacionado con los Active Directory Federation Services (ADFS).

Los Active Directory Federation Services (ADFS) son una solución de Microsoft para proporcionar acceso único (SSO) a aplicaciones que no están dentro del dominio local de Active Directory. A través de ADFS, los usuarios pueden acceder a aplicaciones externas o servicios web sin necesidad de ingresar credenciales repetidamente. ADFS funciona emitiendo tokens SAML (Security Assertion Markup Language) que contienen información sobre la identidad del usuario y sus permisos.

Por lo cual, se nos ocurrió en intentar realizar un Golden SAML Attack.

El Golden SAML Attack es una técnica utilizada para explotar las vulnerabilidades de autenticación en ADFS. En este ataque, el atacante roba el certificado utilizado para firmar los tokens SAML y lo usa para crear tokens de autenticación falsificados que le permiten acceder a aplicaciones federadas sin necesidad de que el usuario real esté presente. Es una forma muy efectiva de realizar escalada de privilegios o moverse lateralmente dentro de una red comprometida.

En este caso, con acceso a la cuenta ADFS_GMSA$, que tiene privilegios sobre el Domain Controller (DC), un atacante puede potencialmente usar esta cuenta para generar un Golden SAML Token. Con dicho token, el atacante podría acceder a cualquier servicio federado que dependa de ADFS para autenticación, como si fuera un usuario legítimo.

Para realizar el Golden SAML Attack, debemos disponer del binario ADFDump.exe, una herramienta muy útil en este tipo de explotación. ADFDump.exe nos permite volcar los datos necesarios desde un Active Directory Federation Services (ADFS) y extraer el certificado privado que se utiliza para firmar los tokens SAML. Este certificado es crucial, ya que es la clave para crear tokens SAML falsificados.

Una vez obtenemos este certificado, podemos generar un token SAML válido para cualquier usuario dentro del dominio, lo que nos permite suplantar identidades y acceder a servicios federados como si fuéramos usuarios legítimos. Lo mejor de este ataque es que, al no necesitar intervención directa de los usuarios afectados, es muy difícil de detectar.

El proceso general sería:

  1. Obtención del certificado: Usamos ADFDump.exe para extraer el certificado privado de ADFS, el cual se encuentra en el servidor de ADFS.

  2. Creación del Golden SAML Token: Con el certificado, generamos el token SAML falso que contiene los datos de cualquier usuario, como si fuera un token legítimo.

  3. Acceso a los servicios federados: Utilizamos el token para acceder a aplicaciones federadas que confían en el sistema de ADFS para autenticación.

Subiremos el ADFSDump.exe al DC y verificaremos que se encuentra correctamente en el equipo.

Al ejecutar el binario de ADFSDump.exe en el DC podemos observar los siguientes resultados.

  • Extracción de la clave privada desde el almacenamiento de Active Directory:

    • Dominio: ghost.htb

    • Clave privada extraída:

      • FA-DB-3A-06-DD-CD-40-57-DD-41-7D-81-07-A0-F4-B3-14-FA-2B-6B-70-BB-BB-F5-28-A7-21-29-61-CB-21-C7

      • 8D-AC-A4-90-70-2B-3F-D6-08-D5-BC-35-A9-84-87-56-D2-FA-3B-7B-74-13-A3-C6-2C-58-A6-F4-58-FB-9D-A1

  • Lectura de la clave de firma encriptada desde la base de datos: La clave de firma encriptada fue extraída en base64 y tiene el siguiente formato:

Convertiremos el PFX y la Private Key en formato binario a través de los siguientes comandos.

Instalaremos la herramienta de ADFSpoof paa creación del Golden SAML.

El comando ejecutado utiliza el script ADFSpoof.py para generar un ticket SAML manipulado, permitiendo la suplantación del usuario administrator en el dominio GHOST. Este ataque se realiza mediante la firma de un Golden Ticket.

Se especifica un archivo PFX cifrado (EncryptedPfx.bin) que contiene la clave privada de la entidad de seguridad, junto con una clave secreta (dkmKey.bin). El objetivo es el servidor core.ghost.htb, sobre el cual se apunta el ataque SAML.

El ticket generado contiene el formato transient para el NameID, indicando un identificador temporal para el usuario suplantado. Se definen las aserciones SAML que afirman que el usuario GHOST\administrator tiene privilegios de acceso, permitiendo el acceso al sistema como si fuera ese usuario.

Este ataque, al manipular los datos SAML, da la capacidad de acceder a servicios protegidos sin necesidad de credenciales reales del usuario.

Deberemos de tener añadidocore.ghost.htb en nuestro archivo /etc/hosts, esto ya lo realizamos inicialmente en la enumeración de subdominios.

Interceptaremos la solicitud al acceder a https://core.ghost.htb:8443/adfs/saml/postResponse, modificaremos la solicitud GET por POST e indicaremos el SAML obtenido en el paso anterior, al enviar la solicitud en BurpSuite, verificamos que parece que ha funcionado correctamente el Golden SAML Attack.

Haremos click derecho y trataremos de visualizar la respuesta en el navegador.

Verificaremos que se nos quedará nuestro navegador cargando en la siguiente página web.

Volvemos al BurpSuite y de la solicitud interceptada, le daremos a la opción de Forward.

Al acceder nuevamente a nuestro navegador, comprobamos el acceso al Ghost Config Panel, el acceso que dispnemos con el SAML. Verificamos que se trata de una página web en la cual nos permite realizar consultas SQL.

Esta consulta intenta obtener el nombre de los servidores vinculados a la base de datos, seleccionando la columna SRVNAME de la tabla SYSSERVERS. Es común en SQL Server, y en un contexto de inyección SQL, un atacante podría usarla para obtener información sobre los servidores vinculados y otros detalles de la base de datos.

Este comando intenta ejecutar código como el usuario sa, que es una cuenta de administrador en el sistema. Se utiliza el EXECUTE AS LOGIN para cambiar el contexto de ejecución al usuario sa, y luego se ejecuta un comando que obtiene el nombre de usuario del sistema con SELECT SYSTEM_USER. Esto puede ser útil para probar si se tienen privilegios elevados o para realizar acciones maliciosas con permisos elevados.

Este comando tiene como objetivo habilitar la opción xp_cmdshell en SQL Server, lo que permite ejecutar comandos del sistema operativo directamente desde la base de datos. Primero, utiliza EXEC AS LOGIN = 'sa' para cambiar al contexto del usuario sa, que es el administrador del sistema. Luego, habilita las opciones avanzadas (sp_configure "show advanced options", 1) y habilita el uso de xp_cmdshell (sp_configure "xp_cmdshell", 1). Finalmente, ejecuta un comando del sistema operativo usando xp_cmdshell, en este caso, whoami, para obtener el nombre de usuario bajo el cual se está ejecutando el proceso.

En elresultado obtenido, verificamos que el usuario que ejecuta el comando es NT SERVICE\mssqlserver.

Dado que podemos ejecutar comandos arbitrarios en el equipo, el siguiente paso será lograr obtener acceso al sistema. Para ello, dispondremos del binario de nc.exe el cual compartiremos a través de un servidor SMB.

Nos pondremos en escucha con nc para recibir la Reverse Shell.

Lo primero que debereos realizar, es conectar nuestro servidor SMB al equipo mediante una unidad de red, para ello haremos uso del siguiente comando. Verificaremos que se nos indica un mensaje de The command completed successfully.

Una vez tengamos nuestro recurso compartido en una unidad de red del equipo, lo que realizaremos es ejecutar el nc.exe que disponemos en nuestro servidor SMB para otorgarnos una Reverse Shell.

Verificamos que hemos ganado acceso al equipo mediante el usuariomssqlserver.

Shell as SYSTEM

Abusing SeImpersonatePrivilege (EfsPotato)

Revisando el equipo al cual disponemos acceso, verificamos que nos encontramos en un equipo distinto al del DC.

Revisando los permisos de whoami /priv que dispone el usuario actual, verificamos que disponemos del privilegio SeImpersonatePrivilege el cual nos permitiría abusar de él para convertirnos en NT AUTHORITY\SYSTEM.

En este caso, lo que realizaremos es abusar del privilegio menciondo a través de EfsPotato.

EfsPotato es una herramienta de post-explotación que permite obtener privilegios elevados en sistemas Windows utilizando una vulnerabilidad en el servicio de cifrado de archivos (EFS). Aprovecha el hecho de que los procesos con privilegios más bajos pueden manipular ciertos objetos relacionados con el cifrado de archivos, lo que permite a un atacante ejecutar código con privilegios de sistema (SYSTEM). Es útil cuando un atacante tiene acceso a una cuenta con privilegios limitados, pero no cuenta con privilegios de administrador en el sistema.

En el repositorio del binario de EfsPotato, deberemos de compilar el binario desde el equipo. Para ello, primero revisaremos las versiones de Microsoft.Net que dispone el equipo víctima.

Nos descargaremos el archivo EfsPotato.cs del proyecto de GitHub.

Copiaremos este archivo que contiene el código fuente del binario hacia el equipo víctima.

Compilaremos elEfsPotato.cs y verificaremos que se ha creado el archivo EfsPotato.exe.

Por otro lado, también nos copiaremos el binario de nc.exe en la ruta de C:\ProgramData.

Nos pondremos en escucha con nc para recibir la Shell como NT AUTHORITY\SYSTEM.

Ejecutaremos el EfsPotato.exe para convertirnos en usuario NT AUTHORITY\SYSTEM y ejecutaremos el nc.exe para enviarnos una Reverse Shell, este comando lo ejecutará el usuario NT AUTHORITY\SYSTEM.

Verificamos que hemos ganado acceso al equipo que nos encontrábamos y nos hemos convertido en usuario NT AUTHORITY\SYSTEM.

Deshabilitaremos el AV (Antivirus) del equipo a través del siguiente comando.

Privilege Escalation

Parent Domain Compromise + SID Injection + Golden Ticket Attack from Linux

Nos encontramos en el equipo PRIMARY, que forma parte del dominio CORP.GHOST.HTB, con privilegios NT AUTHORITY\SYSTEM. Nuestro objetivo es escalar privilegios dentro del dominio y, para ello, utilizaremos un Golden Ticket Attack.

Este método nos permitirá generar un ticket Kerberos válido con privilegios administrativos, otorgándonos acceso total en el dominio sin necesidad de credenciales legítimas. A lo largo del proceso, explicaremos cada paso en detalle, desde la obtención de las claves necesarias hasta la generación y uso del ticket.

En este caso, deberemos de disponer del binario de Mimikatz en nuestro equipo, el cual compartiremos a través de un servidor web.

Desde el equipo de PRIMARY nos descargaremos el binario de Mimikatz.

Utilizamos mimikatz para obtener el hash NTLM y el aes256_hmac del usuario krbtgt, el cual este último necesitaremos para realizar el Golden Ticket Attack.

Obtendremos el Domain SID del dominio CORP.GHOST.HTB a través de BloodHound.

También obtendremos el SID del grupo Enterprise Admins del dominio GHOST.HTB.

También podemos elegir otros grupos de alto privilegios que dispongan del permiso de DCSync sobre el dominio GHOST.HTB.

Exploiting Network Access with Ligolo-ng to Share corp.ghost.htb

Dado que la red de CORP.GHOST.HTB no la tenemos accesible desde la VPN de HTB, lo que deberemos de realizar es compartir esta red mediante herramientas como ligolo-ng.

En nuestra Kali, nos montaremos el servidor Proxy a través del siguiente comando.

Realizaremos las siguiente modificaciones, para habilitar la interfaz de ligolo-ng en nuestro equipo atacante, y de añadir la ruta correspondiente al ip route. Por otro lado, sincronizarmos la hora con el dominio.

También deberemos de disponer del agent.exe de ligolo-ng el cual compartiremos a través de un servidor web.

Desde el equipo de PRIMARY nos descargaremos el binario indicado.

Realizaremos la conexión del agente con el servidor de ligolo-ng.

Verificaremos en el servidor Proxy de ligolo-ng que se ha detectado una sesión nueva, una vez conectada, ingresaremos el comando start para iniciar la compartición de la red.

Añadiremos la siguiente entrada en nuestro archivo /etc/hosts.

Generating Custom Golden Ticket for Administrator in corp.ghost.htb

En este punto, para realizar el Golden Ticket Attack deberemos de disponer de los siguientes puntos claves.

  • Clave aes256_hmac del usuario krbtgt --> esta clave nos servirá para generar el Golden Ticket.

  • Domain SID --> deberemos de disponer del Domain SID del dominio CORP.GHOST.HTB.

  • Extra SID --> deberemos de disponer del sid de un grupo de alto privilegio del dominio GHOST.HTB.

En este caso, estamos añadiendo el SID del grupo "Enterprise Admins" del dominio GHOST.HTB, lo que significa que cuando generemos el Golden Ticket en el dominio corp.ghost.htb, también dispondremos de permisos en GHOST.HTB como si fuéramos miembro de "Enterprise Admins".

¿Para qué sirve esto?

  • Enterprise Admins es un grupo con privilegios altos en toda la estructura de dominios, lo que permite administrar otros dominios dentro del bosque.

  • Como disponemos una relación de confianza entre corp.ghost.htb y GHOST.HTB, podemos movernos lateralmente y escalar privilegios en GHOST.HTB.

  • Básicamente, con este Golden Ticket, podemosactuar como un Administrador de Dominio en GHOST.HTB, aunque originalmente solo teníamos acceso en CORP.GHOST.HTB.

Realizaremos el Golden Ticket y dispondremos del archivo Administrator.ccache que utilizaremos para autenticarnos como Administrator en el dominio GHOST.HTB.

Importaremos el Administrator.ccache en la variable KRB5CCNAME y verificaremos que el Ticket Granting Ticket (TGT) del usuario Administrator es válido.

Dumping Domain Credentials and NTDS Secrets from DC01 in corp.ghost.htb

Una vez dispongamos del TGT del usuario Administrator, lo que realizaremos es un DCSync Attack para disponer de todos los hashes NTLM del dominio GHOST.HTB. Entre los hashes obtenidos, el que nos interesa es el del usuario Administrator del dominio GHOST.HTB.

Verificaremos que podemos autenticarnos mediante PassTheHash con el hash NTLM del usuario Administrator. Una vez verificada la autenticación, nos conectaremos al DC mediante evil-winrm y verificaremos la flag de root.txt.

Última actualización

¿Te fue útil?