Auditd proporciona no solo una forma de rastrear información relevante para la seguridad del sistema, si no también permite obtener información a la hora de rastrear cualquier otro problema con los procesos y sistemas de ficheros. Muy útil para saber qué proceso se ejecutó cuando, qué borro/modificó/leyó, etc.
Según las reglas configuradas Auditd genera entradas de logs para registrar la mayor cantidad posible de información sobre los eventos que suceden en su sistema. Esta información permite determinar en entornos críticos quién viola determinadas política de seguridad y de qué manera. Auditd no proporciona seguridad adicional al sistema, simplemente registra eventos según unas reglas definidas. Estos son algunos ejemplos de lo que se puede hacer con Auditd.
NOTA: Si simplemente se desea detectar cambios sobre el sistema de ficheros (creación, eliminación, cambios de nombre, apertura de ficheros, etc) se puede hacer uso de inotify. Muy útil para implementarlo en scrips, veamos un ejemplo donde se muestran en pantalla acciones de escritura y renombre de archivos/directorios dentro de /root recursivamente.
inotifywait -rm /root -e create -e moved_to # Se pueden usar tuberías para trabajar con los datos obtenidos, para el ejemplo "path", "action" y "file". inotifywait -rm /root -e create -e moved_to | while read path action file; do echo "El fichero '$file' del directorio '$path' fue modificado: '$action'" done
Auditd consta de dos partes, las aplicaciones y utilidades de espacio de usuario y el procesamiento de llamadas del sistema del del kernel. El núcleo recibe llamadas al sistema desde aplicaciones de espacio de usuario y las filtra a través de uno de los tres filtros: usuario, tarea o salida.
audisp: Demonio que provee un mecanismo (plugins) para interactuar con el demonio auditd desde otras aplicaciones, normalmente de análisis.
auditctl: Herramienta de control de Auditd que interactúa con el núcleo para controlar configuraciones y parámetros del proceso de generación de eventos.
Las utilidades restantes de Auditd utilizan el contenido de los archivos de registro de Auditd como entrada y generan resultados en función de los requisitos del usuario. Por ejemplo, la utilidad aureport genera un informe de todos los eventos grabados.
Auditd puede registrar muy rápidamente un gran número de eventos y así llenar un disco o partición. Por eso la configuración del demonio auditd es importante en entornos críticos e incluso ciertas opciones obligatorias en algunos entornos, como por ejemplo los CAPP.
Fichero de configuración de Auditd: /etc/audit/auditd.conf
Configuración del demonio para entornos CAPP: Perfil de protección de control de acceso.
#### Tamaño de ficheros de logs. max_log_file = 100 # Tamaño máximo del registro de logs (100Mb). max_log_file_action keep_logs # Acción si se supera el máximo tamaño de logs. # "keep_logs" permite que no se sobrescriban (ROTATE). #### Espacio libre en disco. space_left = 1024 # Cantidad de espacio libre en disco (1Gb). space_left_action = SYSLOG # Define una acción (normalmente de notificación) a realizar cuando se superó el valor de space_left. admin_space_left = 50 # Cantidad de espacio libre antes de desencadenar una acción administrativa. admin_space_left_action = single # Acción: Usar el modo single para suspender Auditd y dejar de registrar eventos. # Debe establecerse un valor que de tiempo al administrador a responder y librar espacio. # El valor space_left depende de la velocidad a la que se generan los archivos de registro de auditoría. disk_full_action = halt # Especifica una acción que se desencadena cuando no hay espacio libre para los logs de Auditd. # Valores: halt (apagar) / single (modo usuario) #### Mensajes de Syslog de ejemplo. # Opción: space_left_action = SYSLOG # Mensaje: Audit daemon is low on disk space for logging # Opción: admin_space_left_action = SUSPEND # Syslog: Audit daemon is suspending logging due to low disk space.
Las reglas definen lo que los logs deben registrar.
Las reglas se pueden especificar por línea de comandos con auditctl (no persistente). De manera persistente se puede usar el script “augenrules” que lee los ficheros con extensión xxxx.rules de /etc/audit/rules.d/ y genera el fichero /etc/audit/audit.rules, el cual puede editarse a mano también.
augenrules
augenrules --check # Comprueba si hay reglas cambiadas o nuevas y se necesita generar de nuevo audit.rules augenrules --load # Carga las nuevas reglas en el kernel.
auditctl
auditctl -b 8192 Máximo tamaño para el buffer del kernel. -f 1 Como informar al nucleo cuando un problema con auditd ha sido detectado. -e 2 Habilita (0) o deshabilita (1) auditd, con (2) se bloquea. -r 0 Límite de logs registrados por segundo 0 establece sin límite. -s Estado de systemd. -l Lista las reglas actuales en uso. -D Borra todas las reglas en uso. -W Borrar una regla relativa al sistema de ficheros. Debe especificarse siempre todos los parámetros, ej. "auditctl -W /usr/bin -p x -k sbin_monitor" -d Borra las reglas definidas mediante llamadas al sistema: auditctl -d always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F uid=0 -k sbin_monitor -R /usr/share/doc/audit-version/stig.rules Permite definir una ruta a un fichero con reglas.
NOTA: Para borrar (-W y -d) se debe especificar la regla completa (auditctl -l). Una vez eliminada la regla, sus logs pueden seguir siendo cosultados mediante ausearch. Si se quiere obtener el nombre de las reglas que todavía se encuentran en los ficheros de logs, se puede hacer uso de grep de la siguiente manera.
zgrep -E "add_rule.*res=1" /var/log/audit/audit.log* | grep -o key=\".*\"
El fichero de configuración “/etc/audit/auditd.conf” únicamente puede tener los parámetros -D, -b, -e, -f y -r.
# Borra todas las reglas anteriores. -D # Define un buffer, por defecto 64. -b 8192 # Hace la configuración inmutable obligando a un reinicio del sistema (2), con 0 se deshabilita auditd y con 1 se habilita de nuevo. -e 2 # Como debe manejar el kernel errores críticos: 0 = silent 1 = printk (predeterminado) 2 = pánico (Recomendado para entornos críticos) -f 2 # Generar como máximo 100 logs por segundo. -r 100
Las reglas de “/etc/audit/audit.rules” se pueden configurar a mano pero simplemente obviando escribir “auditctl”.
# Reglas del sistema de ficheros. -w /etc/passwd -p wa -k passwd_changes -w /etc/selinux/ -p wa -k selinux_changes -w /sbin/insmod -p x -k module_insertion
Nota: Depende del paquete instalado, en /usr/share/doc/audit-version/ pueden encontrarse ficheros de configuración para diferentes entornos que requieren de certificaciones de seguridad específicas.
Estas reglas se denominan “watches” y tienen un menor impacto en el rendimiento que las demás reglas.
Sintaxis.
auditctl -w ruta_fichero -p permisos -k key_name
Ejemplo: Cambios por escritura y/o cambio de permisos sobre /etc/shadow.
auditctl -w /etc/shadow -p wa -k passwd_changes
Esto también podría hacerse con una regla de llamada al sistema, pero al listarla se mostrará como un watch.
auditctl -a always,exit -F path=/etc/shadow -F perm=wa # auditctl -W /etc/shadow -p wa # Borra la regla (recordar que se debe utilizar -W y no "-d").
Excluir ficheros o directorios es posible agregando otra regla extra. Ejemplo monitorizando la ejecución de todos los ficheros de /usr/bin a excepción de /usr/sbin/ausearch.
auditctl -a never,exit -S all -F dir=/usr/sbin/ausearch -F key=sbin_monitor auditctl -w /usr/sbin -p x -k sbin_monitor
Sintaxis de auditctl para reglas de llamadas al sistema.
auditctl -a action,filter -S system_call -F field=value -k key_name
Ejemplo: Registrar cualquier cambio de nombre o eliminación de fichero por parte del usuario root (uid 0).
auditctl -a always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F uid=0 -k delete # auditctl -d always,exit -F arch=b64 -S unlink -S unlinkat -S rename -S renameat -F uid=0 -k delete # Borra la regla (-d).
Ejecución de comandos que activa la regla del ejemplo anterior para registrar borrados o cambios de nombre de fichero por parte del usuario root.
touch aaaaaaaaaaa rm aaaaaaaaaaa
Fichero /var/log/audit/audit.log.
type=SYSCALL msg=audit(1522369023.154:748): arch=c000003e syscall=263 success=yes exit=0 a0=ffffffffffffff9c a1=23a90c0 a2=0 a3=7ffc19e80120 items=2 ppid=3276 pid=3430 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=5 comm="rm" exe="/usr/bin/rm" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="delete" type=CWD msg=audit(1522369023.154:748): cwd="/root" type=PATH msg=audit(1522369023.154:748): item=0 name="/root" inode=67147297 dev=fd:00 mode=040550 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:admin_home_t:s0 objtype=PARENT type=PATH msg=audit(1522369023.154:748): item=1 name="aaaaaaaaaaa" inode=67147305 dev=fd:00 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:admin_home_t:s0 objtype=DELETE type=PROCTITLE msg=audit(1522369023.154:748): proctitle=726D002D69006161616161616161616161
Explicación de campos de los logs de auditd.
Algunos campos muestran su valor en forma de códigos o directamente en hexadecimal. El comando ausearch interpreta esos logs y permite una visualización más amigable de los registros auditd. Veamos a continucación un desglose y explicación de los campos de audit.log.
Primera linea de registro Auditd.
# Primera linea. # type=SYSCALL msg=audit(1522369023.154:748): arch=c000003e syscall=263 success=yes exit=0 a0=ffffffffffffff9c a1=23a90c0 a2=0 a3=7ffc19e80120 items=2 ppid=3276 pid=3430 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=5 comm="rm" exe="/usr/bin/rm" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="delete" # Tipo de registro, PATH, SYSCALL, LOGIN, ADD_GROUP, etc type=SYSCALL # Timestamp y un ID de evento auditd (puede ser el mismo que el de otros registros). msg=audit(1522369023.154:748): # Arquitectura en hexadecimal (x86_64). arch=c000003e # Tipo de llamada del sistema, "unlinkat", obtenido mediante "ausyscall --dump | grep 263" syscall=263 # Si la llamada al sistema tuvo éxito o no. success=yes # Código de salida, 0 cuando es correcto. exit=0 # Argumentos en hexadecimal de la llamada al sistema. a0=ffffffffffffff9c a1=23a90c0 a2=0 a3=7ffc19e80120 # Rutas a fichero registradas en el evento. items=2 # IDs de usuario, grupos, etc. uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 # Terminal donde se provocó el evento. tty=pts1 # Sesión ID. ses=5 # Linea de comandos utilizada para invocar el evento y su ruta. comm="rm" exe="/usr/bin/rm" # Etiqueta SELinux. subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 # Llave definida para identificar la regla. key="delete"
Segunda linea.
# Segunda linea: type=CWD msg=audit(1522369023.154:748): cwd="/root" # Directorio de trabajo (current working directory) type=CWD # Mismo timestamp e ID de SELinux que vimos en la primera linea. msg=audit(1522369023.154:748): # Ruta donde el evento fue inicializado. cwd="/root"
Tercera y cuarta linea (Una por cada item, el directorio /root y el fichero “aaaaaaaaaaa”).
# Tercera y cuarta linea. # type=PATH msg=audit(1522369023.154:748): item=0 name="/root" inode=67147297 dev=fd:00 mode=040550 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:admin_home_t:s0 objtype=PARENT # type=PATH msg=audit(1522369023.154:748): item=1 name="aaaaaaaaaaa" inode=67147305 dev=fd:00 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:admin_home_t:s0 objtype=DELETE # Ruta pasada como argumento a la llamada del sistema. type=PATH # Mismo timestamp e ID de SELinux que vimos en la primera linea. msg=audit(1522369023.154:748): # Primer item referenciado por la llamada al sistema, su ruta e inodo. item=0 name="/root" inode=67147297 # Dispositivo usado en el evento, en este caso /dev/fd/0 (/dev/fd/0 -> /dev/pts/0), una pseudoterminal. dev=fd:00 # Permisos del directorio o fichero en notación numérica (550 equivale a r-xr-x---). mode=040550 # UID / GID del propietario del archivo / directorio. ouid=0 ogid=0 # Identificador de dispositivo para ficheros especiales, en este caso ninguno ya que era un directorio normal. rdev=00:00 # Etiqueta SELinux aplicada al objeto (fichero o directorio vinculado al evento). obj=system_u:object_r:admin_home_t:s0 objtype=PARENT # La cuarta linea es muy similar y trata sobre el fichero /root/aaaaaaaaaaa que recibió la acción de borrado (objtype=DELETE). type=PATH msg=audit(1522369023.154:748): item=1 name="aaaaaaaaaaa" inode=67147305 dev=fd:00 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:admin_home_t:s0 objtype=DELETE
NOTA: Un objeto puede ser un archivo, un directorio, un socket o cualquier cosa que esté recibiendo una acción (borrado, edición, etc).
Quinta linea.
# Quinta linea. # type=PROCTITLE msg=audit(1522369023.154:748): proctitle=726D002D69006161616161616161616161 # Tipo de registro, PROCTITLE identifica que el evento fue generado mediante la linea de comandos (comando rm). type=PROCTITLE # Comando en hexadecimal. echo -n "rm aaaaaaaaaaa" | xxd proctitle=726D002D69006161616161616161616161
ausearch buscar por defecto en los registros de /var/log/audit/audit.log.
# fichero de configuración alternativo. ausearch -if fichero_configuración
Opciones útiles de ausearch.
ausearch -k key # Busca por llave (nombre de la regla / grupo de reglas). ausearch -p 12345 # Buscar por identificador de proceso. ausearch -c touch # Busca todos los eventos que tengan que ver con el comando touch (comm="touch"). ausearch -ua 100 # Buscar por id de usuario, tanto el efectivo como el login user id (auid). ausearch -gi 100 # Buscar por GID. ausearch -x XXXX # Buscar por Path del binario ejecutado (exe="/usr/bin/touch"). ausearch -sc XXX # Buscar por llamada del sistema. ausearch -sv yes # Buscar por estado de finalización, si fue exitoso "yes", en caso contrario "no". ausearch -f file # Buscar por fichero / directorio. ausearch -w word comando # Las coincidencias basadas en cadenas deben coincidir con la palabra completa. # Esta categoría de coincidencias incluye: nombre de archivo, nombre de host, terminal y contexto de SELinux. # Ejemplo: ausearch -w -f /home/vagrant/
Buscar por fechas.
ausearch -ts 03/30/2018 00:00:00 -te 03/31/2018 08:00:00
Buscar todos los logs con la llave “delete”, evento (key delete) creado cuando root eliminó el fichero “aaaaaaaaaaa”.
ausearch -k delete time->Fri Mar 30 00:17:03 2018 type=PROCTITLE msg=audit(1522369023.154:748): proctitle=726D002D69006161616161616161616161 type=PATH msg=audit(1522369023.154:748): item=1 name="aaaaaaaaaaa" inode=67147305 dev=fd:00 mode=0100644 ouid=0 ogid=0 rdev=00:00 obj=unconfined_u:object_r:admin_home_t:s0 objtype=DELETE type=PATH msg=audit(1522369023.154:748): item=0 name="/root" inode=67147297 dev=fd:00 mode=040550 ouid=0 ogid=0 rdev=00:00 obj=system_u:object_r:admin_home_t:s0 objtype=PARENT type=CWD msg=audit(1522369023.154:748): cwd="/root" type=SYSCALL msg=audit(1522369023.154:748): arch=c000003e syscall=263 success=yes exit=0 a0=ffffffffffffff9c a1=23a90c0 a2=0 a3=7ffc19e80120 items=2 ppid=3276 pid=3430 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=5 comm="rm" exe="/usr/bin/rm" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key="delete"
Aureport está orientado a hacer reportes / sumatorios de los eventos registrados.
Buscar por rango de fechas.
aureport -ts 03/30/2018 00:00:00 --te 03/31/2018 00:00:00
Opciones útiles de aureport.
aureport --summary # Estadísticas generales (eventos, accesos, procesos, etc). Se puede combinar con otras opciones para realizar sumatorios. Ejemplo: aureport -x --summary aureport --success # Estadísticas de eventos con resultado exitoso . aureport --failed # Estadísticas de eventos con resultado fallido. # Obtención de reportes (se puede combinar con --summary). aureport -c # Reporte de cambios en la configuración de auditd. aureport -l # Reporte de logins en el sistema. aureport -p # Reporte de procesos: Fecha, tiempo, id,nombre, syscalls, auid y número de evento. aureport -f # Reporte de ficheros: Fecha, tiempo, id,nombre, syscalls, auid y número de evento. aureport -u # Reporte de usuarios: Fecha, tiempo, id,nombre, syscalls, auid y número de evento. aureport -s # Reporte de syscalls: Fecha, tiempo, número de llamada, nombre del comando que uso la syscall, auid y número de evento.
Enlaces de interés.