📄 Contenido del archivo
#!/bin/bash
# ============================================================
# SCRIPT DE AUDITORIA DE SEGURIDAD
# Secretaria de la Funcion Publica - Zacatecas
# Version: 1.0 - Febrero 2026
# Uso: bash auditoria_servidor.sh > resultado_$(hostname).txt 2>&1
# ============================================================
HOSTNAME=$(hostname)
FECHA=$(date '+%Y-%m-%d %H:%M:%S')
REPORTE="/tmp/auditoria_${HOSTNAME}_$(date +%Y%m%d).txt"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
ALERTAS=0
ADVERTENCIAS=0
log() { echo -e "$1" | tee -a "$REPORTE"; }
alerta() { log "${RED}[ALERTA]${NC} $1"; ALERTAS=$((ALERTAS+1)); }
advertencia() { log "${YELLOW}[ADVERTENCIA]${NC} $1"; ADVERTENCIAS=$((ADVERTENCIAS+1)); }
ok() { log "${GREEN}[OK]${NC} $1"; }
seccion() { log "\n========================================"; log " $1"; log "========================================"; }
log "============================================================"
log " REPORTE DE AUDITORIA DE SEGURIDAD"
log " Servidor: $HOSTNAME"
log " Fecha: $FECHA"
log "============================================================"
# ------------------------------------------------------------
seccion "1. CONEXIONES EXTERNAS ACTIVAS"
# ------------------------------------------------------------
CONEXIONES_EXT=$(ss -tnp 2>/dev/null | grep ESTAB | grep -v '10\.\|127\.\|::1' | grep -v '192\.168\.')
if [ -n "$CONEXIONES_EXT" ]; then
alerta "Conexiones externas activas detectadas:"
echo "$CONEXIONES_EXT" | tee -a "$REPORTE"
else
ok "Sin conexiones externas sospechosas"
fi
# ------------------------------------------------------------
seccion "2. PROCESOS SOSPECHOSOS"
# ------------------------------------------------------------
# Buscar procesos con nombres inusuales conectados a internet
PROCS_RAROS=$(ps aux | grep -v "httpd\|sshd\|mysql\|php\|cron\|postfix\|systemd\|bash\|python\|root\|apache\|nobody\|\[" | grep -v "^USER\|ps\|grep\|awk\|sort\|tee\|sed\|cut\|chrony\|polkit\|dbus\|irqbalance\|rsyslog\|lvmetad\|agetty\|pickup\|qmgr\|su\|nano\|vim\|cat\|tail\|head\|less" | grep -v "^$")
if [ -n "$PROCS_RAROS" ]; then
advertencia "Procesos inusuales encontrados:"
echo "$PROCS_RAROS" | tee -a "$REPORTE"
else
ok "Sin procesos inusuales"
fi
# Buscar especificamente los backdoors conocidos
for BACKDOOR in stderr.w stderr.q stderr.d stderr.l; do
if pgrep -x "$BACKDOOR" > /dev/null 2>&1; then
alerta "BACKDOOR ACTIVO: $BACKDOOR corriendo en este servidor"
fi
if [ -f "/usr/bin/$BACKDOOR" ]; then
alerta "BACKDOOR ENCONTRADO: /usr/bin/$BACKDOOR existe"
fi
done
# ------------------------------------------------------------
seccion "3. BINARIOS MALICIOSOS EN /usr/bin y /usr/sbin"
# ------------------------------------------------------------
# Buscar archivos ejecutables recientes no reconocidos
BINARIOS_NUEVOS=$(find /usr/bin /usr/sbin /bin /sbin -newer /usr/bin/python -type f -ls 2>/dev/null | grep -v '2018\|2019\|2020\|2021\|2022\|2023')
if [ -n "$BINARIOS_NUEVOS" ]; then
alerta "Binarios inusuales en directorios del sistema:"
echo "$BINARIOS_NUEVOS" | tee -a "$REPORTE"
else
ok "Sin binarios inusuales en directorios del sistema"
fi
# Verificar integridad de binarios criticos
for BIN in /usr/bin/ls /usr/bin/ps /usr/bin/netstat /usr/sbin/sshd; do
if [ -f "$BIN" ]; then
rpm -Vf "$BIN" 2>/dev/null | grep "^..5" > /dev/null && advertencia "Binario modificado: $BIN" || ok "Integridad OK: $BIN"
fi
done
# ------------------------------------------------------------
seccion "4. WEBSHELLS Y PHP SOSPECHOSO"
# ------------------------------------------------------------
if [ -d /var/www ]; then
# index.php con cloaking
INDEXPHP_MALOS=$(grep -rl 'HTTP_USER_AGENT.*bot\|preg_match.*bot\|bocoranolympus\|jendralmaya' /var/www/*/index.php /var/www/html/*/index.php 2>/dev/null)
if [ -n "$INDEXPHP_MALOS" ]; then
alerta "index.php comprometidos con codigo de cloaking:"
echo "$INDEXPHP_MALOS" | tee -a "$REPORTE"
else
ok "Sin index.php comprometidos"
fi
# PHP en carpetas estaticas (excluyendo vendors y dompdf/tcpdf que son legitimos)
PHP_ESTATICO=$(find /var/www/ \( -path '*/css/*.php' -o -path '*/js/*.php' -o -path '*/images/*.php' \) 2>/dev/null | grep -v 'vendor\|dompdf\|tcpdf\|phpseclib')
if [ -n "$PHP_ESTATICO" ]; then
alerta "PHP en carpetas estaticas (posibles webshells):"
echo "$PHP_ESTATICO" | tee -a "$REPORTE"
else
ok "Sin PHP sospechoso en carpetas estaticas"
fi
# Buscar patrones de webshell en PHP (eval+base64, system, passthru)
WEBSHELLS=$(grep -rl 'eval(base64_decode\|system($_\|passthru($_\|shell_exec($_\|exec($_REQUEST' /var/www/ 2>/dev/null | grep -v vendor | grep '\.php$')
if [ -n "$WEBSHELLS" ]; then
alerta "Posibles webshells detectadas:"
echo "$WEBSHELLS" | tee -a "$REPORTE"
else
ok "Sin patrones de webshell detectados"
fi
else
advertencia "No existe /var/www - verificar rutas de aplicaciones"
fi
# ------------------------------------------------------------
seccion "5. ARCHIVOS MODIFICADOS RECIENTEMENTE"
# ------------------------------------------------------------
# PHP modificados en las ultimas 72 horas
PHP_RECIENTES=$(find /var/www/ -name "*.php" -mtime -3 2>/dev/null | grep -v 'vendor\|storage/framework/views\|cache' | head -20)
if [ -n "$PHP_RECIENTES" ]; then
advertencia "Archivos PHP modificados en las ultimas 72 horas:"
echo "$PHP_RECIENTES" | tee -a "$REPORTE"
else
ok "Sin PHP modificados recientemente"
fi
# Archivos en /tmp y /var/tmp
TMP_FILES=$(find /tmp /var/tmp -type f -newer /usr/bin/python 2>/dev/null | grep -v 'systemd-private\|sess_')
if [ -n "$TMP_FILES" ]; then
advertencia "Archivos en /tmp o /var/tmp:"
echo "$TMP_FILES" | tee -a "$REPORTE"
else
ok "Sin archivos sospechosos en /tmp"
fi
# ------------------------------------------------------------
seccion "6. USUARIOS Y ACCESOS SSH"
# ------------------------------------------------------------
# Usuarios con shell activo
log "Usuarios con acceso shell:"
grep -v 'nologin\|false\|sync\|shutdown\|halt' /etc/passwd | tee -a "$REPORTE"
# Verificar authorized_keys de todos los usuarios con home
log "\nLlaves SSH autorizadas:"
for DIR in /root /home/*; do
KEYFILE="$DIR/.ssh/authorized_keys"
if [ -f "$KEYFILE" ]; then
USUARIO=$(basename $DIR)
LLAVES=$(wc -l < "$KEYFILE")
log " $USUARIO: $LLAVES llave(s) en $KEYFILE"
cat "$KEYFILE" | tee -a "$REPORTE"
fi
done
# Ultimos logins
log "\nUltimos 10 accesos SSH aceptados:"
grep "Accepted" /var/log/secure 2>/dev/null | tail -10 | tee -a "$REPORTE"
# Intentos fallidos recientes
FALLIDOS=$(grep "Failed password" /var/log/secure 2>/dev/null | wc -l)
if [ "$FALLIDOS" -gt 100 ]; then
advertencia "Alto numero de intentos fallidos de SSH: $FALLIDOS"
log "Top IPs atacantes:"
grep "Failed password" /var/log/secure 2>/dev/null | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' | sort | uniq -c | sort -rn | head -5 | tee -a "$REPORTE"
elif [ "$FALLIDOS" -gt 0 ]; then
advertencia "Intentos fallidos de SSH: $FALLIDOS"
else
ok "Sin intentos fallidos de SSH en log actual"
fi
# ------------------------------------------------------------
seccion "7. CRON JOBS"
# ------------------------------------------------------------
log "Cron jobs de todos los usuarios:"
for U in $(cut -d: -f1 /etc/passwd); do
CRON=$(crontab -u $U -l 2>/dev/null | grep -v '^#' | grep -v '^$')
if [ -n "$CRON" ]; then
log " Usuario $U:"
echo "$CRON" | tee -a "$REPORTE"
fi
done
log "\nCron del sistema:"
ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/ /etc/cron.weekly/ 2>/dev/null | tee -a "$REPORTE"
# Buscar crons sospechosos
if grep -r 'curl\|wget\|bash -i\|/dev/tcp\|base64' /var/spool/cron/ /etc/cron.d/ 2>/dev/null | grep -v '^#'; then
alerta "Cron con comandos sospechosos detectado"
fi
# ------------------------------------------------------------
seccion "8. PUERTOS Y SERVICIOS"
# ------------------------------------------------------------
log "Puertos en escucha:"
ss -tlnp 2>/dev/null | tee -a "$REPORTE"
# ------------------------------------------------------------
seccion "9. INTEGRIDAD DEL SISTEMA (RPM)"
# ------------------------------------------------------------
log "Verificando paquetes criticos..."
RPM_MODIFICADOS=$(rpm -Va 2>/dev/null | grep "^..5" | grep -v 'doc\|config\|log\|pid' | head -20)
if [ -n "$RPM_MODIFICADOS" ]; then
advertencia "Archivos de sistema modificados vs. paquetes RPM:"
echo "$RPM_MODIFICADOS" | tee -a "$REPORTE"
else
ok "Paquetes del sistema sin modificaciones detectadas"
fi
# ------------------------------------------------------------
seccion "10. ARCHIVOS .ENV EXPUESTOS"
# ------------------------------------------------------------
log "Verificando permisos de archivos .env:"
find /var/www/ -name ".env" 2>/dev/null | while read ENV; do
PERMS=$(stat -c "%a" "$ENV")
if [ "$PERMS" != "600" ] && [ "$PERMS" != "640" ]; then
advertencia "Permisos inseguros en $ENV (actual: $PERMS, debe ser 600)"
else
ok "Permisos OK: $ENV ($PERMS)"
fi
done
# ------------------------------------------------------------
seccion "RESUMEN FINAL"
# ------------------------------------------------------------
log "\n============================================================"
log " RESULTADO: Servidor $HOSTNAME"
log " Fecha: $FECHA"
log "------------------------------------------------------------"
if [ "$ALERTAS" -gt 0 ]; then
log " ${RED}ALERTAS CRITICAS: $ALERTAS${NC} - REQUIERE ATENCION INMEDIATA"
fi
if [ "$ADVERTENCIAS" -gt 0 ]; then
log " ${YELLOW}ADVERTENCIAS: $ADVERTENCIAS${NC} - Revisar y evaluar"
fi
if [ "$ALERTAS" -eq 0 ] && [ "$ADVERTENCIAS" -eq 0 ]; then
log " ${GREEN}SIN ALERTAS - Servidor aparentemente limpio${NC}"
fi
log "------------------------------------------------------------"
log " Reporte guardado en: $REPORTE"
log "============================================================"
# Crear marca de tiempo para proxima ejecucion
touch /tmp/.lastcheck_auditoria
echo ""
echo "Auditoria completada. Reporte en: $REPORTE"