¿Qué hace Análisis de artefactos de sistemas Linux?
Cuándo usar esta habilidad
- Al investigar un servidor o estación de trabajo Linux comprometido
- Para identificar mecanismos de persistencia (cron, systemd, claves SSH)
- Al rastrear actividad de usuarios mediante el historial de shell y logs de autenticación
- Durante la respuesta a incidentes para determinar el alcance de una brecha en Linux
- Para detectar rootkits, puertas traseras y modificaciones no autorizadas
Requisitos previos
- Imagen forense o acceso en vivo al sistema Linux (solo lectura)
- Comprensión de la jerarquía del sistema de archivos Linux (FHS)
- Conocimiento de ubicaciones comunes de logs en Linux (/var/log/)
- Herramientas: chkrootkit, rkhunter, AIDE, logs de auditd
- Familiaridad con systemd, cron y configuraciones de PAM
- Acceso root para la recolección completa de artefactos
Flujo de trabajo
Paso 1: Montar y recolectar artefactos del sistema
# Montar imagen forense en modo solo lectura
mount -o ro,loop,offset=$((2048*512)) /cases/case-2024-001/images/linux_evidence.dd /mnt/evidence
# Crear directorios de recolección
mkdir -p /cases/case-2024-001/linux/{logs,config,users,persistence,network}
# Recolectar logs de autenticación
cp /mnt/evidence/var/log/auth.log* /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/secure* /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/syslog* /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/kern.log* /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/audit/audit.log* /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/wtmp /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/btmp /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/lastlog /cases/case-2024-001/linux/logs/
cp /mnt/evidence/var/log/faillog /cases/case-2024-001/linux/logs/
# Recolectar artefactos de usuario
for user_dir in /mnt/evidence/home/*/; do
username=$(basename "$user_dir")
mkdir -p /cases/case-2024-001/linux/users/$username
cp "$user_dir"/.bash_history /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp "$user_dir"/.zsh_history /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp -r "$user_dir"/.ssh/ /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp "$user_dir"/.bashrc /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp "$user_dir"/.profile /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp "$user_dir"/.viminfo /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp "$user_dir"/.wget-hsts /cases/case-2024-001/linux/users/$username/ 2>/dev/null
cp "$user_dir"/.python_history /cases/case-2024-001/linux/users/$username/ 2>/dev/null
done
# Recolectar artefactos del usuario root
cp /mnt/evidence/root/.bash_history /cases/case-2024-001/linux/users/root/ 2>/dev/null
cp -r /mnt/evidence/root/.ssh/ /cases/case-2024-001/linux/users/root/ 2>/dev/null
# Recolectar configuración del sistema
cp /mnt/evidence/etc/passwd /cases/case-2024-001/linux/config/
cp /mnt/evidence/etc/shadow /cases/case-2024-001/linux/config/
cp /mnt/evidence/etc/group /cases/case-2024-001/linux/config/
cp /mnt/evidence/etc/sudoers /cases/case-2024-001/linux/config/
cp -r /mnt/evidence/etc/sudoers.d/ /cases/case-2024-001/linux/config/
cp /mnt/evidence/etc/hosts /cases/case-2024-001/linux/config/
cp /mnt/evidence/etc/resolv.conf /cases/case-2024-001/linux/config/
cp -r /mnt/evidence/etc/ssh/ /cases/case-2024-001/linux/config/
Paso 2: Analizar cuentas de usuario y autenticación
# Analizar cuentas de usuario en busca de anomalías
python3 << 'PYEOF'
print("=== ANÁLISIS DE CUENTAS DE USUARIO ===\n")
# Parsear /etc/passwd
with open('/cases/case-2024-001/linux/config/passwd') as f:
for line in f:
parts = line.strip().split(':')
if len(parts) >= 7:
username, _, uid, gid, comment, home, shell = parts[0], parts[1], int(parts[2]), int(parts[3]), parts[4], parts[5], parts[6]
# Marcar cuentas con UID 0 (equivalentes a root)
if uid == 0 and username != 'root':
print(f" ALERTA: Cuenta UID 0: {username} (shell: {shell})")
# Marcar cuentas con shells de inicio de sesión que no deberían tenerlas
if shell not in ('/bin/false', '/usr/sbin/nologin', '/bin/sync') and uid >= 1000:
print(f" Usuario: {username} (UID:{uid}, Shell:{shell}, Home:{home})")
# Marcar cuentas de sistema con shells de inicio de sesión
if uid < 1000 and uid > 0 and shell in ('/bin/bash', '/bin/sh', '/bin/zsh'):
print(f" ADVERTENCIA: Cuenta de sistema con shell: {username} (UID:{uid}, Shell:{shell})")
# Parsear /etc/shadow para estado de la cuenta
print("\n=== ESTADO DE CONTRASEÑAS ===")
with open('/cases/case-2024-001/linux/config/shadow') as f:
for line in f:
parts = line.strip().split(':')
if len(parts) >= 3:
username = parts[0]
pwd_hash = parts[1]
last_change = parts[2]
if pwd_hash and pwd_hash not in ('*', '!', '!!', ''):
hash_type = 'Desconocido'
if pwd_hash.startswith('$6$'): hash_type = 'SHA-512'
elif pwd_hash.startswith('$5$'): hash_type = 'SHA-256'
elif pwd_hash.startswith('$y$'): hash_type = 'yescrypt'
elif pwd_hash.startswith('$1$'): hash_type = 'MD5 (DÉBIL)'
print(f" {username}: hash {hash_type}, último cambio: día {last_change}")
PYEOF
# Analizar historial de inicio de sesión
last -f /cases/case-2024-001/linux/logs/wtmp > /cases/case-2024-001/linux/analysis/login_history.txt
lastb -f /cases/case-2024-001/linux/logs/btmp > /cases/case-2024-001/linux/analysis/failed_logins.txt 2>/dev/null
Paso 3: Examinar mecanismos de persistencia
# Revisar trabajos cron para todos los usuarios
echo "=== TRABAJOS CRON ===" > /cases/case-2024-001/linux/persistence/cron_analysis.txt
# Cron del sistema
for cronfile in /mnt/evidence/etc/crontab /mnt/evidence/etc/cron.d/*; do
echo "--- $cronfile ---" >> /cases/case-2024-001/linux/persistence/cron_analysis.txt
cat "$cronfile" 2>/dev/null >> /cases/case-2024-001/linux/persistence/cron_analysis.txt
echo "" >> /cases/case-2024-001/linux/persistence/cron_analysis.txt
done
# Cron tabs de usuarios
for cronfile in /mnt/evidence/var/spool/cron/crontabs/*; do
echo "--- Crontab de usuario: $(basename $cronfile) ---" >> /cases/case-2024-001/linux/persistence/cron_analysis.txt
cat "$cronfile" 2>/dev/null >> /cases/case-2024-001/linux/persistence/cron_analysis.txt
echo "" >> /cases/case-2024-001/linux/persistence/cron_analysis.txt
done
# Revisar servicios systemd para persistencia
echo "=== SERVICIOS SYSTEMD ===" > /cases/case-2024-001/linux/persistence/systemd_analysis.txt
find /mnt/evidence/etc/systemd/system/ -name "*.service" -newer /mnt/evidence/etc/os-release \
>> /cases/case-2024-001/linux/persistence/systemd_analysis.txt
for svc in /mnt/evidence/etc/systemd/system/*.service; do
echo "--- $(basename $svc) ---" >> /cases/case-2024-001/linux/persistence/systemd_analysis.txt
cat "$svc" >> /cases/case-2024-001/linux/persistence/systemd_analysis.txt
echo "" >> /cases/case-2024-001/linux/persistence/systemd_analysis.txt
done
# Revisar claves SSH autorizadas (detección de puertas traseras)
echo "=== CLAVES SSH AUTORIZADAS ===" > /cases/case-2024-001/linux/persistence/ssh_keys.txt
find /mnt/evidence/home/ /mnt/evidence/root/ -name "authorized_keys" -exec sh -c \
'echo "--- {} ---"; cat {}; echo ""' \; >> /cases/case-2024-001/linux/persistence/ssh_keys.txt
# Revisar rc.local y scripts de inicio
cat /mnt/evidence/etc/rc.local 2>/dev/null > /cases/case-2024-001/linux/persistence/rc_local.txt
# Revisar /etc/profile.d/ para scripts activados por inicio de sesión
ls -la /mnt/evidence/etc/profile.d/ > /cases/case-2024-001/linux/persistence/profile_scripts.txt
# Revisar secuestro de LD_PRELOAD
grep -r "LD_PRELOAD" /mnt/evidence/etc/ 2>/dev/null > /cases/case-2024-001/linux/persistence/ld_preload.txt
cat /mnt/evidence/etc/ld.so.preload 2>/dev/null >> /cases/case-2024-001/linux/persistence/ld_preload.txt
Paso 4: Analizar el historial de shell y ejecución de comandos
# Analizar el historial de bash para cada usuario
python3 << 'PYEOF'
import os, glob
print("=== ANÁLISIS DEL HISTORIAL DE SHELL ===\n")
suspicious_commands = [
'wget', 'curl', 'nc ', 'ncat', 'netcat', 'python -c', 'python3 -c',
'perl -e', 'base64', 'chmod 777', 'chmod +s', '/dev/tcp', '/dev/udp',
'nmap', 'masscan', 'hydra', 'john', 'hashcat', 'passwd', 'useradd',
'iptables -F', 'ufw disable', 'history -c', 'rm -rf /', 'dd if=',
'crontab', 'at ', 'systemctl enable', 'ssh-keygen', 'scp ', 'rsync',
'tar czf', 'zip -r', 'openssl enc', 'gpg --encrypt', 'shred',
'chattr', 'setfacl', 'awk', '/tmp/', '/dev/shm/'
]
for hist_file in glob.glob('/cases/case-2024-001/linux/users/*/.bash_history'):
username = hist_file.split('/')[-2]
print(f"Usuario: {username}")
with open(hist_file, 'r', errors='ignore') as f:
lines = f.readlines()
print(f" Total de comandos: {len(lines)}")
flagged = []
for i, line in enumerate(lines):
line = line.strip()
for cmd in suspicious_commands:
if cmd in line.lower():
flagged.append((i+1, line))
break
if flagged:
print(f" Comandos sospechosos: {len(flagged)}")
for lineno, cmd in flagged:
print(f" Línea {lineno}: {cmd[:120]}")
print()
PYEOF
Paso 5: Verificar rootkits y binarios modificados
# Verificar indicadores de rootkits conocidos
# Comparar hashes de binarios del sistema contra referencias conocidas
find /mnt/evidence/usr/bin/ /mnt/evidence/usr/sbin/ /mnt/evidence/bin/ /mnt/evidence/sbin/ \
-type f -executable -exec sha256sum {} \; > /cases/case-2024-001/linux/analysis/binary_hashes.txt
# Verificar binarios SUID/SGID (posible escalada de privilegios)
find /mnt/evidence/ -perm -4000 -type f 2>/dev/null > /cases/case-2024-001/linux/analysis/suid_files.txt
find /mnt/evidence/ -perm -2000 -type f 2>/dev/null > /cases/case-2024-001/linux/analysis/sgid_files.txt
# Verificar archivos sospechosos en /tmp y /dev/shm
find /mnt/evidence/tmp/ /mnt/evidence/dev/shm/ -type f 2>/dev/null \
-exec file {} \; > /cases/case-2024-001/linux/analysis/tmp_files.txt
# Verificar archivos y directorios ocultos
find /mnt/evidence/ -name ".*" -not -path "*/\." -type f 2>/dev/null | \
head -100 > /cases/case-2024-001/linux/analysis/hidden_files.txt
# Verificar módulos del kernel
ls -la /mnt/evidence/lib/modules/$(ls /mnt/evidence/lib/modules/ | head -1)/extra/ 2>/dev/null \
> /cases/case-2024-001/linux/analysis/extra_modules.txt
# Verificar modificaciones en la configuración de PAM (puertas traseras de autenticación)
diff /mnt/evidence/etc/pam.d/ /cases/baseline/pam.d/ 2>/dev/null \
> /cases/case-2024-001/linux/analysis/pam_changes.txt
Conceptos clave
| Concepto | Descripción |
|---|---|
| /var/log/auth.log | Log de autenticación principal en sistemas Debian/Ubuntu |
| /var/log/secure | Log de autenticación principal en sistemas RHEL/CentOS |
| wtmp/btmp | Logs binarios que registran sesiones de inicio de sesión exitosas y fallidas |
| .bash_history | Archivo de historial de comandos del usuario (puede ser limpiado por atacantes) |
| crontab | Sistema de tareas programadas comúnmente usado para persistencia |
| authorized_keys | Claves SSH públicas que otorgan acceso sin contraseña a una cuenta |
| Bit SUID | Permiso de archivo que permite la ejecución como propietario del archivo (vector de escalada de privilegios) |
| LD_PRELOAD | Variable de entorno que carga una biblioteca compartida antes que todas las demás (técnica de hooking) |
Herramientas y sistemas
| Herramienta | Propósito |
|---|---|
| chkrootkit | Escáner de detección de rootkits para sistemas Linux |
| rkhunter | Rootkit Hunter - verifica rootkits, puertas traseras y exploits locales |
| AIDE | Entorno de detección de intrusiones avanzado - monitor de integridad de archivos |
| auditd | Marco de auditoría de Linux para monitoreo de llamadas al sistema y acceso a archivos |
| last/lastb | Analiza wtmp/btmp para historial de inicio de sesión y fallos |
| Plaso/log2timeline | Creación de superlíneas de tiempo incluyendo artefactos de Linux |
| osquery | Consultas del sistema basadas en SQL para investigación forense en vivo |
| Velociraptor | Agente de punto final con capacidad de recolección de artefactos de Linux |
Escenarios comunes
Escenario 1: Fuerza bruta SSH seguida de compromiso Analiza auth.log en busca de intentos SSH fallidos seguidos de éxito, identifica la IP atacante, revisa .bash_history en busca de comandos posteriores al compromiso, examina authorized_keys en busca de claves de puerta trasera añadidas, revisa crontab en busca de persistencia, revisa conexiones de red.
Escenario 2: Compromiso de servidor web mediante vulnerabilidad de aplicación Examina los logs de acceso y error del servidor web en busca de intentos de explotación, verifica /tmp y /dev/shm en busca de webshells, analiza la actividad del usuario del servidor web (www-data), verifica escalada de privilegios mediante binarios SUID o exploits del kernel, revisa conexiones salientes.
Escenario 3: Amenaza interna en servidor de base de datos Analiza el historial de bash del usuario sospechoso en busca de comandos de volcado de base de datos, verifica archivos grandes tar/zip en el directorio home o /tmp, examina comandos scp/rsync en busca de transferencia de datos, revisa trabajos cron en busca de exfiltración automatizada, verifica logs de dispositivos USB.
Escenario 4: Criptominero en instancia en la nube Verifica procesos de alta CPU en /proc (en vivo) o archivos de servicio systemd, examina entradas de crontab en busca de scripts de reinicio del minero, verifica /tmp en busca de binarios de minería, analiza conexiones de red en busca de comunicaciones con pools de minería, revisa authorized_keys en busca de acceso del atacante.
Formato de salida
Resumen Forense de Linux:
Sistema: webserver01 (Ubuntu 22.04 LTS)
Hostname: webserver01.corp.local
Kernel: 5.15.0-91-generic
Cuentas de usuario:
Total: 25 (3 con UID 0 - 1 ANÓMALA)
Shells interactivos: 8 usuarios
Creadas recientemente: admin2 (creado 2024-01-15)
Eventos de autenticación:
Inicios de sesión SSH exitosos: 456
Intentos SSH fallidos: 12,345 (desde 23 IPs únicas)
Ejecuciones de sudo: 89
Mecanismos de persistencia encontrados:
Trabajos cron: 3 sospechosos (reverse shell, reinicio de minero)
Servicios systemd: 1 desconocido (update-checker.service)
Claves SSH: 2 claves no autorizadas en authorized_keys de root
rc.local: Modificado con descarga de cradle
Actividad sospechosa:
- bash_history contiene wget a URL de pastebin
- Binario SUID /t
...