FlawOpen

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

● CVE-2024-1086 · CVSS 7.8 · Высокий
Исследования · FlawOpen

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

CVE-2024-1086 — use-after-free в Linux nf_tables из-за принятия неверных параметров DROP. Установите исправленное ядро из вашей дистрибуции.

💡 Простыми словами (ELI5)

Представьте форму, где сотрудник может выбрать только «принять» или «отбросить». В отдельном поле указывается код ошибки для отказа: там допустимы ноль или корректная отрицательная ошибка. Уязвимая проверка пропускала положительное значение «принять» в это поле. Позже сетевой код трактовал вердикт непоследовательно. Исправление закрывает этот путь и принимает только точные поддерживаемые значения.

Ключевые понятия и термины

nf_tables
Подсистема ядра Linux, которую nftables использует для настройки фильтрации пакетов и связанных сетевых правил.
Вердикт Netfilter
Результат обработки правила пакета в ядре, например NF_ACCEPT или NF_DROP. Для DROP hook ожидает ноль или корректный отрицательный errno.
Use-after-free (CWE-416)
Ошибка памяти, при которой код обращается к объекту после завершения его срока жизни. NVD указывает здесь локальное повышение привилегий в ядре.
User namespace
Пространство имён Linux, сопоставляющее идентификаторы и полномочия процессов. Возможность его создания без привилегий зависит от политики ядра и дистрибутива; сама по себе она не означает выход на хост.

Связи со стандартами

Анализ первопричины

В net/netfilter/nf_tables_api.c функция nft_verdict_init() раньше маскировала значение вердикта и принимала параметры для NF_DROP или NF_QUEUE. Хук Netfilter ожидает в старших битах NF_DROP ноль или корректный отрицательный errno. Согласно upstream-исправлению, положительное значение, например NF_ACCEPT, могло привести к use-after-free. Патч удаляет разрешающий путь и принимает только точные поддерживаемые вердикты; остальные значения возвращают -EINVAL. NVD указывает на локальное повышение привилегий. Возможность атаки зависит от ядра, доступных полномочий и политики дистрибутива; не следует считать все контейнеры одинаково уязвимыми.

Пошаговый сценарий атаки

Шаг 1

Локальная возможность управлять правилами

Описанная атака локальная. Процесс должен иметь доступ к проверке вердиктов nf_tables; необходимые полномочия и доступность непривилегированных user namespace зависят от настроек хоста.

Шаг 2

Неверный параметр вердикта проходит проверку

До исправления nft_verdict_init() принимала некоторые значения после применения NF_VERDICT_MASK, включая положительное NF_ACCEPT в битах параметра.

Шаг 3

Хук доходит до use-after-free

Хук Netfilter трактует параметры NF_DROP как ноль или допустимый отрицательный errno. В upstream-отчёте сказано, что принятый положительный параметр может вызвать use-after-free при обработке пакета; патч не подтверждает универсальную примитиву эксплуатации или гарантированный выход из контейнера.

Шаг 4

Установите исправленное ядро дистрибутива

Upstream-изменение отклоняет неподдерживаемые параметры вердикта. Установите и загрузите исправленное ядро, предоставленное дистрибутивом: версии пакетов и переносы исправления различаются.

Исходный код: Уязвимый vs Защищённый вариант

Уязвимый код маскировал вердикт и переходил к дальнейшей обработке, поэтому параметр вроде положительного NF_ACCEPT мог попасть в поле ошибки NF_DROP. Исправление допускает только точные константы и возвращает -EINVAL для остальных значений. Это целевые фрагменты upstream-патча, а не автономные компилируемые функции.

Фрагмент исходного кода: net/netfilter/nf_tables_api.c

УЯЗВИМАЯ РЕАЛИЗАЦИЯ
/* Фрагмент nft_verdict_init() в net/netfilter/nf_tables_api.c до f342de4e2f33.
 * Путь с маскированным значением принимал параметризованные вердикты. */
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:
    /* Далее следует обработка остальных существующих вердиктов. */
    break;
}
БЕЗОПАСНЫЙ ИСПРАВЛЕННЫЙ ВАРИАНТ
/* Фрагмент nft_verdict_init() в net/netfilter/nf_tables_api.c,
 * изменённый в f342de4e2f33. */
switch (data->verdict.code) {
case NF_ACCEPT:
case NF_DROP:
case NF_QUEUE:
    break;
case NFT_CONTINUE:
case NFT_BREAK:
case NFT_RETURN:
    /* Далее следует обработка остальных существующих вердиктов. */
    break;
default:
    return -EINVAL;
}

Чек-лист по защите системы для инженеров

Источники