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
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:
Podemos observar que el puerto 80 revela el directorio .git
. Al ingresar al puerto 5000 http observamos que tenemos un panel de autenticación:
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
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
:
Al inspeccionar más el código notamos diversas rutas como /track
y /order
.
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:
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.
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.
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
:
Podemos visualizar este utilizando el comando
git show <commit>
:
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
:
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
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
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:
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)
Copiamos el token generado y lo utilizamos ante el puerto 5000 con el nombre de auth
como vimos en el código server.py
:
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
Realizamos la misma petición pero esta vez con BurpSuite e identificamos que en el parámetro costume
se pasa el valor de phantom
:
Si cambiamos el valor de phantom
por cualquier cosa como por ejemplo h4rri
observamos que se muestra el valor de este:
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:
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:
A continuación enviamos el payload en BurpSuite:
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:
Observamos que el usuario root arranca una tarea cron y posteriormente ejecuta el script backup.sh
ubicado en /usr/bin
:
El script tiene el siguiente contenido:
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:
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
Observamos que el script se ejecuto correctamente. Ahora copiamos el ultimo fichero tar
creado al directorio tmp y lo descomprimimos:
Posteriormente ingresamos a la carpeta resultando la cual es opt y luego a backups:
Como apreciamos contamos con el fichero checksum, el cual si revisamos podemos notar que es una clave rsa para utilizar con SSH:
La copiamos y la guardamos en nuestra maquina de atacante. Le asignaremos permisos con chmod 600
para que contenga los permisos del propietario:
Observamos que tenemos acceso como usuario root, y ya podremos leer la flag:
Pwned! 🏴☠️