========================================================
 GHOSTAUTH - laboratorio de practicas de Burp Suite
========================================================

Que es esto
-----------
GhostAuth es un servicio de identidad y notas privadas (ficticio) con
3 fallos reales de verificacion de JWT metidos a proposito, para
practicar con Burp Suite:

  1. Token de sesion sin firma verificada ("alg":"none")
  2. Token de API personal con secreto HS256 debil (crackeable offline)
  3. Confusion de algoritmo RS256 -> HS256 en el token de partners

Los 3 retos son fallos DISTINTOS (a diferencia de GhostRace, donde los
3 retos comparten el mismo patron): cada uno ataca una pieza distinta
de como GhostAuth firma y verifica tokens. Los 3 llevan al mismo
objetivo final: leer las notas privadas de la cuenta "admin" en
GET /api/admin/notes, sin conocer su contrasena.

IMPORTANTE - diferencia de las apps hermanas: GhostAuth NO usa cookies
de sesion. El token vive en el almacenamiento local del navegador y se
manda a mano como cabecera "Authorization: Bearer <token>" en cada
llamada a la API. Es asi a proposito: es la convencion real de las
APIs que usan JWT, y es lo que te deja capturar y editar el token con
la extension JWT Editor de Burp.

Corre en tu propio equipo (localhost). No necesita internet una vez
instalada, no envia datos a ningun sitio y no debe exponerse fuera de
tu maquina (no tiene ninguna proteccion real).


Requisitos
----------
  - Windows, macOS o Linux
  - Python 3.10 o superior instalado y accesible desde la terminal
    (compruebalo con:  python --version   o   python3 --version)
  - Unos 50 MB libres en disco (para el entorno virtual; cryptography
    pesa algo mas que las dependencias de las apps anteriores)
  - Ningun otro programa escuchando en el puerto 5003
  - Burp Suite Community con la extension gratuita "JWT Editor"
    instalada desde el BApp Store (capitulo 10 del manual de Burp)


Como desplegarlo
-----------------
1. Descomprime este ZIP en una carpeta de tu equipo.

2. Arranca el servidor:
     - Windows:      doble clic en "run.bat"
     - macOS/Linux:  abre una terminal en esta carpeta y ejecuta:
                        chmod +x run.sh
                        ./run.sh

   La primera vez tardara un poco: crea un entorno virtual Python
   (carpeta "venv") e instala Flask y cryptography dentro de el. Las
   siguientes veces arranca en segundos. Tambien crea la base de datos
   "app/ghostauth.db" (SQLite) y el par de claves RSA del partner
   ("app/keys/partner_public.pem" y "app/keys/partner_private.pem")
   al primer arranque.

3. Cuando veas el mensaje "Arrancando GhostAuth en
   http://127.0.0.1:5003", abre esa direccion en tu navegador
   (o en el navegador embebido de Burp) y crea una cuenta desde
   "Crear cuenta gratis".

4. Deja la ventana de la terminal abierta mientras uses la app.
   Para detenerla, pulsa Ctrl+C en esa misma ventana.


Como se juega cada reto (resumen, el detalle esta en el writeup)
------------------------------------------------------------------
Un JWT son 3 trozos separados por puntos, cada uno en Base64 (cabecera,
payload, firma). Base64 NO es cifrado: cualquiera puede leer y editar
la cabecera y el payload de un token propio. Lo unico que deberia
impedir que el servidor acepte un token modificado es la firma - y
eso solo funciona si el servidor la verifica correctamente.

  1. Inicia sesion con tu cuenta normal y captura en Burp cualquier
     peticion que use tu token de sesion. Con la extension JWT Editor,
     edita el payload a "role":"admin", cambia la cabecera a
     {"alg":"none","typ":"JWT"} y quita la firma (JWT Editor tiene un
     boton "Sign" con la opcion "None"). Usa ese token contra
     GET /api/admin/notes.

  2. En "Mis notas", genera tu token de API personal. Ejecuta el
     script incluido crack_secret.py (en la raiz de este ZIP, se
     explica en detalle en el writeup) contra ese token para encontrar
     el secreto HS256 real del servidor probando una wordlist corta:
         python crack_secret.py "<tu_token_de_api>"
     Con el secreto en la mano, firma un token nuevo con
     "role":"admin" y usalo contra GET /api/admin/notes.

  3. En "Integracion partner", conecta tu cuenta para obtener un token
     RS256 y descarga la clave publica del partner
     (/api/partner/public-key.pem). Firma un token nuevo como HS256
     usando el CONTENIDO de esa clave publica como si fuera un secreto
     simetrico, con "role":"admin", y usalo contra GET /api/admin/notes.

En los 3 casos, el objetivo es el mismo: conseguir que
GET /api/admin/notes devuelva las notas de "admin" (incluida la flag)
sin haber iniciado sesion nunca como esa cuenta.


Si algo falla
--------------
run.bat / run.sh estan pensados para NO fallar en silencio: si falta
Python, si no se puede crear el entorno virtual, si falla la
instalacion de dependencias o si el propio servidor se cae, veras un
mensaje [ERROR] explicando que ha pasado y la ventana se quedara
abierta (con una pausa) para que puedas leerlo con calma en vez de
cerrarse sola.

Los casos mas frecuentes:
  - "No se ha encontrado python en el PATH"
      -> Instala Python desde https://www.python.org/downloads/
         y marca la casilla "Add python.exe to PATH" (Windows).
  - Fallo al arrancar el servidor / puerto ocupado
      -> Cierra cualquier otra cosa que use el puerto 5003, o edita
         PORT en app/app.py, o arranca con:
           Windows:      set PORT=5053 && run.bat
           macOS/Linux:  PORT=5053 ./run.sh
  - "No autorizado" en /api/admin/notes aunque el token parezca correcto
      -> Revisa que el claim "role" del payload sea exactamente
         "admin" (con comillas, en minusculas) y que la cabecera
         Authorization tenga el formato exacto "Bearer <token>".


Reiniciar el laboratorio entre intentos
----------------------------------------
Este laboratorio usa una base de datos SQLite para usuarios y notas.
Para volver a dejarlo todo en su estado inicial sin reiniciar el
servidor, visita:

    http://127.0.0.1:5003/reset

Esto reconstruye la base de datos desde cero (nueva cuenta admin con
contrasena aleatoria distinta, notas de partida) y cierra tu sesion en
el navegador que uses para visitarla. No cambia los secretos de firma
ni las claves RSA del partner, asi que un token que ya hayas forjado
sigue funcionando despues de un /reset.


Estructura del paquete
-----------------------
  app/              codigo de la aplicacion (backend Flask + paginas)
                     app/ghostauth.db se genera sola al primer arranque
                     app/keys/partner_public.pem se genera sola tambien
  requirements.txt  dependencias Python (Flask + cryptography)
  run.bat / run.sh  arranque con comprobaciones de errores
  crack_secret.py   script para el reto 2 (crackeo offline del secreto HS256)
  LEEME.txt         este archivo

El writeup con la solucion guiada de los 3 retos (con capturas de
Burp) se entrega aparte, no dentro de este ZIP.
