--- title: "Playbook de respuesta a incidentes en servidores Linux" description: "Playbook ante un servidor Linux comprometido: registra el caso, recoge evidencias volátiles, aísla la máquina, busca la persistencia y recupera el servicio." category: "Páginas de Estado e Incidentes" language: es source: https://cubepath.com/es/docs/páginas-de-estado-e-incidentes/playbook-de-respuesta-a-incidentes-linux updated: 2026-09-25 --- # Playbook de respuesta a incidentes en servidores Linux Cuando sospechas que un servidor ha sido comprometido, el orden en el que actúas importa: si reinicias o limpias antes de mirar, pierdes las evidencias que explican cómo entró el atacante. Este playbook recoge los pasos que debes seguir en un servidor Ubuntu 24.04 (los comandos valen también para Debian 12) desde la sospecha inicial hasta la recuperación: registrar el caso, capturar el estado en memoria, aislar la máquina, buscar mecanismos de persistencia, reconstruir y endurecer. Puedes copiarlo a tu wiki interna y adaptarlo a tu equipo. ## Requisitos previos - Acceso `sudo` al servidor afectado y, a ser posible, acceso por consola fuera de banda (por ejemplo, la consola VNC del panel de CubePath) por si pierdes el SSH durante la contención. - Una máquina de análisis separada (tu equipo o un servidor limpio) con espacio para guardar las evidencias. Nunca guardes las evidencias solo en el servidor comprometido. - Tu IP de administración (`your_admin_ip`) para no bloquearte al aislar el servidor. - Copias de seguridad recientes y probadas de los datos del servidor. > Importante: si el incidente puede implicar datos personales o tiene consecuencias legales, avisa a tu responsable de seguridad antes de tocar nada. Puede que haya que preservar el disco completo para un análisis forense profesional. ## Paso 1: Registrar el caso y clasificar la severidad Antes de ejecutar ningún comando, abre un registro del incidente (un ticket, un documento compartido) y anota la hora de cada acción. Ese registro será la base del informe posterior. Usa una escala sencilla: | Severidad | Criterio | Ejemplo | |-----------|----------|---------| | P1 | Compromiso confirmado en producción o datos expuestos | Webshell activa, usuario root desconocido | | P2 | Acceso no autorizado probable | Login SSH desde una IP y país inesperados | | P3 | Actividad sospechosa sin acceso confirmado | Proceso minando criptomonedas lanzado por `www-data` | | P4 | Alerta aislada | Escaneo de puertos o fuerza bruta bloqueada | Anota como mínimo: servidor afectado, quién lo detectó y cómo, primera evidencia, severidad y quién coordina la respuesta. ## Paso 2: Recoger evidencias volátiles Procesos, conexiones y sesiones desaparecen al reiniciar o aislar el servidor, así que se capturan primero. Para no escribir en el disco del servidor comprometido, guarda la salida en `/dev/shm`, que está en memoria. Define el nombre del caso: ```bash CASO="INC-$(date +%Y%m%d)-$(hostname -s)" sudo mkdir -p "/dev/shm/$CASO" ``` Captura el estado del sistema. Cada comando escribe un archivo separado: ```bash date -u | sudo tee "/dev/shm/$CASO/00-hora-utc.txt" sudo ps auxwwf | sudo tee "/dev/shm/$CASO/procesos.txt" > /dev/null sudo ss -tunap | sudo tee "/dev/shm/$CASO/conexiones.txt" > /dev/null sudo ss -tulpn | sudo tee "/dev/shm/$CASO/puertos-escucha.txt" > /dev/null sudo lsof -nP | sudo tee "/dev/shm/$CASO/archivos-abiertos.txt" > /dev/null w | sudo tee "/dev/shm/$CASO/sesiones.txt" > /dev/null sudo last -Fwx | sudo tee "/dev/shm/$CASO/logins.txt" > /dev/null ip addr | sudo tee "/dev/shm/$CASO/ip-addr.txt" > /dev/null ip route | sudo tee "/dev/shm/$CASO/ip-route.txt" > /dev/null sudo lsmod | sudo tee "/dev/shm/$CASO/modulos-kernel.txt" > /dev/null ``` Si ves un proceso sospechoso, guarda su binario y su línea de comandos antes de detenerlo. Aunque el atacante haya borrado el archivo del disco, sigue accesible a través de `/proc` mientras el proceso viva. Sustituye `1234` por su PID: ```bash sudo cp /proc/1234/exe "/dev/shm/$CASO/pid-1234.bin" sudo tr '\0' ' ' < /proc/1234/cmdline | sudo tee "/dev/shm/$CASO/pid-1234-cmdline.txt" sudo ls -l /proc/1234/cwd | sudo tee "/dev/shm/$CASO/pid-1234-cwd.txt" ``` Copia los logs antes de que roten o de que el atacante los borre: ```bash sudo journalctl --no-pager -o short-iso | sudo tee "/dev/shm/$CASO/journal.txt" > /dev/null sudo cp /var/log/auth.log* /var/log/syslog* "/dev/shm/$CASO/" ``` Empaqueta las evidencias, calcula su hash y envíalas a tu máquina de análisis por SSH. El archivo nunca toca el disco del servidor: ```bash sudo tar -C /dev/shm -czf - "$CASO" | ssh analyst@your_analysis_host "cat > $CASO.tar.gz" ``` En la máquina de análisis, calcula el hash y anótalo en el registro del caso. Así podrás demostrar después que las evidencias no se han modificado: ```bash sha256sum INC-*.tar.gz ``` ```output 3f1c9a...e27b INC-20260925-web-01.tar.gz ``` Si tu proveedor permite hacer un snapshot del disco, hazlo ahora: es la mejor copia del estado del sistema para analizar con calma sin tocar el original. ## Paso 3: Contener el incidente El objetivo es cortar la actividad del atacante sin destruir evidencias. Primero congela los procesos maliciosos en lugar de matarlos, así se conserva su memoria para un análisis posterior: ```bash sudo kill -STOP 1234 ``` Cierra las sesiones de cuentas sospechosas y bloquea su contraseña: ```bash sudo pkill -KILL -u usuario_sospechoso sudo usermod -L -e 1 usuario_sospechoso ``` Aísla el servidor en la red dejando solo tu IP de administración por SSH. Añade primero la regla de administración para no perder el acceso: ```bash sudo ufw allow from your_admin_ip to any port 22 proto tcp sudo ufw default deny incoming sudo ufw default deny outgoing sudo ufw enable ``` Revisa las reglas que quedan activas y elimina las que abran otros servicios (`sudo ufw delete `): ```bash sudo ufw status numbered ``` ```output To Action From -- ------ ---- [ 1] 22/tcp ALLOW IN 203.0.113.5 ``` UFW es stateful, así que tu sesión SSH actual sigue funcionando aunque el tráfico saliente nuevo quede bloqueado. Comprueba que el servidor ya no puede abrir conexiones hacia fuera: ```bash curl -m 5 -sI https://example.com || echo "salida bloqueada" ``` ```output salida bloqueada ``` Si el servidor forma parte de un clúster o usa claves y tokens compartidos (claves de API, credenciales de base de datos, claves SSH de despliegue), empieza ya a rotarlos desde un equipo limpio: da por hecho que el atacante los ha leído. ## Paso 4: Buscar el acceso inicial y la persistencia Con el servidor aislado, busca cómo entró el atacante y qué dejó para volver. Revisa primero los accesos SSH aceptados, agrupados por usuario e IP de origen. `zgrep` lee también los logs rotados y comprimidos: ```bash sudo zgrep -h "Accepted" /var/log/auth.log* | awk '{print $7, $9}' | sort | uniq -c | sort -rn ``` ```output 42 deploy 203.0.113.5 3 root 198.51.100.77 ``` Cualquier usuario o IP que no reconozcas marca el punto de partida de la investigación. Busca cuentas con UID 0 además de root y usuarios creados recientemente: ```bash sudo awk -F: '$3 == 0 {print $1}' /etc/passwd sudo zgrep -hE "useradd|usermod|groupadd" /var/log/auth.log* ``` ```output root ``` Revisa todas las claves SSH autorizadas del sistema: ```bash sudo find / -xdev -name authorized_keys -exec ls -l {} \; -exec cat {} \; ``` Los atacantes suelen persistir con tareas programadas y servicios de systemd. Lista los crontabs de todos los usuarios y los timers y unidades añadidos a mano: ```bash sudo ls -la /var/spool/cron/crontabs/ /etc/cron.d/ sudo systemctl list-timers --all sudo find /etc/systemd/system /usr/lib/systemd/system -type f -mtime -30 \( -name "*.service" -o -name "*.timer" \) ``` Comprueba `/etc/ld.so.preload`, que permite cargar una librería en todos los procesos y es un truco habitual de rootkits en espacio de usuario. En un sistema limpio no existe: ```bash ls -l /etc/ld.so.preload ``` ```output ls: cannot access '/etc/ld.so.preload': No such file or directory ``` Verifica la integridad de los archivos instalados por paquetes. `dpkg --verify` compara cada archivo con el checksum registrado al instalarlo; una `5` en la tercera columna indica que el contenido ha cambiado: ```bash sudo dpkg --verify ``` ```output ??5?????? /usr/bin/ssh ``` Los archivos de configuración (marcados con `c`) cambian legítimamente; los binarios de `/usr/bin` o `/usr/sbin` no deberían aparecer nunca. Por último, busca archivos modificados en los últimos días fuera de los directorios del sistema virtual y archivos PHP sospechosos en la raíz web: ```bash sudo find / -xdev -type f -mtime -3 -not -path "/proc/*" -not -path "/var/log/*" -not -path "/var/lib/*" 2>/dev/null | head -100 sudo grep -rlE "eval\(base64_decode|gzinflate\(|shell_exec\(" /var/www 2>/dev/null ``` Anota cada hallazgo con su ruta, fecha de modificación (`stat archivo`) y hash en el registro del caso. ## Paso 5: Erradicar y recuperar Un servidor en el que el atacante ha tenido privilegios de root no se puede considerar limpio aunque borres todo lo que has encontrado. Para incidentes P1 y P2 la única recuperación fiable es reconstruir: 1. Despliega un servidor nuevo desde una imagen limpia del sistema operativo. 2. Aplica las actualizaciones: `sudo apt update && sudo apt full-upgrade`. 3. Reinstala las aplicaciones desde tu repositorio de código o gestión de configuración, no copiando binarios del servidor comprometido. 4. Restaura los datos desde una copia de seguridad anterior al compromiso y revísalos (por ejemplo, busca webshells en los archivos subidos por usuarios). 5. Usa credenciales nuevas: contraseñas de base de datos, claves de API, claves SSH de usuarios y tokens de despliegue. 6. Corrige el vector de entrada identificado en el paso 4 (plugin vulnerable, contraseña débil, servicio expuesto) antes de publicar el servidor. Cambia el tráfico al servidor nuevo y conserva el comprometido apagado, o su snapshot, hasta cerrar la investigación. Para incidentes P3 y P4 sin escalada a root (por ejemplo, un proceso de `www-data`), puede bastar con eliminar los archivos maliciosos, actualizar la aplicación vulnerable y rotar las credenciales de esa aplicación. ## Paso 6: Mejorar la detección para el próximo incidente Deja en el servidor nuevo un registro de auditoría que te habría ayudado en esta investigación. Instala `auditd`: ```bash sudo apt install auditd sudo systemctl enable --now auditd ``` Crea un archivo de reglas que vigile cambios en cuentas, sudo y claves SSH, y los comandos ejecutados como root: ```bash sudo nano /etc/audit/rules.d/50-incidentes.rules ``` ```text -w /etc/passwd -p wa -k cuentas -w /etc/shadow -p wa -k cuentas -w /etc/group -p wa -k cuentas -w /etc/sudoers -p wa -k sudo -w /etc/sudoers.d/ -p wa -k sudo -w /etc/ssh/sshd_config -p wa -k ssh -w /root/.ssh/ -p wa -k ssh -w /etc/cron.d/ -p wa -k cron -w /etc/systemd/system/ -p wa -k systemd -a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -F auid!=unset -k comandos_root ``` Carga las reglas y comprueba que están activas: ```bash sudo augenrules --load sudo auditctl -l | head ``` Genera un evento de prueba y búscalo: ```bash sudo touch /etc/sudoers.d/prueba && sudo rm /etc/sudoers.d/prueba sudo ausearch -k sudo -ts recent ``` La salida debe mostrar dos eventos con `key="sudo"`. Envía también los logs a un servidor syslog centralizado: un atacante con root puede borrar los logs locales, pero no los que ya han salido de la máquina. ### Cerrar el caso Termina con una revisión sin culpables en la que el registro del paso 1 se convierte en informe: línea temporal, vector de entrada, datos afectados, qué funcionó en la respuesta, qué no, y acciones de mejora con responsable y fecha. ## Conclusión Has seguido un playbook completo: registrar el caso, capturar evidencias volátiles sin escribir en el disco comprometido, aislar el servidor sin perder el acceso, buscar la entrada y la persistencia, reconstruir desde una imagen limpia y añadir auditoría para el futuro. Como siguientes pasos, ensaya el playbook en un servidor de pruebas para medir cuánto tardas, automatiza el paso 2 en un script revisado que tengas listo antes de necesitarlo y configura alertas sobre las claves de `auditd` que acabas de definir.