FlawOpen

flawopen.com/Teardowns/cve-2024-1086-linux-netfilter-nftables-uaf

● CVE-2024-1086 · CVSS 7.8 · Alta
Investigación · FlawOpen

CVE-2024-1086: use-after-free en Linux nf_tables

CVE-2024-1086 es un use-after-free en nf_tables de Linux por parámetros DROP no válidos. Instala el kernel corregido de tu distribución.

💡 Explicación en Lenguaje Sencillo (ELI5)

Imagina un formulario donde el empleado solo puede elegir “aceptar” o “descartar”. También hay un campo para el código de error del descarte, que admite cero o un error negativo válido. El validador vulnerable dejó pasar el valor positivo “aceptar” en ese campo. Después, el código de red interpretaba el veredicto de forma incoherente. El parche cierra esa entrada y acepta solo los veredictos exactos permitidos.

Conceptos Clave y Términos

nf_tables
Subsistema del kernel Linux que nftables utiliza para configurar el filtrado de paquetes y otras reglas de red.
Veredicto de Netfilter
Resultado de evaluar una regla de paquetes, como NF_ACCEPT o NF_DROP. Un veredicto DROP puede llevar un valor de error que el hook espera que sea cero o un errno negativo válido.
Use-after-free (CWE-416)
Fallo de memoria en el que el código accede a un objeto después de terminar su vida útil. NVD registra aquí una vulnerabilidad local de elevación de privilegios del kernel.
User namespace
Namespace de Linux que asigna identidades y capacidades a procesos. Que un usuario sin privilegios pueda crearlo depende de la política del kernel y de la distribución; no garantiza escapar al host.

Mapeos de marcos

Análisis de Causa Raíz

En net/netfilter/nf_tables_api.c, nft_verdict_init() aplicaba una máscara al veredicto y permitía parámetros para NF_DROP o NF_QUEUE. El hook de Netfilter espera que los bits superiores de un veredicto NF_DROP contengan cero o un errno negativo válido. La corrección upstream indica que un valor positivo como NF_ACCEPT podía causar un use-after-free. El parche elimina la ruta permisiva y acepta únicamente los veredictos exactos; los demás valores devuelven -EINVAL. NVD clasifica el impacto como elevación local de privilegios. La posibilidad de explotación depende del kernel, las capacidades disponibles y la política de la distribución; no des por hecho que todos los contenedores tengan el mismo riesgo.

Flujo de Ataque Paso a Paso

Paso 1

Capacidad local para gestionar reglas

El ataque documentado es local. El proceso debe alcanzar la validación de veredictos de nf_tables; las capacidades necesarias y la disponibilidad de user namespaces sin privilegios dependen de la configuración del host.

Paso 2

Un parámetro de veredicto inválido llega a la validación

Antes del parche, nft_verdict_init() aceptaba ciertos valores con parámetros tras aplicar NF_VERDICT_MASK, incluido un valor positivo como NF_ACCEPT en los bits del parámetro.

Paso 3

El hook alcanza el use-after-free

El hook de Netfilter interpreta los parámetros de NF_DROP como cero o un errno negativo válido. El informe upstream indica que el valor positivo aceptado puede causar un use-after-free durante el procesamiento de paquetes; el parche no documenta una primitiva universal ni una salida garantizada del contenedor.

Paso 4

Instala el kernel corregido de la distribución

El cambio upstream rechaza los parámetros no admitidos. Instala e inicia el kernel corregido de tu distribución, ya que los paquetes y backports varían.

Código Fuente: Vulnerable vs. Seguro

El código vulnerable aplicaba una máscara al veredicto y continuaba, por lo que admitía valores parametrizados como NF_ACCEPT positivo en el campo de error de NF_DROP. La corrección admite solo constantes exactas y devuelve -EINVAL para cualquier otro valor. Son extractos concretos del parche upstream, no funciones independientes compilables.

Fragmento de origen: net/netfilter/nf_tables_api.c

IMPLEMENTACIÓN VULNERABLE
/* Fragmento de nft_verdict_init() en net/netfilter/nf_tables_api.c, antes de f342de4e2f33.
 * La ruta de valor enmascarado aceptaba veredictos parametrizados. */
switch (data->verdict.code) {
default:
    switch (data->verdict.code & NF_VERDICT_MASK) {
    case NF_ACCEPT:
    case NF_DROP:
    case NF_QUEUE:
        break;
    default:
        return -EINVAL;
    }
    fallthrough;
case NFT_CONTINUE:
case NFT_BREAK:
case NFT_RETURN:
    /* A continuación se procesa el resto de los veredictos existentes. */
    break;
}
PARCHE SEGURO Y ROBUSTO
/* Fragmento de nft_verdict_init() en net/netfilter/nf_tables_api.c,
 * según el cambio f342de4e2f33. */
switch (data->verdict.code) {
case NF_ACCEPT:
case NF_DROP:
case NF_QUEUE:
    break;
case NFT_CONTINUE:
case NFT_BREAK:
case NFT_RETURN:
    /* A continuación se procesa el resto de los veredictos existentes. */
    break;
default:
    return -EINVAL;
}

Lista de Verificación de Seguridad para Ingeniería

Fuentes