Use-after-free in Linux kernel's netfilter: nf_tables component
Prioriza la corrección. Ella está bajo explotación confirmada por CISA y tiene prueba de concepto pública.
Apply mitigations per vendor instructions or discontinue use of the product if mitigations are unavailable.
Resumen
Use-after-free (double-free) no subsistema netfilter/nf_tables do kernel Linux, explorável por usuário local sem privilégios para escalar a root. A falha existe desde 2014 mas só ganhou atenção em 2024, quando um PoC público e confiável (>99% de sucesso em imagens KernelCTF) foi divulgado, forçando entrada no catálogo KEV da CISA. O impacto é alto onde existem usuários locais não confiáveis (multi-tenant, containers, shells compartilhados) e onde user namespaces sem privilégio estão habilitados — que é a configuração padrão em Debian e Ubuntu.
Detalle técnico
A função nft_verdict_init(), que interpreta o veredito retornado por uma regra nf_tables, aceita valores positivos como 'drop error' dentro do veredito NF_DROP. O problema é que esses valores positivos coincidem com o espaço de valores usado por NF_ACCEPT em nf_hook_slow(). Quando um veredito NF_DROP chega com um drop error que se parece com NF_ACCEPT, nf_hook_slow() interpreta o pacote como aceito ao invés de descartado, liberando (kfree) uma estrutura relacionada ao pacote que já havia sido — ou vai ser — liberada em outro caminho. O resultado é um double-free / use-after-free (CWE-416) em memória do kernel.
Cómo se explota
O double-free por si só permite corromper heap do kernel. O exploit público (Notselwyn, 'Flipping Pages') transforma essa corrupção em escalonamento de privilégio usando técnicas de heap grooming e uma técnica batizada 'Dirty Pagedirectory', substituindo o objeto liberado por estruturas controladas pelo atacante até obter escrita arbitrária em memória do kernel e, a partir daí, um shell root.
Pré-requisitos reais: o atacante precisa de acesso local (shell) na máquina, capacidade de criar um user namespace sem privilégio (CONFIG_USER_NS=y e kernel.unprivileged_userns_clone=1 ou equivalente) e nf_tables habilitado no kernel (CONFIG_NF_TABLES=y). Como o veredito é avaliado dentro do hook de rede, o atacante também precisa de CAP_NET_ADMIN dentro de um namespace — daí a dependência combinada de user namespace e network namespace, não apenas do módulo nf_tables. Em Debian, Ubuntu e imagens KernelCTF essas condições vêm ativadas por padrão; em kernels ≥6.4 com CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y (caso de Ubuntu 6.5) o exploit publicado deixa de funcionar sem adaptação. O código público só foi testado em x86_64.
A CISA confirma exploração ativa e o exploit deliberadamente causa kernel panic ao final da execução — efeito colateral que o autor manteve de propósito para tornar tentativas de uso mais visíveis/impraticáveis fora de laboratório, mas que não elimina o risco em ambientes onde reinicializações não são monitoradas.
Versiones
Cómo protegerse
A correção definitiva é atualizar o kernel para uma versão que inclua o commit f342de4e2f33e0e39165d8639387aa6c19dff660, retroportado para os ramos estáveis v5.15.149, v6.1.76 e v6.6.15 (fevereiro de 2024). Distribuições com seus próprios ramos de kernel (RHEL/derivados, Debian, Ubuntu, Fedora) publicaram pacotes próprios com o backport — confira o advisory de cada distribuição, pois versões numeradas variam por distro. Em abril de 2024, RHEL 9.3 (e a maioria dos rebuilds) ainda não tinha o patch, segundo relato em oss-security.
Se atualizar o kernel não for viável imediatamente: (1) bloquear o carregamento do módulo nf_tables se ele não for usado (blacklist); (2) desabilitar user namespaces sem privilégio — em Debian/Ubuntu via sysctl kernel.unprivileged_userns_clone=0, em outras distros via user.max_user_namespaces=0, sabendo que isso impede containers mesmo para root; (3) mitigação mais seletiva discutida em oss-security: desabilitar apenas network namespaces via sysctl user.max_net_namespaces=0, já que o exploit depende de CAP_NET_ADMIN dentro de um namespace de rede — isso preserva user namespaces (containers continuam funcionando) mas quebra recursos que dependem de namespace de rede próprio (parte do Apptainer, opções --net de runtimes, systemd PrivateNetwork); (4) carregar um kpatch de terceiros específico para AlmaLinux/RHEL (não oficial do fornecedor) ou usar LKRG, que não impede a exploração mas interrompe o exploit publicado no estágio final, deixando o sistema instável em vez de comprometido. Nenhuma dessas medidas substitui o patch do kernel; são paliativos com custo funcional real (perda de containers, de isolamento de rede, ou de estabilidade).
Cómo detectar
Não há assinatura de rede ou log de aplicação confiável, pois a exploração é inteiramente local e ocorre dentro do kernel via chamadas de sistema para criação de user namespace e manipulação de regras nf_tables. O sinal mais prático é indireto: o exploit público causa kernel panic (crash) como efeito colateral deliberado ao final da execução — quedas inesperadas do sistema após atividade de um usuário local não privilegiado, especialmente correlacionadas com criação de namespaces ou carregamento de regras nf_tables, merecem investigação. Ferramentas de auditoria que monitoram unshare()/clone() com CLONE_NEWUSER e CLONE_NEWNET, ou uso anômalo de nftables por processos sem necessidade administrativa, podem ajudar, mas não existe IOC estático publicado para essa CVE.