Zeek - Sistema de monitorización (2)
Zeek, previamente llamado Bro IDS, es una herramienta IDS como hemos comentado en el primer artículo, que nos permite monitorizar el tráfico de la red, capturándolo y analizándolo, dando como resultado una serie de eventos. Una de las principales características de Zeek, es que posee un intérprete de scripts de políticas, que tiene su propio lenguaje, llamado Zeek-Script. Haciendo uso de este lenguaje, así como de las muy variadas opciones de configuración que nos proporciona Zeek, analizaremos la herramienta en esta sección.
La pregunta más importante es qué nos ofrece zeek que no nos lo pueda proporcionar otro IDS del mercado. Y es qué frente al habitual funcionamiento de los IDS, en los cuales existen una serie de reglas que nos permiten detectar las amenazas, pero que frente a amenazas poco comunes pueden llegar a ser poco eficientes, Zeek nos proporciona a parte de todas esas reglas, un framework, el cual analizará el tráfico y permitirá de una forma más sencilla posteriormente a la persona encargada de ello, verificar si existe algún tipo de anomalía en la red.
Una de las características destacadas de Zeek es que permite automatizar parte del trabajo, ejemplo de ello según se menciona en la página oficial de Zeek, es que permite descargar archivos de la red y analizarlos en búsqueda de malware, notificar incidencias o incluso apagar el dispositivo que descargó el malware.
También hay que comentar que la herramienta es poco usable y que tiene un grado de dificultad elevado, debido a que en parte sus orígenes son como herramienta de investigación.
Funcionamiento básico
Para comenzar, si es la primera vez que usamos zeek, y previamente tenemos bien configurada la red, debemos de entrar a la consola de zeek, desde /usr/local/zeek/bin:
Una vez ahí debemos de usar el comando siguiente para comprobar el estado de la configuración de los ficheros que previamente comentamos.
El resto de veces que iniciemos zeek, bastaría con usar el comando siguiente para arrancar el servicio:
Para ver el estado de Zeek podemos usar el siguiente comando:
Para ver todos los scripts que tenemos activos para usar utilizamos la siguiente instrucción:
Para ver estadísticas de tráfico de red podemos usar:
Para mostrar la configuración:
Si tuviéramos varios nodos en funcionamiento podríamos verificar su funcionamiento mediante el siguiente comando. Si no hubiera ninguno, solo se mostraría nuestro ordenador.
Para parar la captura de red deberíamos de usar el siguiente comando
Una vez ejecutada una captura podemos hacer uso del siguiente comando para comprobar su ejecución:
Para ver los logs generados en tiempo real por zeek deberíamos de acceder a la ruta /usr/local/zeek/logs/current/.
Una vez detenida la captura, los logs se guardarán en la ruta /usr/local/zeek/logs/FechaDelLog
Para terminar con las opciones de funcionamiento básico, hay que comentar algo imprescindible para hacer un buen uso de Zeek, y son los dos logs más importantes: conn-log. Muestra todas las conexiones. notice.log. Muestra todos los eventos potencialmente interesantes según la configuración de Zeek.
Políticas, directivas y plugins
Las políticas son scripts escritos en lenguaje zeek, que describen qué tipos de actividades se consideran sospechosas. Existen muchas políticas creadas por defecto, pero para un uso adecuado de Zeek, deberíamos de crear políticas específicas para actividades concretas que deseemos detectar.
Para comenzar Zeek indica que políticas, plugins y directivas serán cargadas en el inicio de la sesión. Para ello debemos dirigirnos a /usr/local/zeek/share/zeek/site/local.zeek.
Para ello se usa la cláusula @load, sirviendo como ejemplo de su uso la siguiente sentencia.
@load nombre_script
A continuación, mostramos el script ejecución de inicio local.zeek previamente mencionado. Como podemos ver aparecen bien catalogados e indicados los scripts cargados.
Hoy en día, de hecho, existen repositorios en los cuales muchos usuarios publican scripts útiles. [6]
Las políticas se encuentran en el directorio /usr/local/zeek/share/zeek/policy/ y se dividen en varios subgrupos: files, frameworks, integration, misc, protocols y tuning.
En ellas se define qué paquetes se capturan, y cómo se captura el tráfico, buscando patrones, reglas, etc…
Con respecto a los plugins, se encuentran en /usr/local/zeek/lib/zeekctl/plugins. Zeek permite integrar plugins escritos en python. Haciendo uso de estos plugins, zeek nos permite configurar diversas acciones después de ejecutar órdenes, o crear nuestros propios comandos.
Las políticas son una de las partes más importantes del funcionamiento de Zeek y entraremos con más detalle en su funcionamiento en el apartado de la Prueba de Concepto. Será necesario conocer las particularidades de cada política concreta que vayamos a aplicar para adaptarla al funcionamiento de nuestra red. Por ejemplo, si entramos en la política que registra la pérdida de paquetes (capture-loss.zeek) podemos ver como en el apartado ‘export’ tiene algunas características que podemos modificar, como es el caso de los intervalos de tiempo en los que se crearán archivos logs sobre esta información o el porcentaje de pérdidas que se considerará demasiada pérdida:
Herramientas adicionales
Trace-summary [7]: Una herramienta que genera un resumen sobre las conexiones registradas en un archivo conn.log de Zeek o en cualquier archivo .pcap.
Algunas de las opciones más interesantes de trace-summary son:
- -b: Utiliza bytes en lugar de paquetes para sacar el resumen.
- -t: Solo incluye conexiones TCP.
- -u: Solo incluye conexiones UDP.
- -p: Indica una lista de puertos que serán los únicos que se deben tener en cuenta.
- -c: Señala que se va a introducir un fichero conn.log de Zeek.
Capstats: Ofrece estadísticas sobre una interfaz de red.
Aquí podemos observar cómo nos ofrece estadísticas sobre el tráfico de la interfaz wlan0 en intervalos de 10 segundos:
Zeek-cut: Esta herramienta nos permite obtener una salida más acorde con lo que deseemos en cada momento a partir de un log de Zeek de entrada.
Esta herramienta trabaja sobre el resultado de un ‘cat’ de un fichero log de Zeek. En el siguiente ejemplo estamos indicando que del conn.log indicado por el cat queremos que nos muestre el tiempo (ts), el host de origen (id.orig_h), el puerto de origen (id.orig_p) y la duración de la conexión (duration). En la prueba de concepto posterior se verá mejor el funcionamiento y la utilidad de esta herramienta.
Logs
Para acceder a los logs, la opción más sencilla es hacer uso de una herramienta que nos proporciona zeek, llamada zeek-cut, y que se encuentra en /usr/local/zeek/bin/zeek-cut.
Esta herramienta nos permite visualizar las columnas que deseamos de los logs, y en el orden elegido, ya que los logs tienen multitud de columnas como veremos a continuación.
Un ejemplo del uso de zeek-cut adaptándolo a nuestras necesidades sería el siguiente:
zcat /usr/local/zeek/logs/2020-05-05/conn.17:31:55-17:35:26.log.gz | /usr/local/zeek/bin/zeek-cut ts id.orig_h id.orig_p id.resp_h id.resp_p proto orig_bytes | more |
En zeek encontramos una variedad de logs muy amplia, que podemos clasificar según su ámbito en logs de protocolos de red, logs de archivos, logs de control de red, logs de detección, logs de observaciones, logs de miscelánea y logs de diagnósticos. [8] [9]
Cada uno de estos logs tiene una larga lista de campos, que podemos consultar desde el propio terminal de zeek o a través de la documentación online de zeek. Para un análisis más sencillo es recomendable usar, como comentamos previamente, la herramienta zeek-cut para solo mostrar los campos que realmente nos son de utilidad. A continuación, mostraremos la larga lista de campos que tiene uno de estos tipos de logs como es conn.log:
- ts: Fecha del primer paquete.
- uid: Identificador único de conexión.
- id: Conexión de 4 tuplas de direcciones/puertos.
- proto: Protocolo de capa de transporte de la conexión.
- service: Identificación de un protocolo de aplicación que se envía en la conexión.
- duration: Duración de la conexión. Para los cortes de conexión de 3 o 4 vías, esto no incluirá el ACK final.
- orig_bytes: Número de bytes que el que crea el mensaje envía.
- resp_bytes: Número de bytes que el que responde envía.
- conn_state: Indicador de estado de conexión.
- local_orig: Si la conexión se origina localmente este valor será T, sino se deja vacío.
- local_resp: Si la conexión se responde localmente, este valor será T, sino se deja vacío.
- missed_bytes: Indica el número de bytes perdidos.
- history: Registro del historial de estado de las conexiones como una cadena de letras.
- orig_pkts: Número de paquetes que el creador del mensaje envió.
- orig_ip_bytes: Número de bytes de nivel de IP que envió el creador del mensaje.
- resp_pkts: Número de paquetes que el que responde al mensaje envía.
- resp_ip_bytes: Número de bytes de nivel de IP que envió el que responde al mensaje.
- tunnel_parents: Si la conexión se realizó mediante un túnel, indica los valores de uid para la conexión principal.
- orig_l2_addr: Si está disponible, dirección de capa de enlace del emisor.
- resp_l2_addr: Si está disponible, dirección de capa de enlace de la respuesta.
- vlan: Si aplica, VLAN externa para la conexión.
- inner_vlan: Si aplica, VLAN interna para la conexión.
- speculative_service: Protocolo que se determinó mediante una firma coincidente. en este caso los datos no pueden ser analizados, ni se pueda confirmar el protocolo.
Pulsa aquí para continuar con la última parte del artículo.
Referencias
[6] bro/bro-scripts: Misc. Bro scripts.
[8] Log Files — Zeek User Manual v3.1.3
[9] bro-cheatsheets/Corelight-Bro-Cheatsheets-2.6.pdf at master · corelight/bro-cheatsheets