21 de gen. 2009

Auditoria del sistema linux

web original de:

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.

El sistema de log en Unix

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

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 ambos por espacios o tabuladores. El campo de selección está compuesto a su vez de dos partes separadas por un punto: una que indica el servicio que envía el mensaje y otra que marca 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). En segundo lugar, 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 en su fichero de configuración 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
La segunda parte de cada línea del archivo de configuración de syslogd es el campo de acción, y describe el destino de los mensajes (dónde se van a guardar o qué programa los va a procesar); este destino puede ser uno de los siguientes:
  • 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 dispositivo físico
    También tenemos la posibilidad de enviar los registros del sistema a un dispositivo físico del mismo, típicamente un terminal o una impresora. Así conseguimos, entre otras cosas, que esas entradas permanezcan relativa o totalmente inalteradas (en función de qué dispositivo las reciban). Por ejemplo, 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 mediante la combinación de teclas correspondiente:
    # 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, sin más que indicar en el campo de acción el nombre o dirección de dicho sistema precedido por el signo `@'. 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, copia que no podría ser modificada en caso de que alguien entrase en la máquina que los está generando. Esto es especialmente interesante para detectar usuarios `ocultos' en nuestro sistema (usuarios maliciosos que han conseguido los suficientes privilegios para ocultar sus procesos o su conexión), ya que una de las principales cosas que hará este tipo de atacantes es eliminar cualquier registro que denote su presencia en la máquina (por ejemplo, sus entradas en wtmp).
    En el siguiente ejemplo utilizamos un sistema a priori confiable para enviarle algunos de nuestros registros:
    # 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 sus 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; para ello utilizamos un asterisco en el campo de acción:
    # Mostramos los mensajes urgentes a todos los usuarios
    # conectados, mediante wall
    *.=emerg *
Cuando un programa quiere enviar un mensaje al demonio syslogd utiliza la llamada syslog(3); al hacerlo, se ha de indicar tanto el servicio como la prioridad del mismo. Evidentemente, esto es válido para el código en C: si queremos enviar registros al demonio para que sean procesados desde un shellscript podemos utilizar la orden logger, en la que también podemos indicar ambos parámetros:
luisa:~# logger -p local0.info "Esto es una prueba"
luisa:~# tail -1 /var/adm/messages
May 14 03:53:14 luisa root: Esto es una prueba
luisa:~#

Algunos archivos de log

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 ya hemos comentado y luego veremos con mayor detalle), existen ciertos archivos de registro `habituales' en los que se almacena información. A continuación vamos a comentar los más comunes y la información que registra cada uno de ellos.

syslog

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:/#

messages

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:
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] 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] 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] 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:/#

wtmp

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 el fichero 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.

utmp

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.

lastlog

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 órdenes como who o 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:/#

faillog

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:~$

loginlog

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:/#

btmp

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:~#

sulog

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:/#
El registro de las invocaciones a la orden su puede estar deshabilitado por defecto en algunos sistemas Unix: por ejemplo, en Solaris es necesario crear manualmente el fichero /var/adm/sulog, mientras que en algunas distribuciones de Linux es necesario modificar el archivo /etc/login.defs para habilitar el registro de la actividad, tal y como veremos en el capítulo dedicado a este clon de Unix. De esta forma, al instalar el sistema, y antes de pasarlo a un entorno de producción, quizás nos interese asegurarnos de que estamos guardando todos los cambios de identidad que se producen en la máquina a través de su.

debug

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:~#

Logs remotos

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 sistema7.1.

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.

Registros físicos

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...).