En un sistema operativo, existen numerosos mecanismos de monitoreo y recopilación de datos que permiten monitorear la viabilidad de los componentes clave, la seguridad y el rendimiento. En una gran red informática, la recopilación de este tipo de datos es necesaria para responder oportunamente a diversos tipos de eventos e incidentes.
Arquitectónicamente esta tarea se puede realizar de diferentes maneras, en Linux Existe un mecanismo de kernel BPF de bajo nivel que permite implementar código arbitrario en un espacio privilegiado. Los módulos Snort/Suricata lo utilizan para filtrar el tráfico entrante, y tcpdump lo elimina antes de que llegue a la pila TCP/IP. Analicemos el algoritmo de trabajo y las principales ventajas de esta solución.
¿Qué son BPF y eBPF?
BPF o Filtro de Paquetes Berkley es una máquina virtual dentro del kernel del sistema operativo que permite cargar código arbitrario. El algoritmo de esta solución está vinculado a eventos del sistema. Cualquier programa BPF se iniciará solo después de que ocurra el evento al que está vinculado.
Los programas suelen escribirse en lenguaje C utilizando bibliotecas especiales y archivos de encabezado proporcionados por el proyecto LLVM y la comunidad eBPF. El archivo se compila posteriormente en un archivo program.o y se carga en el núcleo mediante la llamada al sistema bpf().
Es importante destacar que el propósito principal de un programa BPF es la monitorización y el rastreo de datos de entrada y salida de las funciones de la biblioteca/aplicación, así como el rastreo de los enlaces del sistema. Sirve para la recopilación de estadísticas, la evaluación del rendimiento y el desarrollo de subsistemas de seguridad.
Su versión extendida es eBPF, que tiene una funcionalidad similar, sin embargo, se presenta en versiones posteriores del kernel.
¿Cómo funcionan los programas y los objetos bpf?
Preinstalemos las herramientas necesarias para generar llamadas al sistema en relación con la pila BPF. Para ello, introduzca el comando en la línea:
Luego de revisar la funcionalidad y sintaxis de la herramienta que tenemos a nuestra disposición:
Está disponible la gestión de objetos como programas BPF, mapas BPF, enlaces y redes.
Programas del BPF
Para el seguimiento y rastreo se utilizan varios tipos de programas con diferentes mecanismos:
- uprobe: le permite crear puntos de interrupción en cualquier proceso de espacio de usuario, sin cambiar el código fuente;
- kprobe: se utiliza para rastrear eventos en el núcleo y los módulos, no requiere puntos de interrupción especiales en el código;
- puntos de seguimiento: se utilizan para rastrear eventos en el núcleo y los módulos, requieren puntos especiales en el código;
- perf_event: permite recopilar varias métricas, como el tiempo de ejecución de la función y el uso de recursos (CPU, memoria, etc.) y analizarlos para optimizar el rendimiento.
Analicemos el mecanismo con más detalle en un ejemplo práctico de monitorización del proceso de autenticación de usuarios. Usaremos uprobe, que nos permitirá conectarnos a una función de biblioteca y leer los datos transferidos. Revisemos la ruta completa a sshd:
Para el demonio, busquemos las bibliotecas que carga; clásicamente, muchas soluciones usan PAM en Linux:
PAM también está presente en sshd, por lo que lo usaremos para volcar credenciales. Veamos las funciones internas que pueden contener el proceso de autenticación:
Entre las funciones presentadas, la más interesante es pam_get_authtok, que trabaja con el token de usuario. Usemos bpftrace para cargar el programa y comprobar la corrección de la función encontrada:
¡Genial! El programa BPF se ejecutó porque se llamó a la función pam_get_authtok y su contexto estaba disponible. Esto significa que el programa pudo volcar las credenciales de la función y guardarlas en el almacenamiento.
Mapas del BPF
Aquí se llaman mapas BPF y almacenan todos los datos en formato clave:valor. Puedes verlos con el comando:
Además, el PID puede usar una llamada al sistema para acceder a las celdas y exportar las credenciales. Diversos programas BPF también pueden comunicarse con los mapas. Por lo tanto, es importante tener en cuenta que el acceso a este tipo de mecanismos debe estar restringido para los usuarios normales.
Vincular objetos
La comunicación entre un programa y un punto de monitorización es posible gracias al objeto Enlace, puedes visualizar los enlaces existentes entre programas y puntos de monitorización con el comando:
El tipo de conexión indica que el programa puede modificar los valores durante la transmisión, y el programa de seguimiento 2 indica que el seguimiento pertenece al programa con id 2. Veámoslo con el comando:
Presumiblemente modifica las solicitudes del dispositivo de interfaz humana, se puede eliminar con el comando:
Como resultado, obtenemos las instrucciones desensambladas utilizadas en el programa. Este tipo de análisis es útil para encontrar soluciones maliciosas y comprender el funcionamiento de mecanismos de monitoreo de bajo nivel como tcpdump y otros.