jueves, 25 de junio de 2015

Jugando con Linux Audit System Parte II

En la entrada anterior veíamos los cimientos de Linux Audit System, ahora vamos a ver un par de aplicaciones prácticas como para hacernos una idea mas clara de para qué se puede utilizar.

La instalación por defecto de Ubuntu no trae ninguna regla pre configurada en audit. Podemos ver las reglas que se encuentran cargadas utilizando auditctl -l de la siguiente manera:

root@ubuntu:/home/juan# auditctl -l
No rules
root@ubuntu:/home/juan#

Reglas de audit

Existen 3 tipos de reglas en audit
  • Reglas de control: permiten modificar el comportamiento de audit.
  • Reglas de archivos (File system): permiten registrar los accesos y modificaciones a archivos y directorios.
  • Reglas de syscalls:  permiten registrar la utilización de las llamadas al system por parte de los procesos.

Reglas de control

Estas reglas van a definir el comportamiento de audit en lineas generales. Por ejemplo la cantidad de buffers disponibles, el comportamiento ante errores críticos, etc.

En el siguiente ejemplo configuramos  audit para que ante un evento crítico genere un kernel panic

root@ubuntu:/home/juan# auditctl -f 2
AUDIT_STATUS: enabled=1 flag=2 pid=882 rate_limit=0 backlog_limit=320 lost=0 backlog=0
root@ubuntu:/home/juan#


Ahora con la opción "-e 2" bloqueamos la configuración para que no pueda ser modificada salvo con un reinicio:

root@ubuntu:/home/juan# auditctl -e 2
AUDIT_STATUS: enabled=2 flag=2 pid=882 rate_limit=0 backlog_limit=320 lost=0 backlog=0
root@ubuntu:/home/juan# auditctl -e 1
Error sending enable request (Operation not permitted)
root@ubuntu:/home/juan# auditctl -e 0
Error sending enable request (Operation not permitted)
root@ubuntu:/home/juan# auditctl -f 1
Error sending failure mode request (Operation not permitted) root@ubuntu:/home/juan#


ninguna operación que modifique el comportamiento de audit estará permitida, la única forma de solucionar esto es reiniciar el sistema. Una vez reiniciado el sistema, enabled vuelve a ser 1, es decir se vuelve a habilitar el cambio de configuración.

root@ubuntu:/home/juan# auditctl -s
AUDIT_STATUS: enabled=1 flag=1 pid=880 rate_limit=0 backlog_limit=320 lost=0 backlog=0
root@ubuntu:/home/juan#

Reglas de archivos

Las reglas de archivos o directorios tienen 3 componentes, el path del archivos indicado por "-w", los permisos indicados por "-p" y una cadena indicada por "-k".

Ejemplo 1: para reportar cada vez que un usuario ejecuta el comando ping hacemos:

root@ubuntu:/home/juan# auditctl -w /bin/ping -p x -k "haciendo ping xD"
root@ubuntu:/home/juan# auditctl -l
LIST_RULES: exit,always watch=/bin/ping perm=x key=haciendo ping xD
root@ubuntu:/home/juan#  


Podemos ver que la regla fue agregada y si ahora hacemos ping

juan@ubuntu:~$ ping -c 1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=58 time=62.0 ms

--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 62.040/62.040/62.040/0.000 ms
juan@ubuntu:~$


veremos las siguientes líneas en /var/log/audit/audit.log

type=EXECVE msg=audit(1435008355.184:39): argc=4 a0="ping" a1="-c" a2="1" a3="8.8.8.8"
type=CWD msg=audit(1435008355.184:39):  cwd="/home/juan"
type=PATH msg=audit(1435008355.184:39): item=0 name="/bin/ping" inode=130121 dev=08:01 mode=0104755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL
type=PATH msg=audit(1435008355.184:39): item=1 name=(null) inode=130569 dev=08:01 mode=0100755 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL


Y qué demonios significa todo eso...??? Vamos a desmenuzar un poco las líneas para entender qué nos está diciendo audit con ese log:

  • Los logs comienzan con un campo tipo type que indica el tipo de registro en cuestión.
  • A continuación viene el campo msg que se encuentra formado por el audit unique ID (los logs que formen parte de un mismo evento se pueden reconocer porque llevarán el mismo audit unique ID) compuesto por el timestamp (1435008355.184) y un identificador (39). Luego de esta campo veremos una lista variable de valores tipo name=value que dependerán del tipo de registro y harán referencia a los distintos campos informativos provistos por el kernel o las aplicaciones en espacio de usuario
Entonces si con esto analizamos las 3 lineas que registró audit daemon vemos:
  • El primer registro es de tipo EXECVE, este registra los parámetros de la syscall execve con la que se ejecutó ping.
  • El segundo registro es de tipo CWD y obtuvo el current working directory del evento /home/juan.
  • El tercer registro (item=0 de la syscall) es de tipo PATH y obtuvo información acerca del archivo /bin/ping, por ejemplo 
    • El inodo del archivo (130569)
    • El dispositivo donde se encuentra (08:01)
    • Los permisos del archivo 4755
    • OUID y OGID ID del usuario dueño y grupo del usuario dueño 0 y 0 en este caso.
  • El cuerto registro (item=1 de la syscall) hace referencia a la llamada al dynamic linker ld que es utilizado para cargar las librerias compartidas que precisa ping para ejecutarse.
    • Vemos el inodo del archivos utilizado (130569)
    • Los permisos (0755)
Ahora podemos comprobar todo esto que vimos en los logs de audit consultando directamente a los archivos en cuestión:

root@ubuntu:/home/juan# ls -lai /bin/ping
130121 -rwsr-xr-x 1 root root 38932 May  7  2014 /bin/ping
root@ubuntu:/home/juan# ls -lai /lib/i386-linux-gnu/ld-2.19.so
130569 -rwxr-xr-x 1 root root 134380 Feb 25 16:58 /lib/i386-linux-gnu/ld-2.19.so
root@ubuntu:/home/juan#  


Por suerte la información es consistente.

Ejemplo 2: ahora algo un poco más sencillo, registremos las alteraciones a un determinado archivo, por ejemplo /etc/resolv.conf

root@ubuntu:/home/juan# auditctl -w /etc/resolv.conf -p wa -k "resolv.conf"
root@ubuntu:/home/juan# auditctl -l
LIST_RULES: exit,always watch=/bin/ping perm=x key=haciendo ping xD
LIST_RULES: exit,always watch=/etc/resolv.conf perm=wa key=resolv.conf
root@ubuntu:/home/juan#


Ahora simplemente agregamos una linea al final con un comentario de la siguiente manera:

root@ubuntu:/home/juan# echo "#comentario" >> /etc/resolv.conf
root@ubuntu:/home/juan#


y vemos qué hay en los logs:

type=SYSCALL msg=audit(1435095642.812:48): arch=40000003 syscall=5 success=yes exit=3 a0=9fba768 a1=8441 a2=1b6 a3=9fba768 items=4 ppid=1033 pid=1034 auid=1000 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="bash" exe="/bin/bash" key="resolv.conf"
type=CWD msg=audit(1435095642.812:48):  cwd="/home/juan"
type=PATH msg=audit(1435095642.812:48): item=0 name="/etc/" inode=6957 dev=00:10 mode=040755 ouid=0 ogid=0 rdev=00:00 nametype=PARENT
type=PATH msg=audit(1435095642.812:48): item=1 name=(null) inode=260560 dev=08:01 mode=0120777 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL
type=PATH msg=audit(1435095642.812:48): item=2 name=(null) inode=8112 dev=00:10 mode=0100644 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL
type=PATH msg=audit(1435095642.812:48): item=3 name=(null) inode=8112 dev=00:10 mode=0100644 ouid=0 ogid=0 rdev=00:00 nametype=NORMAL


A decir verdad esperaba un log un poco mas humano y simple para este escenario, pero viene genial para aprender a usar otra de las herramientas de audit. La herramienta es ausearch, y nos permitirá buscar dentro de los logs determinados eventos y hasta es capaz de interpretar buena parte de los valores y reemplazarlos por palabras mas humanas, por ejemplo si buscamos eventos con la key resolv.conf veremos lo siguiente:

root@ubuntu:/home/juan# ausearch -i -k "resolv.conf"
----
type=CONFIG_CHANGE msg=audit(06/23/15 22:37:40.856:45) : auid=juan ses=1 op="add rule" key=resolv.conf list=exit res=yes
----
type=CONFIG_CHANGE msg=audit(06/23/15 22:38:05.520:46) : auid=juan ses=1 op="add rule" key=resolv.conf list=exit res=yes
----
type=PATH msg=audit(06/23/15 22:40:42.812:48) : item=3 name=(null) inode=8112 dev=00:10 mode=file,644 ouid=root ogid=root rdev=00:00 nametype=NORMAL
type=PATH msg=audit(06/23/15 22:40:42.812:48) : item=2 name=(null) inode=8112 dev=00:10 mode=file,644 ouid=root ogid=root rdev=00:00 nametype=NORMAL
type=PATH msg=audit(06/23/15 22:40:42.812:48) : item=1 name=(null) inode=260560 dev=08:01 mode=link,777 ouid=root ogid=root rdev=00:00 nametype=NORMAL
type=PATH msg=audit(06/23/15 22:40:42.812:48) : item=0 name=/etc/ inode=6957 dev=00:10 mode=dir,755 ouid=root ogid=root rdev=00:00 nametype=PARENT
type=CWD msg=audit(06/23/15 22:40:42.812:48) :  cwd=/home/juan
type=SYSCALL msg=audit(06/23/15 22:40:42.812:48) : arch=i386 syscall=open success=yes exit=3 a0=0x9fba768 a1=O_WRONLY|O_CREAT|O_APPEND a2=0666 a3=0x9fba768 items=4 ppid=1033 pid=1034 auid=juan uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=1 comm=bash exe=/bin/bash key=resolv.conf
root@ubuntu:/home/juan#


ahora se puede ver como muchos campos fueron reemplazados por valores un poco mas conocidos (se reemplazo syscall 5 por open, los ouid y ogid por root, etc).

Reglas de syscalls

Estas reglas ya implican un mayor detalle a la hora de definirlas. Son necesarios los siguientes parámetros:
  • -a action,filter: la acción puede ser always o never. Cuando se elige never, no se generan registros para este evento.
  • -S syscall: indica la syscall he se registrará.
  • -F name=value: permite afinar aún mas el filtro para desencadenar el regirstro de la syscall, por ejemplo se podría filtrar una determinada syscall para el proceso con pid=1000.
  • -k key: una clave para facilitar las búsqueda dentro de los logs.
Por ejemplo, vamos a crear una regla para registrar todos los eventos donde el usuario Juan elimine un archivo

root@ubuntu:/home/juan# grep juan /etc/passwd
juan:x:1000:1000:juan,,,:/home/juan:/bin/bash
root@ubuntu:/home/juan# auditctl -a always,exit -S unlink -F uid=1000 -k juan_delete
root@ubuntu:/home/juan# auditctl -l
LIST_RULES: exit,always uid=1000 (0x3e8) key=juan_delete syscall=unlink
root@ubuntu:/home/juan# 


una vez agregada la regla probamos eliminando un archivo:

juan@ubuntu:~$ touch file
juan@ubuntu:~$ ll -i file
158216 -rw-rw-r-- 1 juan juan 0 Jun 25 22:25 file
juan@ubuntu:~$ rm file
juan@ubuntu:~$


y controlamos los logs con ausearch interpretado (-i)

root@ubuntu:/home/juan# ausearch -i -k juan_delete
----
type=CONFIG_CHANGE msg=audit(06/25/15 22:19:59.309:35) : auid=juan ses=1 op="add rule" key=juan_delete list=exit res=yes 

----
type=PATH msg=audit(06/25/15 22:31:40.089:62) : item=1 name=file inode=158216 dev=08:01 mode=file,664 ouid=juan ogid=juan rdev=00:00 nametype=DELETE
type=PATH msg=audit(06/25/15 22:31:40.089:62) : item=0 name=/home/juan inode=149893 dev=08:01 mode=dir,755 ouid=juan ogid=juan rdev=00:00 nametype=PARENT
type=CWD msg=audit(06/25/15 22:31:40.089:62) :  cwd=/home/juan
type=SYSCALL msg=audit(06/25/15 22:31:40.089:62) : arch=i386 syscall=unlinkat success=yes exit=0 a0=0xffffff9c a1=0x86bdab8 a2=0x0 a3=0x0 items=2 ppid=1209 pid=1241 auid=juan uid=juan gid=juan euid=juan suid=juan fsuid=juan egid=juan sgid=juan fsgid=juan tty=pts1 ses=2 comm=rm exe=/bin/rm key=juan_delete
root@ubuntu:/home/juan#


a partir de los logs del evento, podemos averiguar bastante información de lo que sucedió como: el nombre del archivo eliminado, sus permisos, el comando utilizado la syscall, etc. Queda claro que no pudimos evitar la eliminación, sin embargo quedó bien registrada y documentada.

Rompamos

Bien a modo de última prueba se me ocurrió comprobar el funcionamiento de la opción "-f 2" que ante un evento desafortunado debería generar un kernel panic. Para forzar el evento desafortunado vamos a setear un rate limit the mensajes bajo, 2 por seguno:

root@ubuntu:/home/juan# auditctl -s
AUDIT_STATUS: enabled=1 flag=1 pid=885 rate_limit=0 backlog_limit=320 lost=0 backlog=0
root@ubuntu:/home/juan# auditctl -r 2
AUDIT_STATUS: enabled=1 flag=1 pid=885 rate_limit=2 backlog_limit=320 lost=0 backlog=0
root@ubuntu:/home/juan# auditctl -f 2
AUDIT_STATUS: enabled=1 flag=2 pid=885 rate_limit=2 backlog_limit=320 lost=0 backlog=0
root@ubuntu:/home/juan#

ahora con el nuevo rate limit y la opción de flag 2 seteada forzamos unos cuantos mensajes y boala:


la VM quedó completamente inutilizable.

Resumen

Linux System Audit es sin lugar a dudas una muy buena opción para registrar eventos en el sistema. Sin embargo hay algunas cosas para tener en cuenta:
  • Audit no proveé protección extra, solo reporta eventos. No sustituye ni a SELinux ni Apparmor, los complementa en todo caso.
  • Como toda medida de seguridad, puede afectar la performance del sistema si se aplica desmedidamente. El mismo man de auditcl lo confirma con "Syscall  rules get evaluated for each syscall for every program. If you have 10 syscall rules, every program on your system will delay during a syscall  while  the  audit system evaluates each rule. Too many syscall rules will hurt performance."
  • Las reglas se pueden poner de manera permanente en un archivo dentro de /etc/audit/rules.d/

No hay comentarios:

Publicar un comentario