El proyecto Openwall ha publicado el módulo del kernel LKRG 1.0.0 (Linux Kernel Runtime Guard), diseñado para comprobar la integridad de las estructuras del kernel e identificar intentos de explotar sus vulnerabilidades. Cabe destacar que la asignación del número de versión 1.0.0 marcó que el proyecto alcanzó una etapa madura. El código del proyecto se distribuye bajo la licencia GPLv2.
El módulo es adecuado tanto para protección contra ataques, que manipulan vulnerabilidades conocidas en el kernel de Linux, así como para contrarrestar exploits que explotan vulnerabilidades aún desconocidas, a menos que empleen medidas especiales para eludir LKRG. La protección se basa en la detección de cambios no autorizados en el kernel en ejecución (comprobación de integridad) y la monitorización de cambios en los privilegios de los procesos de usuario (detección de exploits).
La comprobación de integridad se realiza comparando los hashes calculados para las áreas más importantes de la memoria y las estructuras de datos del kernel, como IDT (Tabla de Descriptores de Interrupciones), MSR, tablas de llamadas del sistema, todos los procedimientos y funciones, manejadores de interrupciones, listas de módulos cargados, el contenido de la sección ".text" de los módulos y los atributos de proceso. El procedimiento de comprobación se activa periódicamente mediante un temporizador o cuando se producen ciertos eventos en el kernel, por ejemplo, al ejecutar las llamadas al sistema setuid, setreuid, fork, exit, execve y do_init_module.
La identificación de posibles exploits y el bloqueo de ataques se realiza antes de que el núcleo otorgue acceso a los recursos (por ejemplo, antes de abrir un archivo), pero después de que el proceso haya obtenido privilegios no autorizados (por ejemplo, modificando el UID). Cuando se detecta un comportamiento no autorizado en los procesos, estos se cierran forzosamente, lo cual es suficiente para bloquear muchos exploits. Los costes generales del módulo se estiman entre el 2 % y el 2.5 %.
Es compatible con las arquitecturas x86-64, AArch64 (ARM64), ARM32 y x86. LKRG 1.0.0 se ha probado con kernels de diversas distribuciones, desde RHEL/CentOS 3.10 kernel 7 hasta 6.17-rc4 del repositorio de versiones de Fedora 44. Hay paquetes disponibles para ALT Linux, Arch Linux, Astra Linux, Gentoo, Guix, NixOS, Rocky Linux, Whonix, Yocto y OpenBMC. Los paquetes creados para Rocky Linux se pueden usar en RHEL 8/9 y derivados, como AlmaLinux 8/9, y los paquetes Whonix en Debian y Ubuntu.
Entre los cambios de la nueva versión:
- Se garantiza la compatibilidad con los kernels de Linux hasta la versión 6.17-rc4.
- Al usar kernels posteriores a la versión 6.13, se ha detenido la intercepción de llamadas remotas a override_creds() y revert_creds(), lo que ha limitado la detección de ataques que redefinen el puntero cred. Se han intentado compensar estas limitaciones añadiendo comprobaciones para reescribir el puntero cred en otras partes del kernel.
- Se eliminó el seguimiento excesivo de credenciales sin verificación de integridad. Este cambio redujo la base de código en aproximadamente 1500 líneas.
- Se agregó compatibilidad con el mecanismo introducido en el kernel de Linux 6.10 para crear archivos temporales en el sistema de archivos OverlayFS mediante la opción O_TMPFILE (ovl_tmpfile). Esta compatibilidad es necesaria para evitar los falsos positivos que se producen al usar contenedores aislados en sistemas con kernels 6.10-6.12.
- Para los sistemas x86_64, se ha agregado soporte para Intel CET (Control-flow Enforcement Technology) para proteger el código ejecutable mediante instrucciones IBT (seguimiento de rama indirecto), así como protección de software kCFI (kernel Control Flow Integrity) para bloquear violaciones del orden de ejecución normal (flujo de control) como resultado del uso de exploits que cambian los punteros a las funciones almacenadas en la memoria.
- Para conectar muchos controladores, en lugar de kretprobes, se utiliza el mecanismo kprobes, que simplifica el código de instalación del gancho y permite lograr un mayor rendimiento.
- Se ha rediseñado el manejo de bloqueos de datos específicos del proceso (bloqueos) en el kernel (datos de sombra por tarea). Al eliminar bloqueos innecesarios, se mejoró el rendimiento del acceso a dichos datos.
- Se corrigieron errores que causaban condiciones de carrera, problemas de verificación de integridad y falsos positivos.
- Soporte mejorado para la construcción usando Clang.
Fuente: opennet.ru
