logo

Reconocimiento

Para comenzar realizaremos un scan con nmap para visualizar los puertos abiertos en el host victima:

nmap -sS --min-rate 1500 -p- --open -vv -n -Pn 10.10.11.134

recon1
Vemos abiertos los puertos 22, 80 y 5000. Realizaremos otro scan para obtener más detalles de los servicios y versiones utilizados en estos puertos:
recon2
Podemos observar que el puerto 80 revela el directorio .git. Al ingresar al puerto 5000 http observamos que tenemos un panel de autenticación:
recon3
De momento no podemos hacer mucho en este panel.

Analizando .git

Como el resultado del script de nmap nos revelo el directorio .git en 10.10.11.134/.git podemos utilizar la herramienta Githack para recomponer este repositorio:

pip install githack

git0
git1
Como observamos contamos con 2 ficheros los cuales corresponden a server.py y track_api_CR_148.py. Analizaremos los ficheros individualmente.

server.py

Para server.py podemos notar que en las primeras líneas de código se evidencia el uso de Json Web Token además de que la aplicación estaría construida con Flask. Notamos que se verifica un JWT el cual hace uso del algoritmo HS256 para su construcción y recibe el username:
git2
Al inspeccionar más el código notamos diversas rutas como /track y /order.
git3
Las cuales si ingresamos en el puerto 80 no obtendremos resultados. Pero si tenemos resultados para el puerto 5000 lo que indica que el código fuente encontrado corresponde para este puerto en especifico:
git4

track_api_CR_148.py

Para el fichero track_api_CR_148.py analizamos que también existen variables en forma de secreto. No tenemos estas claves pero si podemos ver que se revela el endpoint de AWS el cual es http://cloud.epsilon.htb. Agregamos este al fichero /etc/hosts de nuestra maquina.
git5 Además vemos que se definen funciones las cuales Zipean una ruta de alguna forma. Adicionalmente tenemos el siguiente fragmento update_lambda el cual simplemente es una función que verifica la existencia de un directorio de Lambda y luego actualiza el código de la función utilizando la API de AWS Lambda.
git6
Ya con esto en mente procedemos a enumerar los commits del proyecto utilizando git para observar distintas versiones de estos códigos.

Git Log

Utilizando el comando git log podemos ver los commits realizados. Observamos el primer commit (el de más abajo) el comentario de “Adding Tracking API Module” lo cual llama la atención ya que fue la primera implementación del código track_api_CR_148.py:
git7 Podemos visualizar este utilizando el comando git show <commit>:
git8
Vemos como se revelan los secretos para conectarse a aws:

aws_access_key_id=’AQLA5M37BDN6FJP76TDC’ aws_secret_access_key=’OsK0o/glWwcjk2U3vVEowkvq5t4EiIreB+WdFo1A

Utilizaremos estos para explorar las funciones.

AWS

Lo primero es configurar AWS con los secretos utilizando aws configure: git9
Ya con esto podemos explorar las funciones, tengamos en cuenta que se nos mostrarón funciones lambda por lo que utilizaremos estás en aws:

aws --endpoint=http://cloud.epsilon.htb lambda list-functions

git10
Observamos que tenemos la función costume_shop_v1 disponible. Podemos utilizar el siguiente comando para obtener la función:

aws --endpoint=http://cloud.epsilon.htb lambda get-function --function-name=costume_shop_v1

git11
Y obtenemos la localización de la función la cual es un comprimido ZIP. Descargamos la función utilizando wget y la renombramos para convertirlo en un comprimido .zip y la descomprimimos para obtener el código:
git12
Y observamos que esta contiene un secreto hardcodeado el cúal podriamos utilizar para crear un token JWT.

Creando JWT

Desde este punto ya que contamos con un secret podemos intentar crear un token JWT para su uso. Para esto utilizamos el siguiente script en python3:

import jwt
secret = "RrXCv`mrNe!K!4+5`wYq"
encoded_jwt = jwt.encode({"username": "admin"}, secret, algorithm="HS256")
print("[!] Token Generado: " + encoded_jwt)

jwt0
Copiamos el token generado y lo utilizamos ante el puerto 5000 con el nombre de auth como vimos en el código server.py:
jwt1

SSTI

Ahora que podemos explorar libremente observamos que en order podemos seleccionar un costume el cual si presionamos en order se despliega el mensaje de “Your order of “phantom” has been placed successfully.” En este caso al seleccionar el item de Phatnom Mask ssti0
Realizamos la misma petición pero esta vez con BurpSuite e identificamos que en el parámetro costume se pasa el valor de phantom:
ssti1
Si cambiamos el valor de phantom por cualquier cosa como por ejemplo h4rri observamos que se muestra el valor de este:
ssti2
Vemos que el valor se refleja correctamente. Sabemos por el script server.py que la aplicación está construida con Flask. Probamos un payload tipico para estos casos para probar la vulnerabilidad de Server-Side Template Injection el cual es `` si el resultado de este es 49 entonces estamos ante la vulnerabilidad mencionada:
ssti3 Con la vulnerabilidad confirmada ya podemos buscar una forma de ejecutar comandos y obtener acceso a la maquina victima.

Shell as Tom

Para ganar acceso a la maquina victima podemos utilizar el siguiente payload:


Desde ya nos ponemos en escucha con netcat:
sh1 A continuación enviamos el payload en BurpSuite:
sh2
sh3
Desde este punto ya podemos leer la flag ubicada en el directorio del usuario tom.

Privesc

Al ejecutar Linpeas no observamos nada de mucho valor para escalar privilegios. Por lo que nos disponemos a enumerar procesos que no podamos ver utilizando la herramienta pspy. La descargamos en la maquina victima, le asignamos permisos de ejecución y la ejecutamos:
priv0
Observamos que el usuario root arranca una tarea cron y posteriormente ejecuta el script backup.sh ubicado en /usr/bin:
priv1
El script tiene el siguiente contenido:
priv2
La línea /usr/bin/tar -chvf "/var/backups/web_backups/${check_file}.tar" /opt/backups/checksum "/opt/backups/$file.tar" crea un nuevo archivo comprimido en el directorio /var/backups/web_backups/.

El nombre del archivo es ${check_file}.tar, donde ${check_file} es el valor de la variable check_file. El contenido del archivo comprimido incluye el archivo /opt/backups/checksum y el archivo comprimido anteriormente creado /opt/backups/$file.tar.

Observamos además de que se está utilizando tar con el parámetro -h el cual según su descripción:
priv3
En base a esto podemos probar el crear un fichero en el directorio /opt/backups con el nombre de checksum el cual apunte directamente a la flag del usuario root o a la clave ssh del usuario root para ganar acceso al sistema con este. Para esto haremos uso de un script en python3 ya que la maquina victima cuenta con este lenguaje:

import os
while True:
	if os.path.exists("/opt/backups/checksum"):
		os.remove("/opt/backups/checksum")
		print("[+] File deleted")
os.symlink("/root/.ssh/id_rsa", "/opt/backups/checksum", target_is_directory=True)
print("[+] Symlink created")
break

priv4
Observamos que el script se ejecuto correctamente. Ahora copiamos el ultimo fichero tar creado al directorio tmp y lo descomprimimos:
pirv5
Posteriormente ingresamos a la carpeta resultando la cual es opt y luego a backups:
priv6

priv7
Como apreciamos contamos con el fichero checksum, el cual si revisamos podemos notar que es una clave rsa para utilizar con SSH:
priv8
La copiamos y la guardamos en nuestra maquina de atacante. Le asignaremos permisos con chmod 600 para que contenga los permisos del propietario: priv9
Observamos que tenemos acceso como usuario root, y ya podremos leer la flag:
priv10

Pwned! 🏴‍☠️