Logs y Análisis Forense en Linux: Investigación y Seguridad de Sistemas
Los logs del sistema son la caja negra de cualquier servidor Linux. Contienen una riqueza de información sobre todo lo que ocurre en el sistema: conexiones, errores, actividad de usuarios, procesos y mucho más. Dominar el análisis de logs es fundamental para la administración de sistemas, troubleshooting y, especialmente, para la investigación forense y detección de incidentes de seguridad.
Fundamentos del Sistema de Logging
Arquitectura del Logging en Linux
En Linux, el sistema de logging tradicionalmente se basa en syslog, aunque sistemas modernos también utilizan systemd-journald. Entender ambos es crucial para un análisis efectivo.
1
2
3
4
5
6
7
| # Ver servicios de logging activos
systemctl status rsyslog
systemctl status systemd-journald
# Verificar configuración de rsyslog
cat /etc/rsyslog.conf
ls -la /etc/rsyslog.d/
|
Facilidades y Prioridades de Syslog
1
2
3
4
5
6
7
8
9
10
11
| # Facilidades (qué tipo de programa genera el log)
# kern, user, mail, daemon, auth, syslog, lpr, news, uucp, cron, authpriv, ftp
# local0-local7
# Prioridades/Severidades (importancia del mensaje)
# emerg(0), alert(1), crit(2), err(3), warning(4), notice(5), info(6), debug(7)
# Ejemplo de configuración en /etc/rsyslog.conf
# mail.info /var/log/mail.log
# auth,authpriv.* /var/log/auth.log
# *.emerg :omusrmsg:*
|
Ubicaciones Principales de Logs
Logs del Sistema
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # Logs principales en /var/log/
/var/log/syslog # Log general del sistema (Debian/Ubuntu)
/var/log/messages # Log general del sistema (CentOS/RHEL)
/var/log/auth.log # Autenticación (Debian/Ubuntu)
/var/log/secure # Autenticación (CentOS/RHEL)
/var/log/kern.log # Kernel
/var/log/dmesg # Mensajes del kernel al arranque
/var/log/boot.log # Proceso de arranque
/var/log/cron.log # Tareas cron
/var/log/mail.log # Servidor de correo
/var/log/apache2/ # Apache web server
/var/log/nginx/ # Nginx web server
/var/log/mysql/ # MySQL/MariaDB
/var/log/postgresql/ # PostgreSQL
# Ver todos los logs disponibles
ls -la /var/log/
find /var/log -name "*.log" -type f
|
Journald (systemd)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| # Ver logs del journal
journalctl
# Logs desde el último arranque
journalctl -b
# Logs en tiempo real
journalctl -f
# Logs de un servicio específico
journalctl -u nginx
journalctl -u ssh
# Logs por prioridad
journalctl -p err # Solo errores y más críticos
journalctl -p warning # Warnings y más críticos
# Logs por tiempo
journalctl --since "2025-06-30 10:00:00"
journalctl --since "1 hour ago"
journalctl --until "2025-06-30 18:00:00"
# Logs de usuario específico
journalctl _UID=1000
|
Herramientas de Análisis de Logs
Comandos Básicos de Análisis
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # Ver últimas líneas de un log
tail -f /var/log/syslog
tail -n 100 /var/log/auth.log
# Buscar patrones específicos
grep "Failed password" /var/log/auth.log
grep -i "error" /var/log/syslog
grep -E "(failed|error|critical)" /var/log/syslog
# Buscar con contexto
grep -A 5 -B 5 "kernel panic" /var/log/syslog
# Buscar en múltiples archivos
grep -r "suspicious activity" /var/log/
# Contar ocurrencias
grep -c "Failed password" /var/log/auth.log
grep "Failed password" /var/log/auth.log | wc -l
|
Análisis Estadístico con awk y sed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| # Extraer IPs de intentos fallidos de SSH
grep "Failed password" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -nr
# Top 10 IPs con más intentos fallidos
grep "Failed password" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -nr | head -10
# Análisis de conexiones SSH exitosas por usuario
grep "Accepted password" /var/log/auth.log | awk '{print $9}' | sort | uniq -c | sort -nr
# Análisis de errores de Apache por código de estado
awk '($9 >= 400)' /var/log/apache2/access.log | awk '{print $9}' | sort | uniq -c | sort -nr
# Análisis de tráfico por hora
awk '{print $4}' /var/log/apache2/access.log | cut -d: -f2 | sort | uniq -c
# IPs que más recursos consumen
awk '{print $1}' /var/log/apache2/access.log | sort | uniq -c | sort -nr | head -20
|
Scripts de Análisis Automatizado
Script de Análisis de Seguridad
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
| #!/bin/bash
# security_log_analysis.sh - Análisis automatizado de logs de seguridad
set -e
LOG_FILE="/var/log/auth.log"
REPORT_FILE="/tmp/security_report_$(date +%Y%m%d).txt"
ALERT_THRESHOLD=50
# Función de logging
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$REPORT_FILE"
}
# Análisis de intentos de login fallidos
analyze_failed_logins() {
log "=== ANÁLISIS DE INTENTOS DE LOGIN FALLIDOS ==="
local failed_attempts=$(grep "Failed password" "$LOG_FILE" | wc -l)
log "Total de intentos fallidos: $failed_attempts"
if [ "$failed_attempts" -gt "$ALERT_THRESHOLD" ]; then
log "⚠️ ALERTA: Número elevado de intentos fallidos detectado!"
fi
log "Top 10 IPs con más intentos fallidos:"
grep "Failed password" "$LOG_FILE" | \
awk '{print $11}' | \
sort | uniq -c | sort -nr | head -10 | \
while read count ip; do
log " $ip: $count intentos"
# Verificar si la IP debe ser bloqueada
if [ "$count" -gt 20 ]; then
log " ⚠️ IP $ip supera 20 intentos - considerar bloqueo"
fi
done
log ""
}
# Análisis de logins exitosos
analyze_successful_logins() {
log "=== ANÁLISIS DE LOGINS EXITOSOS ==="
local successful_logins=$(grep "Accepted password\|Accepted publickey" "$LOG_FILE" | wc -l)
log "Total de logins exitosos: $successful_logins"
log "Usuarios con logins exitosos:"
grep "Accepted password\|Accepted publickey" "$LOG_FILE" | \
awk '{print $9}' | \
sort | uniq -c | sort -nr | \
while read count user; do
log " $user: $count logins"
done
log "IPs de logins exitosos:"
grep "Accepted password\|Accepted publickey" "$LOG_FILE" | \
awk '{print $11}' | \
sort | uniq -c | sort -nr | head -10 | \
while read count ip; do
log " $ip: $count logins"
done
log ""
}
# Análisis de actividad de sudo
analyze_sudo_activity() {
log "=== ANÁLISIS DE ACTIVIDAD SUDO ==="
if grep -q "sudo" "$LOG_FILE"; then
local sudo_attempts=$(grep "sudo" "$LOG_FILE" | wc -l)
log "Total de comandos sudo: $sudo_attempts"
log "Usuarios que usaron sudo:"
grep "sudo" "$LOG_FILE" | \
awk '{print $5}' | \
sed 's/://' | \
sort | uniq -c | sort -nr | \
while read count user; do
log " $user: $count comandos"
done
# Comandos sudo fallidos
local failed_sudo=$(grep "sudo.*authentication failure" "$LOG_FILE" | wc -l)
if [ "$failed_sudo" -gt 0 ]; then
log "⚠️ Intentos sudo fallidos: $failed_sudo"
fi
else
log "No se encontró actividad sudo en el log."
fi
log ""
}
# Análisis de nuevas conexiones
analyze_new_connections() {
log "=== ANÁLISIS DE NUEVAS CONEXIONES ==="
local new_connections=$(grep "New session" "$LOG_FILE" | wc -l)
log "Total de nuevas sesiones: $new_connections"
# Conexiones por hora
log "Distribución de conexiones por hora:"
grep "New session" "$LOG_FILE" | \
awk '{print $3}' | \
cut -d: -f1 | \
sort | uniq -c | \
sort -k2 -n | \
while read count hour; do
log " ${hour}:00 - $count conexiones"
done
log ""
}
# Detección de patrones sospechosos
detect_suspicious_patterns() {
log "=== DETECCIÓN DE PATRONES SOSPECHOSOS ==="
# Intentos de login fuera de horario normal
local night_attempts=$(grep "Failed password" "$LOG_FILE" | \
awk '$3 ~ /^(2[0-3]|0[0-6]):/' | wc -l)
if [ "$night_attempts" -gt 10 ]; then
log "⚠️ Intentos de login sospechosos fuera de horario: $night_attempts"
fi
# Múltiples usuarios desde misma IP
log "IPs que intentaron múltiples usuarios:"
grep "Failed password" "$LOG_FILE" | \
awk '{print $11 " " $9}' | \
sort | uniq | \
awk '{print $1}' | \
sort | uniq -c | \
awk '$1 > 3 {print $2 ": " $1 " usuarios diferentes"}' | \
while read line; do
log " ⚠️ $line"
done
# Verificar intentos de escalación de privilegios
local su_attempts=$(grep "su.*authentication failure" "$LOG_FILE" | wc -l)
if [ "$su_attempts" -gt 0 ]; then
log "⚠️ Intentos fallidos de su: $su_attempts"
fi
log ""
}
# Generar recomendaciones
generate_recommendations() {
log "=== RECOMENDACIONES DE SEGURIDAD ==="
# Analizar configuración SSH
if [ -f "/etc/ssh/sshd_config" ]; then
if grep -q "PermitRootLogin yes" /etc/ssh/sshd_config; then
log "⚠️ RECOMENDACIÓN: Deshabilitar login directo de root"
fi
if ! grep -q "MaxAuthTries" /etc/ssh/sshd_config; then
log "⚠️ RECOMENDACIÓN: Configurar MaxAuthTries en SSH"
fi
if ! grep -q "AllowUsers\|AllowGroups" /etc/ssh/sshd_config; then
log "⚠️ RECOMENDACIÓN: Limitar usuarios SSH con AllowUsers"
fi
fi
# Verificar fail2ban
if ! command -v fail2ban-client > /dev/null; then
log "⚠️ RECOMENDACIÓN: Instalar fail2ban para protección automática"
fi
log ""
}
# Función principal
main() {
log "Iniciando análisis de seguridad de logs"
log "Log analizado: $LOG_FILE"
log "Período: $(head -1 "$LOG_FILE" | awk '{print $1, $2, $3}') - $(tail -1 "$LOG_FILE" | awk '{print $1, $2, $3}')"
log ""
analyze_failed_logins
analyze_successful_logins
analyze_sudo_activity
analyze_new_connections
detect_suspicious_patterns
generate_recommendations
log "Análisis completado. Reporte guardado en: $REPORT_FILE"
}
# Verificar que el log existe
if [ ! -f "$LOG_FILE" ]; then
echo "Error: Log file $LOG_FILE no encontrado"
exit 1
fi
main "$@"
|
Análisis Forense Avanzado
Preservación de Evidencia
1
2
3
4
5
6
7
8
9
| # Crear imagen forense de logs antes de análisis
sudo dd if=/var/log/auth.log of=/evidence/auth.log.img bs=1M conv=noerror,sync
sudo sha256sum /evidence/auth.log.img > /evidence/auth.log.img.sha256
# Montar como solo lectura para análisis
sudo mount -o loop,ro /evidence/auth.log.img /mnt/evidence/
# Crear copia de trabajo
sudo cp /evidence/auth.log.img /working/auth.log.work
|
Timeline Analysis
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
| #!/bin/bash
# timeline_analysis.sh - Crear timeline de eventos de seguridad
LOG_FILE="/var/log/auth.log"
TIMELINE_FILE="/tmp/security_timeline.txt"
create_timeline() {
echo "Creando timeline de eventos de seguridad..."
# Extraer eventos relevantes con timestamp
{
# Logins exitosos
grep "Accepted password\|Accepted publickey" "$LOG_FILE" | \
sed 's/^/LOGIN_SUCCESS: /'
# Logins fallidos
grep "Failed password" "$LOG_FILE" | \
sed 's/^/LOGIN_FAILED: /'
# Actividad sudo
grep "sudo.*COMMAND" "$LOG_FILE" | \
sed 's/^/SUDO_COMMAND: /'
# Nuevas sesiones
grep "New session" "$LOG_FILE" | \
sed 's/^/NEW_SESSION: /'
# Desconexiones
grep "session closed" "$LOG_FILE" | \
sed 's/^/SESSION_CLOSED: /'
} | sort -k2,3 > "$TIMELINE_FILE"
echo "Timeline creado en: $TIMELINE_FILE"
}
# Análisis de timeline por períodos
analyze_timeline_patterns() {
echo "=== ANÁLISIS DE PATRONES TEMPORALES ==="
# Actividad por día de la semana
echo "Actividad por día de la semana:"
awk '{print $2}' "$TIMELINE_FILE" | \
xargs -I {} date -d {} +%A 2>/dev/null | \
sort | uniq -c | sort -nr
# Actividad por hora del día
echo -e "\nActividad por hora:"
awk '{print $3}' "$TIMELINE_FILE" | \
cut -d: -f1 | \
sort | uniq -c | sort -k2 -n
# Detectar actividad fuera de horario normal
echo -e "\nActividad fuera de horario (22:00-06:00):"
awk '$3 ~ /^(2[2-3]|0[0-5]):/ {print}' "$TIMELINE_FILE" | wc -l
}
create_timeline
analyze_timeline_patterns
|
Correlación de Eventos
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| #!/bin/bash
# event_correlation.sh - Correlacionar eventos de múltiples logs
correlate_web_auth_events() {
local auth_log="/var/log/auth.log"
local access_log="/var/log/apache2/access.log"
local output_file="/tmp/correlation_report.txt"
echo "=== CORRELACIÓN DE EVENTOS WEB Y AUTENTICACIÓN ===" > "$output_file"
# Extraer IPs de ambos logs en el mismo período
echo "Analizando correlación entre intentos SSH y tráfico web..." >> "$output_file"
# IPs con intentos SSH fallidos
grep "Failed password" "$auth_log" | \
awk '{print $11}' | sort | uniq > /tmp/ssh_failed_ips.txt
# IPs en logs de Apache
awk '{print $1}' "$access_log" | sort | uniq > /tmp/web_ips.txt
# IPs que aparecen en ambos logs
echo -e "\nIPs con actividad SSH fallida y tráfico web:" >> "$output_file"
comm -12 /tmp/ssh_failed_ips.txt /tmp/web_ips.txt | \
while read ip; do
ssh_attempts=$(grep "Failed password.*$ip" "$auth_log" | wc -l)
web_requests=$(grep "^$ip " "$access_log" | wc -l)
echo " $ip: $ssh_attempts intentos SSH, $web_requests requests web" >> "$output_file"
done
# Limpiar archivos temporales
rm -f /tmp/ssh_failed_ips.txt /tmp/web_ips.txt
echo "Reporte de correlación guardado en: $output_file"
}
correlate_web_auth_events
|
Herramientas Especializadas
GoAccess para Logs Web
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # Instalar GoAccess
sudo apt install goaccess
# Análisis en tiempo real de logs Apache/Nginx
goaccess /var/log/apache2/access.log -c
# Generar reporte HTML
goaccess /var/log/apache2/access.log -o /tmp/report.html --log-format=COMBINED
# Análisis en tiempo real con HTML
goaccess /var/log/apache2/access.log -o /var/www/html/stats.html --log-format=COMBINED --real-time-html
# Filtrar por fecha específica
grep "30/Jun/2025" /var/log/apache2/access.log | goaccess -a -o /tmp/daily_report.html
|
ELK Stack Básico
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| # Configuración básica de Logstash
# /etc/logstash/conf.d/syslog.conf
input {
file {
path => "/var/log/syslog"
type => "syslog"
}
file {
path => "/var/log/auth.log"
type => "auth"
}
}
filter {
if [type] == "auth" {
grok {
match => { "message" => "%{SYSLOGTIMESTAMP:timestamp} %{WORD:hostname} %{WORD:program}(?:\[%{POSINT:pid}\])?: %{GREEDYDATA:message}" }
}
if "Failed password" in [message] {
grok {
match => { "message" => "Failed password for %{USERNAME:username} from %{IP:src_ip}" }
}
mutate {
add_tag => ["auth_failure"]
}
}
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "logs-%{+YYYY.MM.dd}"
}
}
|
Splunk Alternative - rsyslog con database
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| # Configurar rsyslog para enviar a MySQL
# /etc/rsyslog.conf
$ModLoad ommysql
auth,authpriv.* :ommysql:localhost,syslog,rsyslog,password
# Crear tabla en MySQL
CREATE TABLE SystemEvents (
ID int unsigned not null auto_increment primary key,
CustomerID bigint,
ReceivedAt datetime NULL,
DeviceReportedTime datetime NULL,
Facility smallint NULL,
Priority smallint NULL,
FromHost varchar(60) NULL,
Message text,
NTSeverity int NULL,
Importance int NULL,
EventSource varchar(60),
EventUser varchar(60) NULL,
EventCategory int NULL,
EventID int NULL,
EventBinaryData text NULL,
MaxAvailable int NULL,
CurrUsage int NULL,
MinUsage int NULL,
MaxUsage int NULL,
InfoUnitID int NULL,
SysLogTag varchar(60),
EventLogType varchar(60),
GenericFileName VarChar(60),
SystemID int NULL
);
|
Automatización y Alertas
Script de Monitoreo en Tiempo Real
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
| #!/bin/bash
# real_time_monitor.sh - Monitoreo en tiempo real de logs críticos
LOG_FILES=("/var/log/auth.log" "/var/log/syslog" "/var/log/apache2/error.log")
ALERT_EMAIL="admin@empresa.com"
PATTERNS_FILE="/etc/log_monitor/alert_patterns.txt"
# Patrones que generan alertas (uno por línea)
cat > "$PATTERNS_FILE" << 'EOF'
Failed password.*root
authentication failure
kernel panic
Out of memory
segfault
sudo.*authentication failure
Invalid user
Connection closed by.*\[preauth\]
EOF
# Función para enviar alerta
send_alert() {
local message="$1"
local log_file="$2"
echo "ALERTA: $message" | \
mail -s "Alerta de Seguridad - $(hostname)" "$ALERT_EMAIL"
logger "SECURITY_ALERT: $message in $log_file"
}
# Monitor en tiempo real
monitor_logs() {
echo "Iniciando monitoreo en tiempo real..."
# Usar tail -F para seguir múltiples archivos
tail -F "${LOG_FILES[@]}" 2>/dev/null | \
while read line; do
# Verificar cada patrón
while read pattern; do
if echo "$line" | grep -q "$pattern"; then
send_alert "Patrón detectado: $pattern" "$(echo $line | cut -d: -f1)"
echo "$(date): ALERTA - $line"
fi
done < "$PATTERNS_FILE"
done
}
# Verificar dependencias
if ! command -v mail > /dev/null; then
echo "Advertencia: comando 'mail' no encontrado. Instalar mailutils"
fi
# Crear directorio para patrones si no existe
mkdir -p "$(dirname "$PATTERNS_FILE")"
# Iniciar monitoreo
monitor_logs
|
Rotación y Compresión Automatizada
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # /etc/logrotate.d/security-logs
/var/log/security-analysis/*.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
copytruncate
postrotate
/usr/bin/systemctl reload rsyslog > /dev/null 2>&1 || true
endscript
}
# Verificar configuración de logrotate
sudo logrotate -d /etc/logrotate.d/security-logs
# Forzar rotación manual
sudo logrotate -f /etc/logrotate.d/security-logs
|
Investigación de Incidentes
Checklist de Investigación Forense
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
| #!/bin/bash
# incident_investigation.sh - Checklist automatizado para investigación
INCIDENT_DATE="$1"
INVESTIGATION_DIR="/var/investigations/$(date +%Y%m%d_%H%M%S)"
if [ -z "$INCIDENT_DATE" ]; then
echo "Uso: $0 YYYY-MM-DD"
exit 1
fi
# Crear directorio de investigación
mkdir -p "$INVESTIGATION_DIR"
cd "$INVESTIGATION_DIR"
echo "=== INVESTIGACIÓN DE INCIDENTE ===" > investigation_report.txt
echo "Fecha del incidente: $INCIDENT_DATE" >> investigation_report.txt
echo "Investigación iniciada: $(date)" >> investigation_report.txt
echo "" >> investigation_report.txt
# 1. Preservar logs del día del incidente
echo "1. Preservando logs del incidente..." | tee -a investigation_report.txt
grep "$INCIDENT_DATE" /var/log/auth.log > auth_incident.log
grep "$INCIDENT_DATE" /var/log/syslog > syslog_incident.log
grep "$INCIDENT_DATE" /var/log/apache2/access.log > web_access_incident.log 2>/dev/null
# 2. Análisis de conexiones activas durante el incidente
echo "2. Analizando conexiones de red..." | tee -a investigation_report.txt
if [ -f "/var/log/netstat_$INCIDENT_DATE.log" ]; then
cp "/var/log/netstat_$INCIDENT_DATE.log" netstat_incident.log
else
echo " - Log de netstat no disponible para $INCIDENT_DATE" >> investigation_report.txt
fi
# 3. Procesos ejecutándose durante el incidente
echo "3. Analizando procesos..." | tee -a investigation_report.txt
grep "$INCIDENT_DATE" /var/log/syslog | grep -E "(started|executed|launched)" > processes_incident.log
# 4. Cambios en archivos del sistema
echo "4. Verificando integridad del sistema..." | tee -a investigation_report.txt
if command -v aide > /dev/null; then
aide --check > aide_check.txt 2>&1
else
echo " - AIDE no instalado. Recomendado para verificación de integridad" >> investigation_report.txt
fi
# 5. Análisis de usuarios y privilegios
echo "5. Analizando actividad de usuarios..." | tee -a investigation_report.txt
grep "$INCIDENT_DATE" /var/log/auth.log | grep -E "(sudo|su|login|session)" > user_activity_incident.log
# 6. Búsqueda de malware básica
echo "6. Búsqueda básica de malware..." | tee -a investigation_report.txt
find /tmp /var/tmp /dev/shm -type f -executable -newer /var/log/auth.log > suspicious_executables.txt 2>/dev/null
# 7. Análisis de red
echo "7. Analizando tráfico de red..." | tee -a investigation_report.txt
if [ -f "/var/log/tcpdump_$INCIDENT_DATE.pcap" ]; then
tcpdump -r "/var/log/tcpdump_$INCIDENT_DATE.pcap" -n > network_analysis.txt 2>&1
else
echo " - Captura de red no disponible para $INCIDENT_DATE" >> investigation_report.txt
fi
# 8. Generar resumen
echo "8. Generando resumen..." | tee -a investigation_report.txt
{
echo ""
echo "=== RESUMEN DE HALLAZGOS ==="
echo "Intentos de login fallidos: $(grep -c "Failed password" auth_incident.log 2>/dev/null || echo "0")"
echo "Logins exitosos: $(grep -c "Accepted" auth_incident.log 2>/dev/null || echo "0")"
echo "Comandos sudo ejecutados: $(grep -c "sudo.*COMMAND" auth_incident.log 2>/dev/null || echo "0")"
echo "Archivos sospechosos encontrados: $(wc -l < suspicious_executables.txt 2>/dev/null || echo "0")"
echo ""
echo "Archivos generados en: $INVESTIGATION_DIR"
echo "- auth_incident.log: Logs de autenticación"
echo "- syslog_incident.log: Logs del sistema"
echo "- user_activity_incident.log: Actividad de usuarios"
echo "- suspicious_executables.txt: Ejecutables sospechosos"
echo "- investigation_report.txt: Este reporte"
} >> investigation_report.txt
echo "Investigación completada. Ver: $INVESTIGATION_DIR/investigation_report.txt"
|
Mejores Prácticas
Configuración de Logging Seguro
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # /etc/rsyslog.conf - Configuración segura
# Enviar logs críticos a servidor remoto
auth,authpriv.* @@log-server.empresa.com:514
*.emerg @@log-server.empresa.com:514
# Separar logs por facilidad
auth,authpriv.* /var/log/auth.log
mail.* /var/log/mail.log
cron.* /var/log/cron.log
kern.* /var/log/kern.log
# Proteger permisos de logs
$FileOwner root
$FileGroup adm
$FileCreateMode 0640
$DirCreateMode 0755
|
Monitoreo Proactivo
1
2
3
4
5
6
7
8
9
10
11
| # Cron jobs para análisis automatizado
# /etc/cron.d/log-analysis
# Análisis de seguridad cada hora
0 * * * * root /usr/local/bin/security_log_analysis.sh > /dev/null 2>&1
# Reporte diario de seguridad
0 6 * * * root /usr/local/bin/daily_security_report.sh
# Limpieza de logs antiguos
0 2 * * 0 root find /var/log -name "*.log" -mtime +30 -exec gzip {} \;
|
Hardening del Sistema de Logs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| # Configurar inmutabilidad de logs críticos (requiere ext2/3/4)
sudo chattr +a /var/log/auth.log # Solo append
sudo chattr +i /var/log/secure.log # Inmutable
# Verificar atributos
lsattr /var/log/auth.log
# Configurar logrotate para preservar evidencia
# /etc/logrotate.d/forensic-logs
/var/log/auth.log {
daily
rotate 365
compress
delaycompress
missingok
notifempty
sharedscripts
postrotate
# Firmar digitalmente logs rotados
gpg --detach-sign /var/log/auth.log.1
endscript
}
|
Conclusión
El análisis de logs y la investigación forense son habilidades cruciales para cualquier administrador de sistemas. Los logs contienen la historia completa de lo que ocurre en un sistema, y saber interpretarlos correctamente puede significar la diferencia entre detectar un ataque a tiempo o sufrir una brecha de seguridad.
Puntos clave para recordar:
- Centralizar logs para análisis correlacionado
- Automatizar análisis con scripts y herramientas
- Preservar evidencia con técnicas forenses apropiadas
- Monitorear proactivamente patrones sospechosos
- Documentar procedimientos de investigación
- Mantener chains of custody para evidencia legal
La práctica constante con estas herramientas y técnicas te convertirá en un investigador forense más efectivo y un administrador de sistemas más seguro.
Andrés Nuñez - t4ifi