Vulnerabilidade raíz no núcleo de Linux e denegación de servizo en systemd

Os investigadores de seguridade de Qualys revelaron detalles de dúas vulnerabilidades que afectan ao núcleo de Linux e ao xestor do sistema systemd. Unha vulnerabilidade do núcleo (CVE-2021-33909) permite que un usuario local poida executar código con dereitos de root mediante a manipulación de directorios moi aniñados.

O perigo da vulnerabilidade vese agravado polo feito de que os investigadores puideron preparar exploits de traballo que funcionen en Ubuntu 20.04/20.10/21.04, Debian 11 e Fedora 34 na configuración predeterminada. Nótase que outras distribucións non foron probadas, pero teoricamente tamén son susceptibles ao problema e poden ser atacadas. Prométese que o código completo dos exploits se publicará despois de que se elimine o problema en todas partes, pero polo de agora só está dispoñible un prototipo de funcionalidade limitada, o que provoca que o sistema falle. O problema está presente desde xullo de 2014 e afecta ás versións do núcleo a partir da 3.16. A corrección da vulnerabilidade coordinouse coa comunidade e aceptouse no núcleo o 19 de xullo. As principais distribucións xa xeraron actualizacións dos seus paquetes do núcleo (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch).

A vulnerabilidade é causada por non comprobar o resultado dunha conversión size_t a int antes de realizar operacións no código seq_file, que crea ficheiros a partir dunha secuencia de rexistros. Se non se verifica, pode producirse escrituras fóra dos límites no búfer ao crear, montar e eliminar unha estrutura de directorios moi aniñada (tamaño do camiño superior a 1 GB). Como resultado, un atacante pode conseguir unha cadea de 10 bytes "//deleted" escrita cun desfase de "-2 GB - 10 bytes" que apunte á área inmediatamente anterior ao búfer asignado.

O exploit preparado require 5 GB de memoria e 1 millón de inodos libres para funcionar. O exploit funciona chamando a mkdir() para crear unha xerarquía de preto dun millón de subdirectorios para conseguir un tamaño de ruta de ficheiro superior a 1 GB. Este directorio montase mediante bind-mount nun espazo de nomes de usuario separado, despois de que se executa a función rmdir() para eliminalo. Paralelamente, créase un fío que carga un pequeno programa eBPF, que se bloquea na fase despois de comprobar o pseudocódigo eBPF, pero antes da súa compilación JIT.

No espazo de nomes de ID de usuario sen privilexios, ábrese o ficheiro /proc/self/mountinfo e lese o camiño longo do directorio montado no enlace, o que resulta en que a cadea "//deleted" se escriba na área antes do inicio do búfer. Escóllese a posición para escribir a liña para que sobrescriba a instrución no programa eBPF xa probado pero aínda non compilado.

A continuación, a nivel de programa eBPF, a escritura descontrolada fóra do búfer transfórmase nunha capacidade controlada para ler e escribir noutras estruturas do núcleo mediante a manipulación das estruturas btf e map_push_elem. Como resultado, o exploit determina a localización do búfer modprobe_path[] na memoria do núcleo e sobrescribe a ruta "/sbin/modprobe" nel, o que lle permite iniciar o lanzamento de calquera ficheiro executable con dereitos de root en caso de chamada request_module(), que se executa, por exemplo, ao crear un socket de enlace de rede.

Os investigadores proporcionan varias solucións que só son eficaces para unha explotación específica, pero que non eliminan o problema en si. Recoméndase establecer "/proc/sys/kernel/unprivileged_userns_clone" en 0 para desactivar a montaxe de directorios nun espazo de nomes de ID de usuario separado, e "/proc/sys/kernel/unprivileged_bpf_disabled" en 1 para desactivar a carga de programas eBPF no núcleo.

Cabe destacar que mentres analizaban un ataque alternativo que implicaba o uso do mecanismo FUSE en lugar de bind-mound para montar un directorio grande, os investigadores atoparon outra vulnerabilidade (CVE-2021-33910) que afectaba ao xestor do sistema do sistema. Resultou que ao tentar montar un directorio cun tamaño de ruta superior a 8 MB a través de FUSE, o proceso de inicialización do control (PID1) queda sen memoria de pila e falla, o que pon o sistema nun estado de "pánico".

O problema é que systemd rastrexa e analiza o contido de /proc/self/mountinfo, e procesa cada punto de montaxe na función unit_name_path_escape(), que realiza unha operación strdupa() que coloca os datos na pila e non na memoria asignada de forma dinámica. . Dado que o tamaño máximo da pila está limitado a través de RLIMIT_STACK, o procesamento dunha ruta demasiado grande ata o punto de montaxe fai que o proceso PID1 falle e deteña o sistema. Para un ataque, pode usar o módulo FUSE máis sinxelo en combinación co uso dun directorio altamente aniñado como punto de montaxe, cuxo tamaño de ruta supera os 8 MB.

O problema aparece dende o systemd 220 (abril de 2015), xa foi solucionado no repositorio principal de systemd e solucionado nas distribucións (Debian, Ubuntu, Fedora, RHEL, SUSE, Arch). Notablemente, na versión 248 de systemd o exploit non funciona debido a un erro no código systemd que fai fallar o procesamento de /proc/self/mountinfo. Tamén é interesante que en 2018 xurdiu unha situación similar e ao tentar escribir un exploit para a vulnerabilidade CVE-2018-14634 no núcleo de Linux, os investigadores de Qualys atopáronse con tres vulnerabilidades críticas en systemd.

Fonte: opennet.ru

Engadir un comentario