Next: Copias de seguridad
Up: Seguridad del sistema Previous: Programas seguros, inseguros y Índice
General
Subsecciones
Casi todas las actividades realizadas en un sistema Unix son susceptibles de ser,
en mayor o menor medida, monitorizadas: desde las horas de acceso de cada usuario
al sistema hasta las páginas web más frecuentemente visitadas,
pasando por los intentos fallidos de conexión, los programas ejecutados
o incluso el tiempo de CPU que cada usuario consume. Obviamente esta facilidad
de Unix para recoger información tiene unas ventajas inmediatas para la
seguridad: es posible detectar un intento de ataque nada más producirse
el mismo, así como también detectar usos indebidos de los recursos
o actividades 'sospechosas'; sin embargo, existen también desventajas,
ya que la gran cantidad de información que potencialmente se registra puede
ser aprovechada para crear negaciones de servicio o, más habitualmente,
esa cantidad de información puede hacer difícil detectar problemas
por el volumen de datos a analizar.
Algo muy interesante de los archivos de log en Unix es que la mayoría
de ellos son simples ficheros de texto, que se pueden visualizar con un simple
cat. Por una parte esto es bastante cómodo para el administrador
del sistema, ya que no necesita de herramientas especiales para poder revisar
los logs (aunque existen algunas utilidades para hacerlo, como swatch)
e incluso puede programar shellscripts para comprobar los informes generados
de forma automática, con órdenes como awk, grep
o sed. No obstante, el hecho de que estos ficheros sean texto plano
hace que un atacante lo tenga muy fácil para ocultar ciertos registros
modificando los archivos con cualquier editor de textos; esto implica una cosa
muy importante para un administrador: nunca ha de confiar al 100% en lo
que los informes de auditoría del sistema le digan. Para minimizar estos
riesgos se pueden tomar diversas medidas, desde algunas quizás demasiado
complejas para entornos habituales ([SK98])
hasta otras más sencillas pero igualmente efectivas, como utilizar una
máquina fiable para registrar información del sistema o incluso
enviar los registros más importantes a una impresora; más adelante
hablaremos de ellas.
Una desventaja añadida al sistema de auditoría en Unix puede ser
la complejidad que puede alcanzar una correcta configuración; por si la
dificultad del sistema no fuera suficiente, en cada Unix el sistema de logs
tiene peculiaridades que pueden propiciar la pérdida de información
interesante de cara al mantenimiento de sistemas seguros. Aunque muchos de los
ficheros de log de los que hablaremos a continuación son comunes
en cualquier sistema, su localización, o incluso su formato, pueden variar
entre diferentes Unices.
Dentro de Unix hay dos grandes familias de sistemas: se trata de System V
y BSD; la localización de ficheros y ciertas órdenes
relativas a la auditoría de la máquina van a ser diferentes en ellas,
por lo que es muy recomendable consultar las páginas del manual antes de
ponerse a configurar el sistema de auditoría en un equipo concreto. La
principal diferencia entre ellos es el denominado process accounting o
simplemente accounting, consistente en registrar todos los programas ejecutados
por cada usuario; evidentemente, los informes generados en este proceso pueden
llegar a ocupar muchísimo espacio en disco (dependiendo del número
de usuarios en nuestro sistema) por lo que sólo es recomendable en situaciones
muy concretas, por ejemplo para detectar actividades sospechosas en una máquina
o para cobrar por el tiempo de CPU consumido. En los sistemas System V
el process accounting está desactivado por defecto; se puede iniciar
mediante /usr/lib/acct/startup, y para visualizar los informes se utiliza
la orden acctcom. En la familia BSD los equivalentes
a estas órdenes son accton y lastcomm; en este caso
el process accounting está inicializado por defecto.
Un mundo aparte a la hora de generar (y analizar) informes acerca de las actividades
realizadas sobre una máquina Unix son los sistemas con el modelo de auditoría
C2 ([B$^$85]); mientras que con el modelo clásico se
genera un registro tras la ejecución de cada proceso, en Unix C2 se proporciona
una pista de auditoría donde se registran los accesos y los intentos de
acceso de una entidad a un objeto, así como cada cambio en el estado del
objeto, la entidad o el sistema global. Esto se consigue asignando un identificador
denominado Audit ID a cada grupo de procesos ejecutados (desde el propio
login), identificador que se registra junto a la mayoría de llamadas
al sistema que un proceso realiza, incluyendo algunas tan comunes como write(),
open(), close() o read(). A nadie se le puede escapar
la cantidad de espacio y de CPU necesarios para mantener los registros a un nivel
tan preciso, por lo que en la mayoría de sistemas (especialmente en entornos
habituales, como los estudiados aquí) el modelo de auditoría C2
es innecesario; y no sólo esto, sino que en muchas ocasiones también
se convierte en una monitorización inútil ([ALGJ98])
si no se dispone de mecanismos para interpretar o reducir la gran cantidad de
datos registrados: el administrador guarda tanta información que es casi
imposible analizarla en busca de actividades sospechosas.
El demonio syslogd ( Syslog Daemon) se lanza automáticamente
al arrancar un sistema Unix, y es el encargado de guardar informes sobre el funcionamiento
de la máquina. Recibe mensajes de las diferentes partes del sistema (núcleo,
programas...) y los envía y/o almacena en diferentes localizaciones, tanto
locales como remotas, siguiendo un criterio definido en el fichero de configuración
/etc/syslog.conf, donde especificamos las reglas a seguir para gestionar
el almacenamiento de mensajes del sistema. Las líneas de este archivo que
comienzan por '#' son comentarios, con lo cual son ignoradas de la misma
forma que las líneas en blanco; si ocurriera un error al interpretar una
de las líneas del fichero, se ignoraría la línea completa.
Un ejemplo de fichero /etc/syslog.conf es el siguiente:
anita:~# cat /etc/syslog.conf
#ident "@(#)syslog.conf 1.4 96/10/11 SMI" /* SunOS 5.0 */
#
# Copyright (c) 1991-1993, by Sun Microsystems, Inc.
#
# syslog configuration file.
#
# This file is processed by m4 so be careful to quote ('') names
# that match m4 reserved words. Also, within ifdef's, arguments
# containing commas must be quoted.
#
*.err;kern.notice;auth.notice /dev/console
*.err;kern.debug;daemon.notice;mail.crit /var/adm/messages
*.alert;kern.err;daemon.err operator
*.alert root
*.emerg *
# if a non-loghost machine chooses to have authentication messages
# sent to the loghost machine, un-comment out the following line:
#auth.notice ifdef('LOGHOST', /var/log/authlog, @loghost)
mail.debug ifdef('LOGHOST', /var/log/syslog, @loghost)
#
# non-loghost machines will use the following lines to cause "user"
# log messages to be logged locally.
#
ifdef('LOGHOST', ,
user.err /dev/console
user.err /var/adm/messages
user.alert 'root, operator'
user.emerg *
)
anita:~#
Podemos ver que cada regla del archivo tiene dos campos: un campo de selección
y un campo de acción, separados por espacios o tabuladores. El campo
de selección está formado a su vez de dos partes: una del servicio
que envía el mensaje y otra de su prioridad, separadas por un punto ('.');
ambas son indiferentes a mayúsculas y minúsculas. La parte del servicio
contiene una de las siguientes palabras clave: auth, auth-priv,
cron, daemon, kern, lpr, mail,
mark, news, security (equivalente a auth),
syslog, user, uucp y local0 hasta local7.
Esta parte especifica el 'subsistema' que ha generado ese mensaje (por ejemplo,
todos los programas relacionados con el correo generarán mensajes ligados
al servicio mail).
La prioridad está compuesta de uno de los siguientes términos, en
orden ascendente: debug, info, notice, warning,
warn (equivalente a warning), err, error
(equivalente a err), crit, alert, emerg,
y panic (equivalente a emerg). La prioridad define la gravedad
o importancia del mensaje almacenado. Todos los mensajes de la prioridad especificada
y superiores son almacenados de acuerdo con la acción requerida.
Además de los términos mencionados hasta ahora, el demonio
syslogd emplea los siguientes caracteres especiales:
- '
' (asterisco)
Empleado como comodín para todas las prioridades y servicios anteriores,
dependiendo de dónde son usados (si antes o después del carácter
de separación '.'):
# Guardar todos los mensajes del servicio mail en /var/adm/mail
#
mail.* /var/adm/mail
- ' ' (blanco, espacio, nulo)
Indica que no hay prioridad definida para el servicio de la línea almacenada.
- ',' (coma)
Con este carácter es posible especificar múltiples servicios
con el mismo patrón de prioridad en una misma línea. Es posible
enumerar cuantos servicios se quieran:
# Guardar todos los mensajes mail.info y news.info en
# /var/adm/info
mail,news.=info /var/adm/info
- ';' (punto y coma)
Es posible dirigir los mensajes de varios servicios y prioridades a un mismo
destino, separándolos por este carácter:
# Guardamos los mensajes de prioridad "info" y "notice"
# en el archivo /var/log/messages
*.=info;*.=notice /var/log/messages
- '=' (igual)
De este modo solo se almacenan los mensajes con la prioridad exacta especificada
y no incluyendo las superiores:
# Guardar todos los mensajes criticos en /var/adm/critical
#
*.=crit /var/adm/critical
- '!' (exclamación)
Preceder el campo de prioridad con un signo de exclamación sirve para
ignorar todas las prioridades, teniendo la posibilidad de escoger entre la
especificada (!=prioridad) y la especificada más todas las
superiores ( !prioridad). Cuando se usan conjuntamente los caracteres
'=' y '!', el signo de exclamación '!'
debe preceder obligatoriamente al signo igual '=', de esta forma:
!=.
# Guardar mensajes del kernel de prioridad info, pero no de
# prioridad err y superiores
# Guardar mensajes de mail excepto los de prioridad info
kern.info;kern.!err /var/adm/kernel-info
mail.*;mail.!=info /var/adm/mail
Por su parte, el campo de acción describe el destino de los mensajes,
que puede ser :
- Un fichero plano
Normalmente los mensajes del sistema son almacenados en ficheros planos. Dichos
ficheros han de estar especificados con la ruta de acceso completa (comenzando
con '/').
Podemos preceder cada entrada con el signo menos, '-', para omitir
la sincronización del archivo (vaciado del buffer de memoria
a disco). Aunque puede ocurrir que se pierda información si el sistema
cae justo después de un intento de escritura en el archivo, utilizando
este signo se puede conseguir una mejora importante en la velocidad, especialmente
si estamos ejecutando programas que mandan muchos mensajes al demonio
syslogd.
# Guardamos todos los mensajes de prioridad critica en "critical"
#
*.=crit /var/adm/critical
- Un terminal (o la consola)
También tenemos la posibilidad de enviar los mensajes a terminales;
de este modo podemos tener uno de los terminales virtuales que muchos sistemas
Unix ofrecen en su consola 'dedicado' a listar los mensajes del sistema, que
podrán ser consultados con solo cambiar a ese terminal:
# Enviamos todos los mensajes a tty12 (ALT+F12 en Linux) y todos
# los mensajes criticos del nucleo a consola
#
*.* /dev/tty12
kern.crit /dev/console
- Una tubería con nombre
Algunas versiones de syslogd permiten enviar registros a ficheros
de tipo pipe simplemente anteponiendo el símbolo '
' al nombre del archivo; dicho fichero
ha de ser creado antes de iniciar el demonio syslogd, mediante órdenes
como mkfifo o mknod. Esto es útil para debug
y también para procesar los registros utilizando cualquier aplicación
de Unix, tal y como veremos al hablar de logs remotos cifrados.
Por ejemplo, la siguiente línea de /etc/syslog.conf enviaría
todos los mensajes de cualquier prioridad a uno de estos ficheros denominado
/var/log/mififo:
# Enviamos todos los mensajes a la tuberia con nombre
# /var/log/mififo
#
*.* |/var/log/mififo
- Una máquina remota
Se pueden enviar los mensajes del sistema a otra máquina, de manera
a que sean almacenados remotamente. Esto es útil si tenemos una máquina
segura, en la que podemos confiar, conectada a la red, ya que de esta manera
se guardaría allí una copia de los mensajes de nuestro sistema
y no podrían ser modificados en caso de que alguien entrase en nuestra
máquina. Esto es especialmente útil para detectar usuarios 'ocultos'
en nuestro sistema (usuarios maliciosos que han conseguido los suficientes
privilegios para ocultar sus procesos o su conexión):
# Enviamos los mensajes de prioridad warning y superiores al
# fichero "syslog" y todos los mensajes (incluidos los
# anteriores) a la maquina "secure.upv.es"
#
*.warn /usr/adm/syslog
*.* @secure.upv.es
- Unos usuarios del sistema (si están conectados)
Se especifica la lista de usuarios que deben recibir un tipo de mensajes simplemente
escribiendo su login, separados por comas:
# Enviamos los mensajes con la prioridad "alert" a root y toni
#
*.alert root, toni
- Todos los usuarios que estén conectados
Los errores con una prioridad de emergencia se suelen enviar a todos los usuarios
que estén conectados al sistema, de manera que se den cuenta de que
algo va mal:
# Mostramos los mensajes urgentes a todos los usuarios
# conectados, mediante wall
*.=emerg *
En función de la configuración del sistema de auditoría de
cada equipo Unix los eventos que sucedan en la máquina se registrarán
en determinados ficheros; aunque podemos loggear en cualquier fichero
(incluso a través de la red o en dispositivos, como veremos luego), existen
ciertos archivos de registro 'habituales' en los que se almacena información.
A continuación comentamos los más comunes y la información
que almacenan.
El archivo syslog (guardado en /var/adm/ o /var/log/)
es quizás el fichero de log más importante del sistema;
en él se guardan, en texto claro, mensajes relativos a la seguridad de
la máquina, como los accesos o los intentos de acceso a ciertos servicios.
No obstante, este fichero es escrito por syslogd, por lo que dependiendo
de nuestro fichero de configuración encontraremos en el archivo una u otra
información. Al estar guardado en formato texto, podemos visualizar su
contenido con un simple cat:
anita:/# cat /var/log/syslog
Mar 5 04:15:23 anita in.telnetd[11632]: connect from localhost
Mar 5 06:16:52 anita rpcbind: connect from 127.0.0.1 to getport(R )
Mar 5 06:16:53 anita last message repeated 3 times
Mar 5 06:35:08 anita rpcbind: connect from 127.0.0.1 to getport(R )
Mar 5 18:26:56 anita rpcbind: connect from 127.0.0.1 to getport(R )
Mar 5 18:28:47 anita last message repeated 1 time
Mar 5 18:32:43 anita rpcbind: connect from 127.0.0.1 to getport(R )
Mar 6 02:30:26 anita rpcbind: connect from 127.0.0.1 to getport(R )
Mar 6 03:31:37 anita rpcbind: connect from 127.0.0.1 to getport(R )
Mar 6 11:07:04 anita in.telnetd[14847]: connect from rosita
Mar 6 11:40:43 anita in.telnetd[14964]: connect from localhost
anita:/#
En este archivo de texto se almacenan datos 'informativos' de ciertos programas,
mensajes de baja o media prioridad destinados más a informar que a avisar
de sucesos importantes, como información relativa al arranque de la máquina;
no obstante, como sucedía con el fichero syslog, en función
de /etc/syslog.conf podremos guardar todo tipo de datos. Para visualizar
su contenido es suficiente una orden como cat o similares:
anita:/# head -70 /var/adm/messages
Jan 24 18:09:54 anita unix: SunOS Release 5.7 Version Generic
[UNIX(R) System V Release 4.0]
Jan 24 18:09:54 anita unix: Copyright (c) 1983-1998, Sun Microsystems, Inc.
Jan 24 18:09:54 anita unix: mem = 65152K (0x3fa0000)
Jan 24 18:09:54 anita unix: avail mem = 51167232
Jan 24 18:09:54 anita unix: root nexus = i86pc
Jan 24 18:09:54 anita unix: isa0 at root
Jan 24 18:09:54 anita unix: pci0 at root: space 0 offset 0
Jan 24 18:09:54 anita unix: IDE device at targ 0, lun 0 lastlun 0x0
Jan 24 18:09:54 anita unix: model WDC WD84AA, stat 50, err 0
Jan 24 18:09:54 anita unix: cfg 0x427a, cyl 16383, hd 16, sec/trk 63
Jan 24 18:09:54 anita unix: mult1 0x8010, mult2 0x110, dwcap 0x0,
cap 0x2f00
Jan 24 18:09:54 anita unix: piomode 0x280, dmamode 0x0, advpiomode
0x3
Jan 24 18:09:54 anita unix: minpio 120, minpioflow 120
Jan 24 18:09:54 anita unix: valid 0x7, dwdma 0x7, majver 0x1e
Jan 24 18:09:54 anita unix: ata_set_feature: (0x66,0x0) failed
Jan 24 18:09:54 anita unix: ATAPI device at targ 1, lun 0 lastlun 0x0
Jan 24 18:09:54 anita unix: model CD-ROM 50X, stat 50, err 0
Jan 24 18:09:54 anita unix: cfg 0x85a0, cyl 0, hd 0, sec/trk 0
Jan 24 18:09:54 anita unix: mult1 0x0, mult2 0x0, dwcap 0x0, cap 0xf00
Jan 24 18:09:54 anita unix: piomode 0x400, dmamode 0x200, advpiomode
0x3
Jan 24 18:09:54 anita unix: minpio 227, minpioflow 120
Jan 24 18:09:54 anita unix: valid 0x6, dwdma 0x107, majver 0x0
Jan 24 18:09:54 anita unix: PCI-device: ata@0, ata0
Jan 24 18:09:54 anita unix: ata0 is /pci@0,0/pci-ide@7,1/ata@0
Jan 24 18:09:54 anita unix: Disk0: <Vendor 'Gen-ATA ' Product 'WDC WD84AA '>
Jan 24 18:09:54 anita unix: cmdk0 at ata0 target 0 lun 0
Jan 24 18:09:54 anita unix: cmdk0 is /pci@0,0/pci-ide@7,1/ata@0/cmdk@0,0
Jan 24 18:09:54 anita unix: root on /pci@0,0/pci-ide@7,1/ide@0/cmdk@0,0:a
fstype ufs
Jan 24 18:09:54 anita unix: ISA-device: asy0
Jan 24 18:09:54 anita unix: asy0 is /isa/asy@1,3f8
Jan 24 18:09:54 anita unix: ISA-device: asy1
Jan 24 18:09:54 anita unix: asy1 is /isa/asy@1,2f8
Jan 24 18:09:54 anita unix: ISA-device: asy2
Jan 24 18:09:54 anita unix: asy2 is /isa/pnpSUP,1670@pnpSUP,1670,7ec2
Jan 24 18:09:54 anita unix: Number of console virtual screens = 13
Jan 24 18:09:54 anita unix: cpu 0 initialization complete - online
Jan 24 18:09:54 anita unix: dump on /dev/dsk/c0d0s1 size 86 MB
Jan 24 18:09:55 anita unix: pseudo-device: pm0
Jan 24 18:09:55 anita unix: pm0 is /pseudo/pm@0
Jan 24 18:09:56 anita unix: pseudo-device: vol0
Jan 24 18:09:56 anita unix: vol0 is /pseudo/vol@0
Jan 24 18:09:57 anita icmpinfo: started, PID=213.
Jan 24 18:09:57 anita unix: sd1 at ata0:
Jan 24 18:09:57 anita unix: target 1 lun 0
Jan 24 18:09:57 anita unix: sd1 is /pci@0,0/pci-ide@7,1/ata@0/sd@1,0
Jan 24 18:10:03 anita icmpinfo: ICMP_Dest_Unreachable[Port] < 127.0.0.1
[localhost] > 127.0.0.1 [localhost] sp=1664 dp=3200 seq=0x002e0000 sz=74(+20)
Jan 24 18:10:03 anita unix: ISA-device: fdc0
Jan 24 18:10:03 anita unix: fd0 at fdc0
Jan 24 18:10:03 anita unix: fd0 is /isa/fdc@1,3f0/fd@0,0
Jan 24 18:10:04 anita icmpinfo: ICMP_Dest_Unreachable[Port] < 127.0.0.1
[localhost] > 127.0.0.1 [localhost] sp=2944 dp=161 seq=0x00420000 sz=92(+20)
Jan 24 18:10:05 anita unix: ISA-device: asy0
Jan 24 18:10:05 anita unix: asy0 is /isa/asy@1,3f8
Jan 24 18:10:05 anita unix: ISA-device: asy1
Jan 24 18:10:05 anita unix: asy1 is /isa/asy@1,2f8
Jan 24 18:10:05 anita unix: ISA-device: asy2
Jan 24 18:10:05 anita unix: asy2 is /isa/pnpSUP,1670@pnpSUP,1670,7ec2
an 24 18:10:08 anita icmpinfo: ICMP_Dest_Unreachable[Port] < 127.0.0.1
[localhost] > 127.0.0.1 [localhost] sp=32780 dp=162 seq=0x00370000 sz=83(+20)
Jan 24 18:10:35 anita unix: pseudo-device: xsvc0
Jan 24 18:10:35 anita unix: xsvc0 is /pseudo/xsvc@0
anita:/#
Este archivo es un fichero binario (no se puede leer su contenido directamente
volcándolo con cat o similares) que almacena información
relativa a cada conexión y desconexión al sistema. Podemos ver su
contenido con órdenes como last:
anita:/# last -10
toni pts/11 localhost Mon Mar 6 11:07 - 11:07 (00:00)
toni pts/11 rosita Sun Mar 5 04:22 - 04:25 (00:03)
ftp ftp andercheran.aiin Sun Mar 5 02:30 still logged in
ftp ftp andercheran.aiin Sun Mar 5 00:28 - 02:30 (02:01)
ftp ftp anita Thu Mar 2 03:02 - 00:28 (2+21:25)
ftp ftp anita Thu Mar 2 03:01 - 03:02 (00:00)
ftp ftp localhost Thu Mar 2 02:35 - 03:01 (00:26)
root console Thu Mar 2 00:13 still logged in
reboot system boot Thu Mar 2 00:12
root console Wed Mar 1 06:18 - down (17:54)
anita:/#
Los registros guardados en este archivo (y también en utmp) tienen
el formato de la estructura utmp, que contiene información como
el nombre de usuario, la línea por la que accede, el lugar desde donde
lo hace y la hora de acceso; se puede consultar la página de manual de
funciones como getutent() para ver la estructura concreta en el clon
de Unix en el que trabajemos. Algunas variantes de Unix (como Solaris o IRIX)
utilizan un fichero wtmp extendido denominado wtmpx, con campos
adicionales que proporcionan más información sobre cada conexión.
El archivo utmp es un fichero binario con información de cada
usuario que está conectado en un momento dado; el programa /bin/login
genera un registro en este fichero cuando un usuario conecta, mientras que
init lo elimina cuando desconecta. Aunque habitualmente este archivo está
situado en /var/adm/, junto a otros ficheros de log, es posible
encontrar algunos Unices - los más antiguos - que lo situan en /etc/.
Para visualizar el contenido de este archivo podemos utilizar órdenes como
last (indicando el nombre de fichero mediante la opción
-f), w o who:
anita:/# who
root console Mar 2 00:13
root pts/2 Mar 3 00:47 (unix)
root pts/3 Mar 2 00:18 (unix)
root pts/5 Mar 2 00:56 (unix)
root pts/6 Mar 2 02:23 (unix:0.0)
root pts/8 Mar 3 00:02 (unix:0.0)
root pts/7 Mar 2 23:43 (unix:0.0)
root pts/9 Mar 3 00:51 (unix)
root pts/10 Mar 6 00:23 (unix)
anita:/#
Como sucedía con wtmp, algunos Unices utilizan también
una versión extendida de utmp ( utmpx) con campos adicionales.
El archivo lastlog es un fichero binario guardado generalmente en
/var/adm/, y que contiene un registro para cada usuario con la fecha y hora
de su última conexión; podemos visualizar estos datos para un usuario
dado mediante la orden finger:
anita:/# finger toni
Login name: toni In real life: Toni at ANITA
Directory: /export/home/toni Shell: /bin/sh
Last login Mon Mar 6 11:07 on pts/11 from localhost
No unread mail
No Plan.
anita:/#
Este fichero es equivalente al anterior, pero en lugar de guardar información
sobre la fecha y hora del último acceso al sistema lo hace del último
intento de acceso de cada usuario; una conexión es fallida si el usuario
(o alguien en su lugar) teclea incorrectamente su contraseña. Esta información
se muestra la siguiente vez que dicho usuario entra correctamente a la máquina:
andercheran login: toni
Password:
Linux 2.0.33.
1 failure since last login. Last was 14:39:41 on ttyp9.
Last login: Wed May 13 14:37:46 on ttyp9 from pleione.cc.upv.es.
andercheran:~$
Si en algunas versiones de Unix (como Solaris) creamos el archivo /var/adm/loginlog
(que originalmente no existe), se registrarán en él los intentos
fallidos de login, siempre y cuando se produzcan cinco o más de
ellos seguidos:
anita:/# cat /var/adm/loginlog
toni:/dev/pts/6:Thu Jan 6 07:02:53 2000
toni:/dev/pts/6:Thu Jan 6 07:03:00 2000
toni:/dev/pts/6:Thu Jan 6 07:03:08 2000
toni:/dev/pts/6:Thu Jan 6 07:03:37 2000
toni:/dev/pts/6:Thu Jan 6 07:03:44 2000
anita:/#
En algunos clones de Unix, como Linux o HP-UX, el fichero btmp se utiliza
para registrar las conexiones fallidas al sistema, con un formato similar al que
wtmp utiliza para las conexiones que han tenido éxito:
andercheran:~# last -f /var/adm/btmp |head -7
pnvarro ttyq1 term104.aiind.up Wed Feb 9 16:27 - 15:38 (23:11)
jomonra ttyq2 deportes.etsii.u Fri Feb 4 14:27 - 09:37 (9+19:09)
PNAVARRO ttyq4 term69.aiind.upv Wed Feb 2 12:56 - 13:09 (20+00:12)
panavarr ttyq2 term180.aiind.up Fri Jan 28 12:45 - 14:27 (7+01:42)
vbarbera ttyp0 daind03.etsii.up Thu Jan 27 20:17 still logged in
pangel ttyq1 agarcia2.ter.upv Thu Jan 27 18:51 - 16:27 (12+21:36)
abarra ttyp0 dtra-51.ter.upv. Thu Jan 27 18:42 - 20:17 (01:34)
andercheran:~#
Este es un fichero de texto donde se registran las ejecuciones de la orden
su, indicando fecha, hora, usuario que lanza el programa y usuario cuya identidad
adopta, terminal asociada y éxito ('+') o fracaso ('-')
de la operación:
anita:/# head -4 /var/adm/sulog
SU 12/27 07:41 + console root-toni
SU 12/28 23:42 - vt01 toni-root
SU 12/28 23:43 + vt01 toni-root
SU 12/29 01:09 + vt04 toni-root
anita:/#
En este archivo de texto se registra información de depuración (de
debug) de los programas que se ejecutan en la máquina; esta información
puede ser enviada por las propias aplicaciones o por el núcleo del sistema
operativo:
luisa:~# tail -8 /var/adm/debug
Dec 17 18:51:50 luisa kernel: ISO9660 Extensions: RRIP_1991A
Dec 18 08:15:32 luisa sshd[3951]: debug: sshd version 1.2.21
[i486-unknown-linux]
Dec 18 08:15:32 luisa sshd[3951]: debug: Initializing random number
generator; seed file /etc/ssh_random_seed
Dec 18 08:15:32 luisa sshd[3951]: debug: inetd sockets after dupping: 7, 8
Dec 18 08:15:34 luisa sshd[3951]: debug: Client protocol version 1.5; client
software version 1.2.21
Dec 18 08:15:34 luisa sshd[3951]: debug: Calling cleanup 0x800cf90(0x0)
Dec 18 16:33:59 luisa kernel: VFS: Disk change detected on device 02:00
Dec 18 23:41:12 luisa identd[2268]: Successful lookup: 1593 , 22 : toni.users
luisa:~#
El demonio syslog permite fácilmente guardar registros en máquinas
remotas; de esta forma se pretende que, aunque la seguridad de un sistema se vea
comprometida y sus logs sean modificados se puedan seguir registrando
las actividades sospechosas en una máquina a priori segura. Esto
se consigue definiendo un 'LOGHOST' en lugar de un archivo normal en
el fichero /etc/syslogd.conf de la máquina de la que nos interesa
guardar información; por ejemplo, si queremos registrar toda la información
de prioridad info y notice en la máquina remota
rosita, lo indicaremos de la siguiente forma:
*.=info;*.=notice @rosita
Tras modificar /etc/syslogd.conf hacemos que el demonio relea su fichero
de configuración enviándole la señal SIGHUP
(por ejemplo, con kill).
Por su parte, en el host donde deseemos almacenar los logs, tenemos
que tener definido el puerto syslog en /etc/services y ejecutar
syslogd con el parámetro '-r' para que acepte conexiones
a través de la red:
rosita:~# grep syslog /etc/services
syslog 514/udp
rosita:~# ps xua|grep syslogd
root 41 0.0 0.4 852 304 ? S Mar21 0:01 /usr/sbin/syslogd
rosita:~# kill -TERM 41
rosita:~# syslogd -r
rosita:~#
A partir de ese momento todos los mensajes generados en la máquina origen
se enviarán a la destino y se registrarán según las reglas
de esta, en un fichero (lo habitual), en un dispositivo...o incluso se reenviarán
a otra máquina (en este caso hemos de tener cuidado con los bucles); si
suponemos que estas reglas, en nuestro caso, registran los mensajes de la prioridad
especificada antes en /var/adm/messages, en este archivo aparecerán
entradas de la máquina que ha enviado la información:
rosita:~# tail -3 /var/adm/messages
Mar 23 07:43:37 luisa syslogd 1.3-3: restart.
Mar 23 07:43:46 luisa in.telnetd[7509]: connect from amparo
Mar 23 07:57:44 luisa -- MARK --
rosita:~#
Esto, que en muchas situaciones es muy recomendable, si no se realiza correctamente
puede incluso comprometer la seguridad de la máquina que guarda registros
en otro equipo: por defecto, el tráfico se realiza en texto claro, por
lo que cualquier atacante con un sniffer entre las dos máquinas
puede tener acceso a información importante que habría que mantener
en secreto; imaginemos una situación muy habitual: un usuario que teclea
su password cuando el sistema le pide el login. Evidentemente,
esto generará un mensaje de error que syslogd registrará;
este mensaje será similar a este (Linux Slackware 4):
Mar 23 05:56:56 luisa login[6997]: invalid password for 'UNKNOWN'\
on 'ttyp5' from 'amparo'
Pero, ¿qué sucedería si en lugar de 'UNKNOWN' el
sistema almacenara el nombre de usuario que se ha introducido, algo que hacen
muchos clones de Unix? En esta situación el mensaje sería muy parecido
al siguiente (Linux Red Hat 6.1):
Mar 23 05:59:15 rosita login[3582]: FAILED LOGIN 1 FROM amparo FOR\
5k4@b&-, User not known to the underlying authentication module
Como podemos ver se registraría una contraseña de usuario, contraseña
que estamos enviando a la máquina remota en texto claro a través
de la red; evidentemente, es un riesgo que no podemos correr. Quizás alguien
pueda pensar que una clave por sí sola no representa mucho peligro, ya
que el atacante no conoce el nombre de usuario en el sistema. De ninguna forma:
el pirata sólo tiene que esperar unos instantes, porque cuando el usuario
teclee su login y su password correctamente (en principio, esto
sucederá poco después de equivocarse, recordemos que el usuario
trata de acceder a su cuenta) el sistema generará un mensaje indicando
que ese usuario (con su nombre) ha entrado al sistema.
Para evitar este problema existen dos aproximaciones: o bien registramos logs
en un equipo directamente conectado al nuestro, sin emitir tráfico al resto
de la red, o bien utilizamos comunicaciones cifradas (por ejemplo con
SSH) para enviar los registros a otro ordenador. En el primer caso sólo
necesitamos un equipo con dos tarjetas de red, una por donde enviar el tráfico
hacia la red local y la otra para conectar con la máquina donde almacenamos
los logs, que sólo será accesible desde nuestro equipo y
que no ha de tener usuarios ni ofrecer servicios; no es necesaria una gran potencia
de cálculo: podemos aprovechar un viejo 386 o 486 con Linux o FreeBSD para
esta tarea.
El segundo caso, utilizar comunicaciones cifradas para guardar registros en otro
equipo de la red, requiere algo más de trabajo; aquí no es estrictamente
necesario que la máquina esté aislada del resto de la red, ya que
la transferencia de información se va a realizar de forma cifrada, consiguiendo
que un potencial atacante no obtenga ningún dato comprometedor analizando
el tráfico; evidentemente, aunque no esté aislado, es fundamental
que el sistema donde almacenamos los logs sea seguro. Para enviar un
log cifrado a una máquina remota podemos utilizar, como hemos dicho
antes, SSH unido a las facilidades que ofrece syslogd;
si lo hacemos así, lo único que necesitamos es el servidor
sshd en la máquina destino y el cliente ssh en la origen.
Por ejemplo, imaginemos que queremos utilizar a rosita para almacenar
una copia de los registros generados en luisa conforme se vayan produciendo;
en este caso vamos a enviar logs a un fifo con nombre, desde donde
los cifraremos con SSH y los enviaremos al sistema remoto a través
de la red. Lo primero que necesitamos hacer es crear un fichero de tipo tubería
en la máquina origen, por ejemplo con mknod o mkfifo:
luisa:~# mknod /var/run/cifra p
luisa:~# chmod 0 /var/run/cifra
luisa:~# ls -l /var/run/cifra
p--------- 1 root root 0 May 4 05:18 /var/run/cifra|
luisa:~#
Este es el archivo al que enviaremos desde syslogd los registros que
nos interesen, por ejemplo los de prioridad warn; hemos de modificar
/etc/syslog.conf para añadirle una línea como la siguiente:
luisa:~# tail -1 /etc/syslog.conf
*.warn |/var/run/cifra
luisa:~#
A continuación haremos que syslog relea su nueva configuración
mediante la señal SIGHUP:
luisa:~# ps xua|grep syslog |grep -v grep
root 7978 0.0 0.2 1372 156 ? S 03:01 0:00 syslogd -m 0
luisa:~# kill -HUP 7978
luisa:~#
Una vez realizados estos pasos ya conseguimos que se registren los eventos que
nos interesan en el fichero /var/run/cifra; este archivo es una tubería
con nombre, de forma que los datos que le enviamos no se graban en el disco realmente,
sino que sólo esperan a que un proceso lector los recoja. Ese proceso lector
será justamente el cliente ssh, encargado de cifrarlos y enviarlos
al sistema remoto; para ello debemos lanzar una orden como:
luisa:~# cat /var/run/cifra | ssh -x rosita 'cat >>/var/log/luisa'
Si tenemos configurado SSH para que autentique sin clave podemos
lanzar el proceso directamente en background; si tenemos que introducir
la clave del root, una vez tecleada podemos parar el proceso y relanzarlo
también en segundo plano (esto es simplemente por comodidad, realmente
no es necesario). Lo único que estamos haciendo con este mecanismo es cifrar
lo que llega al fifo y enviarlo de esta forma al sistema remoto, en el
que se descifrará y se guardará en el fichero /var/log/luisa.
Quizás nos interese añadir unas líneas en los scripts
de arranque de nuestra máquina para que este proceso se lance automáticamente
al iniciar el sistema; si lo hacemos así hemos de tener cuidado con la
autenticación, ya que si ssh requiere una clave para conectar
con el sistema remoto es probable que la máquina tarde más de lo
normal en arrancar si un operador no está en la consola: justamente el
tiempo necesario hasta que ssh produzca un timeout por no teclear
el password de root en el sistema remoto. Si al producirse el
timeout el programa ssh no devuelve el control al shell,
el sistema ni siquiera arrancará; de cualquier forma, si ese timeout
se produce no estaremos registrando ningún evento en la otra máquina.
Por supuesto, también debemos prestar atención a otros problemas
con la máquina destino que eviten que la conexión se produzca, con
un número máximo de usuarios sobrepasado o simplemente que ese sistema
esté apagado.
Para asegurarnos más de que la información que se registra de las
actividades en nuestro sistema es fiable acabamos de explicar cómo almacenarla,
a la vez que en un fichero de la propia máquina, en un equipo remoto a
través de la red; la idea es poder comparar los registros de ambos sistemas
para detectar posibles modificaciones en una de ellas. Pero, ¿qué
sucede si el atacante consigue también control sobre el segundo equipo,
y modifica también ahí los ficheros de log? Aunque a
priori este sea un sistema seguro, sabemos que nadie nos puede garantizar
la seguridad al 100%; en algunos casos (por ejemplo si sospechamos que el intruso
ha conseguido el control de ambos equipos) es conveniente recurrir a registros
físicos, mucho más difíciles de alterar que los lógicos.
No siempre se guarda información en un fichero plano, ya sea local o remoto.
Unix permite almacenar mensajes en ficheros especiales - dispositivos -, como
terminales o impresoras; son estas últimas las más habituales por
la seguridad que ofrecen, ya que mientras que un intruso con el privilegio suficiente
puede modificar un fichero de log local, o acceder a un sistema donde
se almacenen registros remotos, no puede eliminar una información extraída
por impresora sin tener acceso físico a la misma. El demonio syslog
de cualquier sistema Unix permite especificar uno de estos ficheros especiales
como destinatario de ciertos registros de una forma muy simple: no tenemos más
que añadir una entrada en /etc/syslog.conf indicando el dispositivo
y la clase de eventos a registrar en él; por ejemplo, para enviar todos
los mensajes de prioridad warn a una impresora (como /dev/lp1)
no tenemos más que añadir en el archivo la línea siguiente:
*.warn /dev/lp1
Como siempre, tras modificar el fichero de configuración hemos de hacer
que el demonio lo relea, bien enviándole la señal SIGHUP
o bien deteniéndolo y volviéndolo a lanzar; por último, si
decidimos utilizar una impresora para generar registros físicos hemos de
intentar que se trate de un modelo de agujas, ya que dispositivos más modernos
utilizan buffers que no se llegan a imprimir hasta que están llenos,
por lo que sería posible para un atacante hacer que se pierda cierta información.
Hemos de evitar especialmente algunos modelos nuevos de impresoras que tienen
incluso sistema de red y dirección IP para control remoto,
ya que en este caso puede suceder que un pirata llegue a controlar el dispositivo
igual que controla la máquina que envía los registros.
Otro tipo de registro físico, más básico e incluso más
fiable que el anterior, pero que por desgracia no se suele utilizar mucho, son
las propias anotaciones sobre la marcha del sistema que todo administrador debería
realizar en una especie de 'cuaderno de bitácora' de cada equipo. Evidentemente
la única persona con acceso a dicho cuaderno debería ser el administrador,
y debería guardarse en un lugar seguro, aplicando las mismas políticas
que por ejemplo aplicamos a las cintas de backup (alejadas del entorno
de operaciones para prevenir la pérdida ante un desastre físico,
almacenadas bajo llave...).
Next: Copias de seguridad
Up: Seguridad del sistema Previous: Programas seguros, inseguros y Índice
General