Java Code Analysis!?!
Desafío
Recibimos una página web con un formulario de login y credenciales de acceso básicas:
Username: "user"
Password: "user"
El objetivo es explotar vulnerabilidades en la implementación de JWT (JSON Web Tokens) para escalar privilegios y acceder como administrador al libro que contiene la flag.
Herramientas
- Navegador Web (DevTools - Application/Storage)
- jwt.io (para decodificar y codificar JWT)
- Análisis de código fuente Java
Explicación
Paso 1: Reconocimiento inicial
Nos logueamos con las credenciales proporcionadas (user:user). Una vez dentro, abrimos las DevTools del navegador (F12) y navegamos a la pestaña Application (Chrome) o Storage (Firefox).
Dentro de Local Storage, observamos que la aplicación utiliza JWT (JSON Web Tokens) para gestionar la autenticación. Encontramos un token almacenado que contiene información sobre nuestra sesión.
Paso 2: Análisis del código Java
Al revisar el código fuente proporcionado, encontramos dos archivos críticos:
SecretGenerator.java
Este archivo contiene el método encargado de generar el secret para firmar los JWT:
private String generateRandomString(int len) {
// not so random
return "1234";
}
El “secret” que se usa para firmar los tokens no es aleatorio, siempre es "1234". Esto significa que cualquiera que conozca este secreto puede falsificar tokens válidos.
BookShelfConfig.java
Este archivo se encarga de crear usuarios por defecto al iniciar la aplicación:
// Crea usuario normal (userId: 1)
User user = new User("user", "user", "Free");
// Crea usuario administrador (userId: 2)
User admin = new User("admin", "admin123", "Admin");
Sabemos entonces que:
- El usuario
usertiene userId: 1 y rol “Free” - El usuario
admintiene userId: 2 y rol “Admin”
Paso 3: Decodificando nuestro JWT actual
Si tomamos el JWT que obtuvimos al loguearnos y lo pegamos en jwt.io, vemos su estructura:
Payload del token original:
{
"role": "Free",
"iss": "bookshelf",
"exp": 1765497111,
"iat": 1764892311,
"userId": 1,
"email": "user"
}
Este token nos identifica como usuario con rol "Free" y userId: 1.
Paso 4: Falsificando el JWT de Admin
Ahora que conocemos el secret (1234) y sabemos que el admin tiene userId: 2, podemos crear un JWT falso con privilegios de administrador.
En jwt.io, en la sección VERIFY SIGNATURE, ingresamos el secreto 1234. Luego, modificamos el payload para que tenga los datos del admin:
Payload modificado:
{
"role": "Admin",
"iss": "bookshelf",
"exp": 1765497111,
"iat": 1764892311,
"userId": 2,
"email": "admin"
}
La herramienta nos genera automáticamente un nuevo JWT firmado con el secret correcto:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiQWRtaW4iLCJpc3MiOiJib29rc2hlbGYiLCJleHAiOjE3NjU0OTcxMTEsImlhdCI6MTc2NDg5MjMxMSwidXNlcklkIjoyLCJlbWFpbCI6ImFkbWluIn0.zH-PuUnuyv_ofmJNjdFHgsv2EftAbsDIIhHhGlR3XMQ
Paso 5: Reemplazando el token en el navegador
Volvemos a las DevTools > Application > Local Storage y buscamos las claves donde se almacena el JWT:
auth-token: Aquí pegamos el JWT completo que acabamos de generartoken-payload: Aquí pegamos solo el payload decodificado (el objeto JSON con role: “Admin”)
Paso 6: Obtener la flag
Refrescamos la página (F5). El sistema ahora nos reconoce como administrador y nos permite acceder al libro restringido que contiene la flag.