Ruben Groenewoud

Ingeniería de detección de Linux con Auditd

En este artículo, obtenga más información sobre el uso de Auditd y Auditd Manager para la ingeniería de detección.

Ingeniería de detección de Linux con Auditd

Introducción

Los sistemas Unix y Linux operan entre bastidores, apuntalando silenciosamente una parte significativa de nuestra infraestructura tecnológica. Con la creciente complejidad de las amenazas dirigidas a estos sistemas, garantizar su seguridad se volvió más importante que nunca.

Una de las herramientas fundamentales en el arsenal de ingenieros de detección de seguridad que trabajan en sistemas Unix y Linux es Auditd. Esta poderosa utilidad está diseñada para monitorear y registrar eventos del sistema, proporcionando una pista de auditoría detallada de quién hizo qué y cuándo. Actúa como un perro guardián, patrullando y registrando información detallada sobre las llamadas al sistema, los accesos a los archivos y los cambios del sistema, que son cruciales para el análisis forense y el monitoreo en tiempo real.

El objetivo de este artículo es multifacético:

  1. Nuestro objetivo es proporcionar información adicional sobre Auditd, mostrando sus capacidades y el inmenso poder que tiene en la ingeniería de detección de seguridad.
  2. Lo guiaremos a través de la configuración de Auditd en sus propios sistemas, adaptándolo para satisfacer sus necesidades específicas de monitoreo. Al comprender cómo crear y modificar reglas de Auditd, aprenderá a capturar el comportamiento exacto que le interesa monitorear e interpretar los registros resultantes para crear sus propias reglas de detección.
  3. Presentaremos Auditd Manager, una herramienta de integración que mejora la utilidad de Auditd al simplificar la administración de Auditd en todos los sistemas.

Al final de esta publicación, no solo aprenderá a emplear Auditd Manager para incorporar algunas de nuestras reglas de detección prediseñadas en su estrategia de seguridad, sino que también obtendrá una comprensión integral de Auditd y cómo aprovecharlo para crear sus propias reglas de detección.

Introducción a Auditd

Auditd es una herramienta de Linux diseñada para monitorear y registrar eventos del sistema para proporcionar una pista de auditoría completa de las actividades del usuario, los cambios del sistema y el acceso de seguridad. Auditd funciona conectar al kernel de Linux, capturando información detallada sobre las llamadas al sistema y otros eventos del sistema a medida que ocurren. Estos eventos se registran en un archivo, proporcionando un registro con marca de tiempo. Los administradores pueden definir reglas que especifiquen qué eventos registrar, ofreciendo la flexibilidad de centrar en áreas específicas de interés o preocupación. Los datos registrados se pueden emplear para una variedad de propósitos, desde auditorías de cumplimiento hasta análisis forenses detallados.

Configuración auditada

Para comenzar con Auditd, Elastic ofrece varias opciones:

En este artículo, nos centraremos en los dos últimos, aprovechando Elastic Agent para ingerir fácilmente logs en Elasticsearch. Si eres nuevo en Elasticsearch, puedes crear fácilmente una cuenta de Elastic Cloud con una licencia de prueba de 30 días o, para pruebas locales, puedes descargar The Elastic Container Project y establecer el valor de la licencia en prueba en el .env archivo.

No dudes en seguir usando Auditbeat o Filebeat: para obtener instrucciones de configuración, consulta la documentación vinculada anteriormente. Como la integración de Auditd Logs funciona analizando el archivo audit.log, debe instalar Auditd en el host Linux desde el que desea recopilar los registros. Dependiendo de la distribución de Linux y del administrador de paquetes elegido, se debe instalar el paquete Auditd y se debe iniciar y habilitar el servicio Auditd. Para distribuciones basadas en Debian:

sudo apt update
sudo apt install auditd
sudo systemctl start auditd
sudo systemctl enable auditd

El archivo /var/log/audit/audit.log ahora debe rellenar con registros de auditoría. A continuación, debes instalar la integración de Auditd Logs, crear una política de agente en Fleet con la integración recién instalada y aplicar la integración a un Elastic Agent compatible con Auditd instalado.

La configuración predeterminada debería ser suficiente para la mayoría de los escenarios. A continuación, debe agregar la integración a una política de agente y agregar la política de agente a los Elastic Agents de los que desea recopilar datos. Elastic Agent envía los logs al logs-auditd.log-[namespace] flujo de datos. Ahora puede crear una nueva vista de datos para que solo coincida con nuestros registros de auditoría entrantes.

Ahora puede explorar los registros auditados ingeridos. Pero como notará rápidamente, Auditd no registra mucho de forma predeterminada: debe aprovechar las reglas de Auditd para desbloquear todo su potencial.

Auditd rules

Las reglas auditd son directivas que se emplean para especificar qué actividades del sistema monitorear y registrar, lo que permite un control granular sobre el proceso de auditoría de seguridad. Estas reglas se configuran normalmente en el archivo /etc/audit/audit.rules . Las reglas auditadas vienen en 3 variedades: control, filey syscall. Puede encontrar más información aquí.

Reglas de tipo de control

En la mayoría de los casos, el tipo de control se usa para configurar Auditd en lugar de especificar los eventos que se van a monitorear. De forma predeterminada, el archivo de reglas de auditoría contiene la siguiente configuración de tipo de control:

-D
-b 8192
-f 1
--backlog_wait_time 60000
  • -D: elimina todas las reglas al iniciar (Auditd analiza las reglas del archivo de arriba a abajo. La eliminación de todas las reglas en el lanzamiento garantiza una configuración limpia).
  • -b 8192: establece la cantidad máxima de búferes de auditoría existentes en el kernel.
  • -f 1: establezca el modo de error de Auditd en log.
  • --backlog_wait_time 60000: especifique la cantidad de tiempo (en MS) que el sistema de auditoría esperará si se alcanza el límite de trabajo pendiente de auditoría antes de eliminar los registros de auditoría.

Reglas del sistema de archivos

Basar en esta configuración de tipo de control predeterminada, puede crear reglas del sistema de archivos, a veces denominadas inspecciones. Estas reglas nos permiten monitorear archivos de interés para acciones de lectura, escritura, cambio y ejecución. Una regla típica del sistema de archivos tendría el siguiente aspecto:

-w [path-to-file] -p [permissions] -k [keyname]
  • -w: la ruta al archivo o directorio a monitorear.
  • -p: cualquiera de las licencias de lectura (r), escritura (w), ejecución (e) o cambio (a).
  • -k: el nombre de un identificador de clave que se puede emplear para buscar más fácilmente en los registros auditd.

En caso de que desee monitorear el archivo /etc/shadow en busca de lecturas, escrituras y cambios de archivos, y almacenar dichos eventos con una clave denominada shadow_access, puede configurar la siguiente regla:

-w /etc/shadow -p rwa -k shadow_access

Reglas de llamada al sistema

El verdadero poder de Auditd se revela cuando se trabaja con sus reglas de llamada al sistema. Las reglas de llamada al sistema auditadas son configuraciones que especifican qué llamadas al sistema (syscalls) se deben monitorear y registrar, lo que permite un seguimiento detallado de la actividad del sistema y las interacciones con el kernel del sistema operativo. A medida que cada llamada al sistema se intercepta y se hace coincidir con la regla, es importante aprovechar esta funcionalidad con cuidado capturando solo las llamadas al sistema de interés y, cuando sea posible, capturando varias de estas llamadas al sistema en una regla. Una regla de llamada al sistema típica se vería así:

-a [action],[filter] -S [syscall] -F [field=value] -k [keyname]

Puede aprovechar el indicador -a seguido de action,filter para elegir cuándo se registra un evento, dónde se puede always (crear siempre un evento) o never action (nunca crear un evento).

El filtro puede ser cualquiera de los siguientes:

  • task: registra eventos de creación de tareas.
  • entry: registra los puntos de entrada de syscall.
  • exit: registra las salidas/resultados de las llamadas del sistema.
  • user: registra eventos en el espacio de usuario.
  • exclude: excluye eventos del registro.

A continuación, tienes:

  • -S: la llamada al sistema que le interesa (nombre o número de llamada al sistema).
  • -F: uno o más filtros para elegir con qué coincidir.
  • -k: identificador de clave.

Con la información proporcionada anteriormente, debería poder comprender los conceptos básicos de la mayoría de las reglas de Auditd. Para obtener más información y ejemplos de qué valores se pueden agregar a estas reglas, no dude en leer más aquí.

Comenzar a crear y probar un archivo de reglas de Auditd completo y dedicado para su organización puede parecer desalentador. Afortunadamente, hay algunos buenos ejemplos de archivos de reglas públicas disponibles en GitHub. Una plantilla favorita para construir es la de Neo23x0, que es un buen equilibrio entre visibilidad y rendimiento.

Una desventaja de usar la integración de registros auditados es que debe instalar manualmente Auditd en cada host que desee monitorear y aplicar el archivo de reglas manualmente a cada instancia de Auditd en ejecución. Esto significa que cada vez que desee actualizar el archivo de reglas, tendrá que actualizarlo en todos los hosts. Hoy en día, muchas organizaciones aprovechan las herramientas de gestión que pueden hacer que este proceso consuma menos tiempo. Sin embargo, Elastic también proporciona otra forma de ingerir logs auditados a través de la integración de Auditd Manager, lo que alivia la carga de la administración.

Introducción a Auditd Manager y configuración

La integración de Auditd Manager recibe eventos de auditoría del marco de auditoría de Linux que forma parte del kernel de Linux. Esta integración establece una subscripción al kernel para recibir los eventos a medida que ocurren. El marco de auditoría de Linux puede enviar varios mensajes para un único evento auditable. Por ejemplo, una llamada al sistema rename() hace que el kernel envíe ocho mensajes separados. Cada mensaje describe un aspecto diferente de la actividad que está ocurriendo (la llamada al sistema en sí, las rutas de archivo, el directorio de trabajo actual, el título del proceso). Esta integración combinará todos los datos de cada uno de los mensajes en un solo evento. Puede encontrar más información sobre Auditd Manager aquí.

Además, Auditd Manager resuelve la carga de gestión, ya que permite una gestión centralizada a través de Fleet. Se aplicará automáticamente una actualización de la integración a todos los agentes de Elastic que forman parte de la política de agente modificada.

Configurar la integración de Auditd Manager es sencillo. Debe cerciorar de que Auditd ya no se ejecuta en nuestros hosts, deteniendo y deshabilitando el servicio.

sudo systemctl stop auditd
sudo systemctl disable auditd

Ahora puede eliminar la integración de Auditd Logs de nuestra política de agente y, en su lugar, instalar/agregar la integración de Auditd Manager.

Hay varias opciones disponibles para configurar la integración. Auditd Manager nos brinda la opción de establecer la configuración de auditoría como inmutable (similar a establecer la regla de tipo de control -e 2 en la configuración de Auditd), lo que brinda seguridad adicional en la que los usuarios no autorizados no pueden cambiar el sistema de auditoría, lo que dificulta ocultar la actividad maliciosa.

Puede aprovechar la funcionalidad Resolver ID para habilitar la resolución de UID y GID en sus nombres asociados.

Para nuestra administración de reglas de auditoría, puede proporcionar las reglas en la sección Reglas de auditoría o aprovechar un archivo de reglas y especificar la ruta del archivo desde el que leer este archivo. El formato de la regla es similar al formato de la regla para la integración de registros auditados. Sin embargo, en lugar de proporcionar indicadores de control en nuestro archivo de reglas, puede establecer estas opciones en la configuración de integración.

Auditd Manager purga automáticamente todas las reglas existentes antes de agregar las nuevas reglas proporcionadas en la configuración, por lo que no es necesario especificar el indicador -D en el archivo de reglas. Además, puede configurar nuestro modo de falla en silent en la configuración y, por lo tanto, tampoco es necesario proporcionar el indicador de -f .

También puede establecer el límite de trabajo pendiente, que sería similar a establecer la marca -b .

También hay una opción para establecer la estrategia de contrapresión, equivalente a la configuración --backlog_wait_time .

Finalmente, marque la opción para preservar el evento original, ya que esto le permitirá analizar el evento más fácilmente en el futuro.

Ahora puede almacenar la integración y aplicarla a la política del agente para los hosts de los que desea recibir registros auditados.

Solución de problemas del archivo de reglas auditd

El archivo de reglas proporcionado por Neo23x0 no funciona para Auditd Manager de forma predeterminada. Para que funcione, tendrá que realizar algunos ajustes menores, como eliminar las marcas de tipo de control, una conversión de UID a usuario para un usuario que no está presente en los sistemas predeterminados o una entrada de regla redundante. Los cambios que deben realizar serán en última instancia únicos para su entorno.

Tiene dos formas de identificar los errores que se generarán al copiar y pegar un archivo incompatible en la integración de Auditd Manager. Puede navegar hasta el agente que recibió la política y ver el error de entrada de integración. Puede analizar los errores uno por uno y cambiar o eliminar la línea conflictiva.

También puede usar la pestaña Descubrir , seleccionar nuestra vista de datos del Administrador auditado y filtrar los eventos en los que existe el campo auditd.warnings y revisar las advertencias una por una.

Por ejemplo, puede ver que el error indica "tipo de regla desconocido" , que está relacionado con Auditd que no admite reglas de control. El "error al convertir el usuario 'x' en un ID numérico", está relacionado con el usuario que no existe en el sistema. Y finalmente, "la regla 'x' es un duplicado de 'x'", está relacionada con las reglas duplicadas. Ahora que eliminó las entradas en conflicto y nuestro estado de agente es correcto, puede comenzar a analizar algunos datos de Auditd.

Análisis de eventos de Auditd Manager

Ahora que tienes datos de Auditd Manager disponibles en nuestro clúster de Elasticsearch, tal como lo hiciste antes, puedes crear una vista de datos para el índice de logs-auditd_manager.auditd* para filtrar específicamente estos datos. Nuestro archivo de reglas implementado contiene la siguiente entrada:

-w /etc/sudoers -p rw -k priv_esc

Esto captura acciones de lectura y escritura para el archivo /etc/sudoers y escribe estos eventos en un registro con la clave priv_esc . Ejecutemos el comando cat /etc/sudoers y analicemos el evento. Veamos primero algunos de los campos que contienen información general.

Puede ver que el binario /usr/bin/cat accedió al archivo /etc/sudoers a través de la llamada al sistema openat(). Como el propietario del archivo y el grupo son rooty el usuario que aplicar acceso a este archivo no es UID 0 (raíz), se produjo un error en la llamada al sistema de openat() , que se representa en el registro. Finalmente, puede ver la etiqueta que se vinculó a esta actividad específica.

Profundizando un poco más, puede identificar información adicional sobre el evento.

Puede ver la línea de comandos del proceso que se ejecutó y qué ID de proceso e ID principal del proceso iniciaron la actividad. Además, puede ver desde qué arquitectura se originó el evento y a través de qué tty (terminal conectado a la entrada estándar) se ejecutó el comando.

Para comprender los valores a0-3, debe profundizar en las llamadas al sistema de Unix. En este punto, debe ser consciente de lo que es una llamada al sistema, pero para completarla, una llamada al sistema de Unix (llamada al sistema) es una interfaz fundamental que permite a un programa aplicar un servicio del kernel del sistema operativo, como operaciones de archivos, control de procesos o comunicaciones de red.

Echemos un vistazo a la openat() llamada al sistema. Consultando la página del manual de open(2) (fuente), verá la siguiente información.

openat() es una versión evolucionada de la llamada al sistema open() , que permite el acceso a archivos en relación con un descriptor de archivo de directorio (dirfd). Esta llamada al sistema permite que un programa abra un archivo o directorio, una operación crucial para muchas tareas del sistema. Puede ver que la llamada al sistema es parte de la biblioteca C estándar y está disponible en fcntl.h encabezado a través de la instrucción #include <fcntl.h> include.

Consultando el manual, puede ver que la sintaxis de openat() syscall es la siguiente:

int openat(int dirfd, const char *pathname, int flags, /* mode_t mode */);
  • dirfd Especifica el descriptor del archivo de directorio.
  • *pathname es un puntero al nombre del archivo/directorio que se va a abrir.
  • flags Determine el modo de operación (por ejemplo, lectura, escritura, creación, etc.).

Volviendo a nuestro evento original, ahora está listo para comprender los campos auditd.data.a0-a3 . Los a0 a a3 valores de un registro auditd representan los argumentos pasados a una llamada al sistema. Estos argumentos son cruciales para comprender el contexto y los detalles de la ejecución de la llamada al sistema. Analicemos cómo se relacionan estos valores con openat() y qué nos dicen sobre el intento de operación basado en nuestra exploración anterior.

  • auditd.data.a0 (dirfd): El valor a0, ffffff9c, indica una directiva especial, AT_FDCWD, lo que sugiere que la operación es relativa al directorio de trabajo actual.
  • auditd.data.a1 (pathname): El valor a1 , 7ffd0f81871d, representa una dirección de memoria hexadecimal que apunta a la cadena de nombre de ruta del archivo o directorio de destino. En este caso, se refiere a un intento de acceder al archivo /etc/sudoers .
  • auditd.data.a2 (flags): Reflejado por el valor a2 de 0, el argumento flags especifica el modo en el que se va a acceder al archivo. Con 0 que indica que no se usaron marcas especiales, implica una operación predeterminada, probablemente acceso de solo lectura.
  • auditd.data.a3 (mode): El valor a3 , también 0, se vuelve relevante en contextos donde se está creando el archivo, dictando las licencias establecido en el nuevo archivo.

Según el análisis anterior, ahora tiene una comprensión bastante buena de cómo interpretar los eventos de Auditd Manager.

Una forma diferente de tener una idea rápida de lo que significa un evento de Auditd Manager es mediante el uso del asistente de IA integrado de Elastic. Ejecutemos el comando whoami y echemos un vistazo al campo auditd.messages dentro del evento.

Puedes pedirle al Asistente de IA de Elastic que haga el trabajo pesado y analice el evento, luego de lo cual solo tienes que consultar el manual de syscall para cerciorarte de que fue correcto. Primero creemos un nuevo aviso del sistema, centrado en analizar los registros de Auditd, algo similar a esto:

Ahora puede aprovechar el mensaje del sistema recién creado y pegar el mensaje de Auditd allí sin ningún formato adicional, y recibir la siguiente respuesta:

Las herramientas de IA generativa son muy útiles para recibir una explicación rápida de un evento. Pero la IA generativa puede cometer errores, por lo que siempre debe ser consciente de aprovechar las herramientas de IA para este tipo de análisis y verificar qué resultados genera. Especialmente cuando se aprovecha el resultado de estas herramientas para el desarrollo de reglas de detección, ya que un error menor podría conducir a una lógica defectuosa.

Ejemplos de reglas de detección de Auditd Manager

Luego de leer la sección anterior, ahora debería tener suficiente conocimiento disponible para comenzar a analizar los registros de Auditd Manager. El conjunto actual de reglas de detección de Elastic aprovecha principalmente la integración de Elastic Defend, pero la cantidad de reglas que aprovechan Auditd está aumentando significativamente. En esta sección se profundizará en varias reglas de detección que aprovechan Auditd, se explicará el por qué y se intentará mostrar algunas técnicas infrautilizadas para escribir consultas de reglas de detección.

Posible shell inverso a través de UDP

La regla Potential Reverse Shell via UDP tiene como objetivo identificar los shells inversos basados en UDP. Como Elastic Defend actualmente no captura el tráfico UDP, puedes aprovechar Auditd para cerrar esta brecha de visibilidad. La regla aprovecha la siguiente lógica:

sample by host.id, process.pid, process.parent.pid
  [process where host.os.type == "linux" and event.type == "start" and event.action == "executed" and process.name : (
    "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "perl", "python*", "nc", "ncat", "netcat", "php*",
    "ruby", "openssl", "awk", "telnet", "lua*", "socat"
    )]
  [process where host.os.type == "linux" and auditd.data.syscall == "socket" and process.name : (
    "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "perl", "python*", "nc", "ncat", "netcat", "php*",
    "ruby", "openssl", "awk", "telnet", "lua*", "socat"
    ) and auditd.data.a1 == "2"]
  [network where host.os.type == "linux" and event.type == "start" and event.action == "connected-to" and
   process.name : (
    "bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "perl", "python*", "nc", "ncat", "netcat", "php*",
    "ruby", "openssl", "awk", "telnet", "lua*", "socat"
    ) and network.direction == "egress" and destination.ip != null and
   not cidrmatch(destination.ip, "127.0.0.0/8", "169.254.0.0/16", "224.0.0.0/4", "::1")]

La regla aprovecha la funcionalidad de ejemplo , que describe y coincide con un serial de eventos cronológicamente desordenados. Esto cerciorará que la secuencia también se active si los eventos ocurren en el mismo milisegundo. Además, aprovechamos un enfoque de lista blanca para especificar binarios sospechosos que son capaces de generar una conexión inversa, lo que permite minimizar la tasa de falsos positivos.

Cercioramos la captura de conexiones UDP aprovechando los datos auditados relacionados con la llamada al sistema socket().

Vemos que el valor a0 representa el dominio, a1 representa el tipo y a2 representa el protocolo empleado. Nuestra regla aprovecha la sintaxis auditd.data.a1 == "2" , que se traduce en el tipo SOCK_DGRAM , que es UDP.

Por último, nos cercioramos de capturar solo las conexiones de red de salida del host y garantizar la exclusión de direcciones de bucle invertido IPv4 e IPv6, direcciones de enlace IPv4 locales y de multidifusión, y secuenciamos la consulta por process.pid y process.parent.pid para cerciorarnos de que los eventos se originan en el mismo proceso (principal).

Si queremos buscar procesos sospechosos que abran sockets UDP, podemos consultar todas las llamadas al sistema socket() con auditd.data.a1 == "2", contar el número de ocurrencias de procesos distintos y ordenarlos en orden ascendente para encontrar anomalías. Para ello, podemos aprovechar este ES|Consulta QL:

FROM logs-*, auditbeat-*
| EVAL protocol = CASE(
    auditd.data.a1 == "1", "TCP",
    auditd.data.a1 == "2", "UDP"
)
| WHERE host.os.type == "linux" and auditd.data.syscall == "socket" and protocol == "UDP"
| STATS process_count = COUNT(process.name), host_count = COUNT(host.name) by process.name, protocol
| SORT process_count asc
| LIMIT 100

Al observar los resultados, podemos ver aparecer bastantes procesos interesantes, que podrían ser un buen punto de partida para la búsqueda de amenazas.

Carcasa inversa de Meterpreter de potencial

Otro tipo interesante de conexiones inversas para las que aprovechamos Auditd es la detección del shell Meterpreter, que es un shell inverso popular empleado dentro de Metasploit-Framework. La regla de shell inverso de Meterpreter potencial aprovecha el comportamiento de enumeración de host predeterminado de Meterpreter para detectar su presencia.

sample by host.id, process.pid, user.id
  [file where host.os.type == "linux" and auditd.data.syscall == "open" and auditd.data.a2 == "1b6" and file.path == "/etc/machine-id"]
  [file where host.os.type == "linux" and auditd.data.syscall == "open" and auditd.data.a2 == "1b6" and file.path == "/etc/passwd"]
  [file where host.os.type == "linux" and auditd.data.syscall == "open" and auditd.data.a2 == "1b6" and file.path == "/proc/net/route"]
  [file where host.os.type == "linux" and auditd.data.syscall == "open" and auditd.data.a2 == "1b6" and file.path == "/proc/net/ipv6_route"]
  [file where host.os.type == "linux" and auditd.data.syscall == "open" and auditd.data.a2 == "1b6" and file.path == "/proc/net/if_inet6"]

Cuando se genera Meterpreter, recopila información predeterminada del sistema, como la máquina, el usuario y la información de enrutamiento IP, mediante la lectura de archivos específicos del sistema. Podemos ver este comportamiento al descompilar la carga útil de Meterpreter, ya que las rutas están codificadas en el binario.

Nuestra lógica de detección aprovecha auditd.data.a2 == “1b6”, ya que es coherente con el comportamiento del Meterpreter. Podemos encontrar a Meterpreter aprovechando esta combinación específica de llamadas al sistema para leer archivos observando la forma en que Meterpreter abre los controladores de archivos.

Solo con fines informativos, algunas otras rutas de acceso que lee Meterpreter se pueden encontrar en la captura de pantalla a continuación.

Podemos aprovechar ES|QL para analizar un conjunto de shells inversos de Meterpreter y averiguar fácilmente a qué rutas de archivo acceden todos ellos.

FROM logs-*, auditbeat-*
| WHERE host.os.type == "linux" and event.action == "opened-file" and process.name in ("shell-x64.elf", "JBNhk", "reverse.elf", "shell.elf", "elf") and auditd.data.a2 == "1b6"
| STATS file_access = COUNT_DISTINCT(process.name) by file.path
| SORT file_access desc
| LIMIT 100

En este ejemplo, solo estamos analizando 5 shells de Meterpreter, pero usando ES|QL podemos escalar fácilmente este análisis a números más grandes. Según la información anterior, podemos ver que las rutas que se seleccionaron para la regla de detección están presentes en las cinco muestras.

Combinando la lógica anterior, podemos descubrir potencialmente cargas útiles de Linux Meterpreter.

Se detectó un ataque de fuerza bruta FTP / RDP de Linux

Dado que hay tantos clientes FTP/RDP diferentes disponibles para Linux, y los registros de autenticación no se implementan de manera similar, puede aprovechar el campo auditd.data.terminal de Auditd para detectar diferentes implementaciones de FTP/RDP. Nuestra lógica de detección de FTP tiene el siguiente aspecto:

sequence by host.id, auditd.data.addr, related.user with maxspan=3s
  [authentication where host.os.type == "linux" and event.action == "authenticated" and 
   auditd.data.terminal == "ftp" and event.outcome == "failure" and auditd.data.addr != null and 
   auditd.data.addr != "0.0.0.0" and auditd.data.addr != "::"] with runs=5

  [authentication where host.os.type == "linux" and event.action  == "authenticated" and 
   auditd.data.terminal == "ftp" and event.outcome == "success" and auditd.data.addr != null and 
   auditd.data.addr != "0.0.0.0" and auditd.data.addr != "::"] | tail 1

Aquí, secuenciamos 5 intentos fallidos de inicio de sesión con 1 intento de inicio de sesión exitoso en el mismo host, desde la misma IP y para el mismo usuario. Aprovechamos la función de cola que funciona de manera similar a la cola en Unix, seleccionando el último número X de alertas en lugar de seleccionar todas las alertas dentro del periodo de tiempo. Esto no afecta la interfaz de reglas de detección de SIEM, solo se usa para facilitar la lectura, ya que los ataques de fuerza bruta pueden generar rápidamente muchas alertas.

Aunque estamos aprovechando diferentes herramientas FTP como vsftpd, la entrada auditd.data.terminal sigue siendo similar en todas las herramientas, lo que nos permite capturar una gama más amplia de ataques de fuerza bruta de FTP. Nuestra regla de detección de RDP aprovecha una lógica similar:

sequence by host.id, related.user with maxspan=5s
  [authentication where host.os.type == "linux" and event.action == "authenticated" and
   auditd.data.terminal : "*rdp*" and event.outcome == "failure"] with runs=10
  [authentication where host.os.type == "linux" and event.action  == "authenticated" and
   auditd.data.terminal : "*rdp*" and event.outcome == "success"] | tail 1

Dado que auditd.data.terminal campos de diferentes clientes RDP son inconsistentes, podemos aprovechar los comodines para capturar sus eventos de autenticación.

Conexión de red desde binario con región de memoria RWX

La llamada al sistemamprotect() se usa para cambiar las protecciones de acceso en una región de memoria que ya se asignó. Esta llamada al sistema permite que un proceso modifique las licencias de las páginas en su espacio de direcciones virtuales, habilitando o deshabilitando licencias como lectura, escritura y ejecución para esas páginas. Nuestro objetivo con esta regla de detección es detectar conexiones de red de binarios que tienen establecido licencias de región de memoria de lectura, escritura y ejecución. Echemos un vistazo a la llamada al sistema.

Para nuestra lógica de regla de detección, el valor prot es lo más importante. Puede ver que prot puede tener las siguientes marcas de acceso:

Como se indicó, prot es un OR bit a bit de los valores de la lista. Entonces, para las licencias de lectura, escritura y ejecución, estamos buscando un int de:

int prot = PROT_READ | PROT_WRITE | PROT_EXEC;

Esto se traduce en un valor de 0x7 luego de bitwising, y por lo tanto estaremos viendo un auditd.data.a2 == “7”. Creamos dos reglas de detección que aprovechan esta lógica: ejecución desconocida de binario con región de memoria RWX y conexión de red desde binario con región de memoria RWX. Las reglas de detección que aprovechan configuraciones específicas de Auditd para funcionar, tendrán una nota sobre qué regla agregar en su guía de configuración:

El anterior aprovecha el tipo de regla new_terms , lo que nos permite detectar términos previamente desconocidos dentro de una ventana de tiempo específica. Esto nos permite detectar binarios con licencias RWX que se ven en un host específico por primera vez, al tiempo que reduce los falsos positivos para los binarios que son demasiado permisivos pero que se usan de manera regular.

Este último aprovecha la siguiente lógica de detección:

sample by host.id, process.pid, process.name
[process where host.os.type == "linux" and auditd.data.syscall == "mprotect" and auditd.data.a2 == "7"]
[network where host.os.type == "linux" and event.type == "start" and event.action == "connection_attempted" and
   not cidrmatch(destination.ip, "127.0.0.0/8", "169.254.0.0/16", "224.0.0.0/4", "::1")
]

Se muestra un proceso que se ejecuta con estas licencias RWX, luego de lo cual se inicia una conexión de red (excluyendo las direcciones de bucle invertido, multidifusión y local de vínculo).

Curiosamente, Metasploit a menudo asigna estas licencias RWX a regiones específicas de sus cargas útiles generadas. Por ejemplo, uno de los eventos que desencadenan esta lógica de detección en una pila de pruebas está relacionado con la ejecución de Postgres Payload de Metasploit para Linux. Al analizar el código fuente de esta carga útil, puede ver que la función payload_so define las marcas PROT_READ, PROT_WRITE y PROT_EXEC .

Luego de lo cual, una región de memoria específica, con un tamaño de página específico de 0x1000 recibe las marcas de acceso RWX de manera similar a la descrita anteriormente.

Luego de ejecutar la carga útil y consultar la pila, puede ver que se devuelven varios hits, todos relacionados con las cargas útiles de Metasploit Meterpreter.

Centrándonos en la carga útil de Postgres que estábamos analizando anteriormente, puede ver la ruta exacta de ejecución de la carga útil a través de nuestro analizador visual de eventos. Elastic Security permite analizar cualquier evento detectado por Elastic Endpoint mediante un analizador visual basado en procesos, que muestra una línea de tiempo gráfica de los procesos que condujeron a la alerta y los eventos que ocurrieron inmediatamente después. El examen de eventos en el analizador visual de eventos es útil para determinar el origen de la actividad potencialmente maliciosa y otras áreas del entorno que pueden estar en peligro. También permite a los analistas de seguridad profundizar en todos los hosts, procesos y otros eventos relacionados para ayudar en sus investigaciones.

En el analizador, puede ver que se aprovecha perl para crear y completar la carga útil jBNhk en el directorio /tmp (con licencias RWX) y generar un shell Meterpreter inverso.

Conclusión

En este post, nos sumergimos en el mundo de Auditd, explicando qué es y su propósito. Te mostramos cómo poner en marcha Auditd, cómo canalizar esos logs a Elasticsearch para aumentar la visibilidad de Unix/Linux y permitirte mejorar tus habilidades de ingeniería de detección de Linux. Discutimos cómo crear reglas de Auditd para vigilar actividades específicas y cómo dar sentido a los eventos que genera. Para hacer la vida más fácil, presentamos Auditd Manager, una integración creada por Elastic para quitarte parte de la carga de administración de encima. Finalmente, terminamos explorando varias reglas de detección y parte de la investigación que se realizó para crearlas, lo que le permite aprovechar al máximo esta fuente de datos.

¡Esperamos que esta guía le resultó útil! La incorporación de Auditd en sus sistemas Unix es un movimiento inteligente para una mejor visibilidad de la seguridad. Ya sea que decida seguir nuestras reglas de detección prediseñadas o crear algunas propias, Auditd realmente puede fortalecer su juego de seguridad Unix.