flagPrincipal HackTheBox (Intermediate)

Contexto de la maquina

Trayectoria Principal

Descripción

Principal es una máquina Linux orientada a la explotación de vulnerabilidades en aplicaciones web modernas que utilizan autenticación basada en JWT/JWE. El escenario gira en torno a una plataforma interna denominada Principal Internal Platform, que implementa autenticación mediante la librería pac4j.

Durante el proceso de explotación se identifican varios fallos críticos de seguridad, entre ellos un bypass de autenticación en pac4j, exposición de secretos dentro del panel administrativo y una configuración insegura del sistema de certificados SSH.

Estos errores permiten a un atacante:

  1. Bypassear el mecanismo de autenticación de la aplicación web.

  2. Acceder al panel administrativo.

  3. Obtener credenciales reutilizadas para acceso SSH.

  4. Escalar privilegios mediante abuso de una Certificate Authority (CA) utilizada por el servidor SSH.

Objetivo del reto

El objetivo consiste en comprometer completamente el sistema mediante las siguientes etapas:

  • Obtener acceso administrativo a la aplicación web.

  • Identificar credenciales reutilizadas.

  • Acceder al sistema mediante SSH.

  • Escalar privilegios hasta root aprovechando una mala configuración del sistema de certificados SSH.

Tipo de máquina

  • Linux

  • Web Application

  • Autenticación JWT/JWE

  • Escalada de privilegios mediante SSH Certificates

Habilidades y técnicas evaluadas

  • Enumeración de servicios con Nmap

  • Análisis de aplicaciones web

  • Identificación de versiones vulnerables de librerías

  • Explotación de Authentication Bypass

  • Manipulación de JWT/JWE

  • Uso de herramientas como curl, jq y Hydra

  • Reutilización de credenciales

  • Acceso remoto mediante SSH

  • Escalada de privilegios mediante SSH Certificate Authority

Análisis de vulnerabilidades

Escaneo de puertos

Comenzamos realizando un escaneo completo de puertos TCP para identificar los servicios expuestos en la máquina objetivo.

Una vez identificados los puertos abiertos, lanzamos un escaneo más detallado sobre ellos para obtener versiones y scripts por defecto.

Resultado:

Observamos que existen dos puertos abiertos:

  • 22 → SSH

  • 8080 → HTTP

Accedemos ahora a la web:

Respuesta:

Al acceder a la página de login del panel interno "Principal", lo primero que observamos es el footer de la aplicación:

Esta información es crucial, ya que nos indica que el sistema utiliza la librería de autenticación pac4j en su versión 1.2.0. Investigando sobre esta versión, descubrimos que es vulnerable a un CVE crítico.

CVE-2026-29000

Identificación de la Vulnerabilidad

Buscando vulnerabilidades asociadas a pac4j v1.2.0, encontramos el CVE-2026-29000, un Authentication Bypass con severidad CVSS 10.0 (Crítico).

Descripción de la vulnerabilidad: El CVE-2026-29000 consiste en un bypass de autenticación mediante JWE-Wrapped PlainJWT. La vulnerabilidad permite a un atacante con solo la clave pública del servidor (que está diseñada para ser pública) forjar un token JWT con cualquier identidad y autenticarse como cualquier usuario, incluyendo administrador.

Referencias:

Análisis del Entorno

Buscando información adicional sobre la implementación, descubrimos un archivo JavaScript que revela detalles técnicos importantes:

Este archivo contiene documentación y código que nos proporciona información valiosa:

También encontramos los endpoints definidos:

Comprensión del Ataque

El CVE-2026-29000 explota una debilidad en la lógica de validación de pac4j cuando se procesan tokens JWE. El flujo normal debería ser:

  1. Cliente envía token JWE encriptado

  2. Servidor descifra con su clave privada

  3. Verifica la firma del JWT interno

  4. Autentica al usuario

La vulnerabilidad: Cuando el token interno es un PlainJWT (sin firma), la librería omite completamente la verificación de firma y procede a autenticar al usuario con los claims del token.

Estrategia de Explotación

Para explotar esta vulnerabilidad necesitamos:

  1. Obtener la clave pública RSA del servidor (disponible en /api/auth/jwks según el JavaScript)

  2. Crear un token JWT malicioso con los claims de administrador

  3. Envolverlo en un JWE usando la clave pública

  4. Enviar el token al endpoint correspondiente

La clave del ataque es que el JWT interno debe ser un PlainJWT (sin firma), lo que provocará que pac4j omita la verificación y acepte cualquier identidad.

Obtención de la Clave Pública

Primero accedemos al endpoint JWKS (JSON Web Key Set) para obtener la clave pública RSA utilizada por el servidor para trabajar con los tokens.

Respuesta:

Este endpoint devuelve las claves públicas que utiliza la aplicación para descifrar o validar tokens JWT/JWE.

En este caso vemos que se trata de una clave RSA, donde:

  • kty → tipo de clave

  • n → módulo RSA

  • e → exponente público

  • kid → identificador de la clave

Sabiendo esto, podemos reconstruir la clave pública y utilizarla para generar un token manipulado.

El objetivo será crear un JWT sin firma (alg: none), suplantando la identidad del usuario admin, y posteriormente envolverlo en un JWE cifrado con la clave pública del servidor.

De esta forma, el servidor podrá descifrar el token, pero no verificará correctamente la firma interna, permitiéndonos bypassear la autenticación.

Generación del Token malicioso

Para ello vamos a crear un pequeño script en Python que:

  1. Reconstruya la clave pública RSA

  2. Cree un JWT sin firma (alg: none)

  3. Incluya claims de administrador

  4. Lo envuelva dentro de un JWE cifrado con RSA

generateTOKEN.py

Generar el token

Ahora ejecutamos el script.

Respuesta:

Si abrimos el archivo generado veremos el token JWE completo.

Este token contiene:

  1. Un JWT interno sin firma

  2. Claims de administrador

  3. Cifrado con la clave pública del servidor

Cuando el servidor lo procese:

  1. Podrá descifrarlo correctamente

  2. Pero no verificará correctamente la firma interna

  3. Por lo tanto aceptará el token como válido

Inyección del Token en la Web

Ahora debemos introducir el token en la aplicación web.

La aplicación guarda el token en:

Por lo tanto abrimos las Developer Tools del navegador y en la pestaña Console ejecutamos lo siguiente:

Esto simula exactamente el comportamiento de autenticación de la aplicación.

Acceso como administrador

Después de ejecutar el script que redirige al dashboard veremos lo siguiente:

Ahora estamos autenticados como usuario admin dentro de la aplicación.

Esto confirma que el bypass de autenticación ha funcionado correctamente.

A partir de aquí podemos continuar investigando el panel para encontrar nuevas formas de comprometer el sistema.

Escalate user svc-deploy

Si accedemos a la sección Users, veremos varios usuarios registrados en el sistema.

Vamos a guardarlos en una lista.

users.txt

Ahora si nos dirigimos a Settings, veremos algo bastante interesante.

En la sección Security aparece la clave utilizada para firmar los JWT, expuesta en texto plano.

Esto significa que podríamos generar tokens válidos firmados correctamente, sin necesidad de realizar el bypass anterior.

Sin embargo, teniendo en cuenta que ya podemos suplantar cualquier usuario mediante el bypass, no es necesario generar nuevos tokens.

En su lugar, podemos aprovechar esta información de otra forma.

Sabemos que el sistema expone un servicio SSH, por lo que existe la posibilidad de que la contraseña utilizada para firmar los tokens haya sido reutilizada como contraseña de algún usuario del sistema.

Ataque de reutilización de credenciales

Probamos la contraseña encontrada contra todos los usuarios utilizando hydra.

Respuesta:

Encontramos credenciales válidas para el usuario:

Por lo tanto, podemos acceder al sistema mediante SSH.

SSH (svc-deploy)

Metemos como contraseña D3pl0y_$$H_Now42!...

Vemos que hemos accedido de forma correcta, por lo que leeremos la flag del usuario.

user.txt

Escalate Privileges

Inspeccionando el directorio /opt, encontramos una carpeta llamada principal con la siguiente estructura:

Lo que inmediatamente llama la atención es el directorio ssh con permisos restrictivos pero accesibles para el grupo deployers.

Descubrimiento Crítico

Listando el contenido del directorio ssh:

Aquí tenemos dos archivos cruciales:

  • ca → Clave privada de la Certificate Authority (CA)

  • ca.pub → Clave pública de la CA

Verificación de Permisos

Comprobamos a qué grupos pertenecemos:

Respuesta:

Pertenecemos al grupo deployers, lo que significa que podemos leer el archivo ca (la clave privada de la CA). Esto es una vulnerabilidad crítica, ya que esta clave debería ser secreta y accesible solo para root.

Análisis de Configuración SSH

Para confirmar que el sistema acepta certificados firmados por esta CA, verificamos la configuración de SSH:

Respuesta:

Esto confirma que el servidor SSH confía en cualquier certificado firmado por nuestra CA. Es decir, podemos crear certificados válidos para cualquier usuario, incluyendo root.

Generación de Claves

Procedemos a generar un par de claves RSA para nuestro ataque:

Respuesta:

Firma del Certificado como Root

Ahora, usando la clave privada de la CA, firmamos nuestra clave pública para que sea válida para el usuario root:

Respuesta:

Explicación de los parámetros:

  • -s → Archivo de clave privada de la CA

  • -I → Identificador del certificado

  • -n → Nombre(s) de usuario para los que es válido

  • -V → Período de validez (+1d = 1 día)

Esto genera el archivo root-key-cert.pub, que es nuestro certificado SSH firmado.

Acceso como Root

Finalmente, nos conectamos por SSH usando nuestra clave privada y el certificado firmado:

Respuesta:

Hemos escalado privilegios hasta root utilizando la CA de SSH, por lo que leeremos la flag de root.

root.txt

Last updated