Unicode presenta un sitio web donde obtuvimos acceso modificando un token JWT, para luego realizar Path Traversal utilizando caracteres Unicode lo que nos permitio acceder al codigo fuente y a la máquina. Finalmente escalamos privilegios obteniendo el codigo fuente de un fichero en python y realizando ‘bypass’.
Nombre | Unicode |
---|---|
OS | Linux |
Puntos | 30 |
Dificultad | Media |
IP | 10.10.11.126 |
Maker | |
|
Recon
nmap
nmap muestra multiples puertos abiertos: http (80) y ssh (22).
|
|
Web Site
El sitio web presenta un botton el cual redirige hacia google.com vemos que es un redireccionamiento por medio de: /redirect/?url=google.com
. Además vemos dos direcciones de Login y Register.
La direccion del Login presenta un formulario para el ingreso de usuarios.
Register muestra un formulario de registro de usuarios.
Auth - User
Tras registrar un usuario e ingresar, vemos un dashboard con multiples opciones. Observamos en el footer que el sitio esta “desarrollado” con Flask.
- En la opción
Buy Now
presenta un formluario que tras llenarlo nos redirige hacia una página donde muestra un mensaje, aunque no envia ningun tipo de dato al servidor. Upload a Threat Report
permite subir unicamente documentos:.pdf
y.doc
, segun el formulario.
|
|
Tras enviar un documento muestra un mensaje igual al de Buy Now
, y no muestra algun directorio donde el archivo fue subido.
Directory Brute Forcing
Ejecutamos feroxbuster
para busqueda de alguna direcci+on donde se muestren los archivos subidos. Vemos multiples direcciones nuevas,
|
|
- /display , redirige hacia una pagina donde muestra:
unauthorise_.attempt = true;
, - /internal , muestra
NoneType: None
. - /debug , muestra codigo 502.
Json Web Token
En los Headers del sitio encontramos un Json Web token.
|
|
Tras revisar el token en jwt.io vemos en el Header el parametro “jku” que apunta a un archivo json en el dominio hackmedia.htb
.
Dicho dominio pertenece a la maquina, y el archivo json contiene un set de claves publicas (JSON Web Key Set) codificadas como se menciona en 1, 2.
|
|
JSON Set URL (jku)
La herramienta jwt_tool permite modificar un token incluso testear distintas vulnerabilidades. Su instalación es sencilla:
|
|
Iniciamos almacenando la cookie en una variable de bash para luego ejecutar jwt_tool modificando la URL en “jku”, jwt_tool crearía el archivo jwttool_custom_jwks.json
. Por ultimo debemos de crear un mini servidor para que se realice la solicitud y verifique el token con el json generado en nuestro servidor.
|
|
Tras haber generado el token nuevo, lo utilizamos en el sitio, sin embargo nos mostró un mensaje, muestra que el parametro “jku” es invalido.
|
|
admin - Web Site
Realizando distintas pruebas con el redireccionamiento (/redirect/?url=10.10.14.30/jwttool_custom_jwks.json
) no nos permitió acceder a nuestro servidor, sin embargo encontramos que el sitio unicamente muestra el error cuando no existe http://hackmedia.htb/static/
en la URL. Utilizamos ../
para “subir” un directorio lo cual nos permitiría acceder a redirect
de tal forma: http://hackmedia.htb/static/../redirect/?url=[URL]
. Tras generar el token con esta nueva URL obtuvimos una solicitud en el miniservidor, aunque no encontramos información nueva.
|
|
Por ello generamos nuevamente un token esta vez modificando el el usuario a “admin”.
|
|
Tras modificar el token en el navegador, vemos un nuevo dashboard.
Path Traversal - Unicode
El nuevo sitio web unicamente muestra una pagina que recibe el nombre de un archivo .pdf, aunque solo muestra un mensaje.
Tras solicitar un archivo local nos muestra que existen algunos filtros en el sitio.
Intentando distintas formas de realizar bypass y diferentes “payloads” no encontramos alguna que mostrara algun archivo. Sin embargo el nombre de la maquina nos podría dar una idea de lo que podemos utilizar.
Tras investigar un poco sobre Unicode Bypass en Flask nos topamos con un post de Jorge Lajara - WAF Bypassing with Unicode Compatibility donde explica cómo funciona la normalizacion de caracteres unicode, además muestra un lista de payloads para ciertas vulnerabilidades utilizando ciertos caracteres unicode.
Tras utilizar el payload de Path Traversal obtuvimos el archivo /etc/passwd
donde vemos al usuario code
.
Codigo Fuente
Como sabemos estan utilizando Flask para el sitio web, sabiendo esto, logramos obtener el codigo fuente suponiendo el nombre del archivo principal (app.py
). Vemos al inicio del archivo que carga la configuracion de la base de datos desde un archivo .yaml, (codigo fuente en Pestaña 2).
|
|
|
|
User - Code
Tras obtener el archivo db.yaml
vemos las credenciales del usuario code
.
|
|
Con estas credenciales logramos acceder por SSH y obtener la flag user.txt
.
|
|
Privesc
Enumerando los comandos que pueden ser ejecutados con “sudo” vemos /usr/bin/treport
.
|
|
Tras ejecutar algunas de las opciones podemos observar que esta utilizando el archivo treport.py
y que el directorio donde almacena los informes es /root/reports/
, además al intentar descargar un informe vemos que utiliza curl
.
|
|
El archivo treport.py
parece no existir en la maquina, además al ejecutar strings
sobre el comando treport
se muestran algunas palabras relacionadas a librerias de python.
|
|
Unpacking Pyinstaller
Suponiendo que es un archivo generado con Python utilizamos archive_viewer
de pyinstaller, por medio de apt instalamos este ‘comando’. Además copiamos el binario a nuestra maquina local.
|
|
- Unpacking PyInstaller packed files
- Recurso online alternativo para decompilar un archivo
.pyc
: tool.lu/pyc.
Ejecutamos archive_viewer
sobre el archivo, vemos una lista de archivos o ’librerias’, extraemos treport
y struct
.
|
|
Tras ello, intentamos decompilar dicho archivo pero parece estar “dañado”. Tras intentar con el archivo struct.pyc
logramos obtener una porcion del codigo.
|
|
Fix Pyc File
uncompyle6
no logra decompilar el archivo ya que hacen faltan los “magic numbers” y “timestamp”. Para repararlo debemos de obtener los 16 bytes iniciales de un archivo .pyc sin algun daño o que pueda ser decompilado, en este caso vemos el archivo struct.pyc
. Comparando ambos archivos vemos que struct tiene los 16 bytes iniciales a diferencia de treport
que no los tiene.
|
|
Utilizamos el editor wxHexEditor (instalamos por medio de apt).
|
|
Abrimos el archivo treport.pyc
con esta herramienta, insertamos 16 bytes en "Edit > Insert"
al inicio.
Luego de ello agregamos los 16 bytes iniciales de struct.pyc
.
|
|
Tras realizar esto, guardamos el archivo, y ejecutamos uncompyle6
, logrando obtener el codigo fuente.
|
|
Command Injection “Bypass”
En la función download()
vemos que existe un “filtro” para Command Injection de diferentes caracteres que son utilzados para verificar que ninguno de estos exista en la variable que obtiene la IP y archivo para su descarga.
|
|
Siguiendo algunos posts (1, 2, 3) crafteamos un comando que podemos utilizar para obtener un archivo utilizando curl. En este caso estamos realizando “bypass” utilizando brackets ({}
) y comas (,
), enviamos un archivo con la opcion -T
.
|
|
De nuestro lado tenemos netcat a la escucha, que, tras enviar esta peticion, logramos obtener el archivo especificado.
|
|
Logramos obtener la clave privada de root pero no parece funcionar. Utilizamos una forma similar de escalar privilegios que en Curling - HTB donde modificamos el archivo /etc/sudoers
con permisos para el usuario code
. El archivo quedaría de la siguiente forma:
|
|
En la maquina ejecutaríamos el siguiente commando.
|
|
Tras realizar esto, el archivo se modificaría, logrando obtener acceso root y la flag root.txt
.
|
|