Skip to content

Latest commit

 

History

History
101 lines (63 loc) · 13.6 KB

TCP SACK PANIC - Уязвимости ядра - CVE-2019-11477, CVE-2019-11478 и CVE-2019-11479.md

File metadata and controls

101 lines (63 loc) · 13.6 KB

TCP SACK PANIC - Уязвимости ядра - CVE-2019-11477, CVE-2019-11478 и CVE-2019-11479

Управляющее резюме

В работе ядра TCP с сетью TCP было обнаружено три связанных недостатка. Самая серьезная уязвимость может позволить удаленному злоумышленнику вызвать панику ядра в системах, на которых работает уязвимое программное обеспечение, и, как следствие, повлиять на работу системы. доступность.

Проблемам было назначено несколько CVE: CVE-2019-11477 считается Важным серьезность, тогда как CVE-2019-11478 и CVE-2019-11479 считаются умеренными серьезностью.

Первые два относятся к пакетам выборочного подтверждения (Selective Acknowledgement -SACK) в сочетании с максимальным размером сегмента (Maximum Segment Size - MSS), третьи - только с максимальным размером сегмента (MSS).

Эти проблемы могут быть исправлены путем применения исправлений или исправлений ядра. Подробные сведения о митигации и ссылки на рекомендации RHSA можно найти на вкладке RESOLVE этой статьи.

Детали и история вопроса

В обработке ядром Linux обработки пакетов выборочного подтверждения TCP (SACK) с низким размером MSS было обнаружено три связанных недостатка. Степень воздействия в настоящее время ограничивается отказом в обслуживании. В настоящее время не ожидается повышения привилегий или утечки информации.

Несмотря на то, что представленные в этой статье смягчения доступны, они могут повлиять на трафик из законных источников, для которых требуется правильная передача более низких значений MSS и производительность системы. Пожалуйста, оцените меры по смягчению, которые подходят для среды системы, прежде чем применять.

Что такое выборочное подтверждение?

Выборочное подтверждение TCP (SACK) - это механизм, в котором получатель данных может информировать отправителя обо всех успешно принятых сегментах. Это позволяет отправителю повторно передавать сегменты потока, отсутствующие в его «известном хорошем» наборе. Когда TCP SACK отключен, для повторной передачи всего потока требуется гораздо больший набор повторных передач.

Что такое MSS?

Максимальный размер сегмента (MSS) - это набор параметров в заголовке TCP пакета, который указывает общий объем данных, содержащихся в восстановленном сегменте TCP. Поскольку пакеты могут стать фрагментированными при передаче по разным маршрутам, хост должен указать MSS как равный наибольшему размеру полезной нагрузки дейтаграммы IP, который может обработать хост. Очень большие размеры MSS могут означать, что поток пакетов в конечном итоге фрагментируется на пути к месту назначения, тогда как меньшие пакеты могут обеспечить меньшую фрагментацию, но в итоге неиспользованные издержки.

Операционные системы и типы транспорта могут по умолчанию указывать размеры MSS. Злоумышленники с привилегированным доступом могут создавать необработанные пакеты с особыми параметрами MSS в пакете для создания этой атаки.

TCP SACKs:

TCP - это протокол, ориентированный на соединение. Когда две стороны хотят установить связь по TCP-соединению, они устанавливают соединение путем обмена определенной информацией, такой как запрос на инициирование (SYN) соединения, начальный порядковый номер, номер подтверждения, максимальный размер сегмента (MSS) для использования по этому соединению, разрешение отправлять и обрабатывать выборочные подтверждения (SACK) и т. д. Этот процесс установления соединения известен как трехстороннее рукопожатие.

TCP отправляет и получает пользовательские данные с помощью блока Segment. Сегмент TCP состоит из заголовка TCP, параметров и пользовательских данных.

TCP Segmentation

Каждый сегмент TCP имеет порядковый номер (SEQ) и номер подтверждения (ACK).

Эти номера SEQ и ACK используются для отслеживания того, какие сегменты были успешно приняты получателем. Номер ACK указывает следующий ожидаемый сегмент получателем.

Пример: пользователь «A» выше отправляет 1 килобайт данных через 13 сегментов по 100 байт каждый, 13, потому что каждый сегмент имеет заголовок TCP размером 20 байт. На принимающей стороне пользователь «B» получает сегменты 1, 2, 4, 6, 8–13, сегменты 3, 5 и 7 теряются, а пользователь «B» не получает их.

Используя номера ACK, пользователь «B» будет указывать, что он ожидает сегмент № 3, который пользователь «A» читает, поскольку ни один из сегментов после того, как 2 не был получен пользователем «B» и пользователь «A» будет повторно передавать все сегменты с 3 и далее, даже если сегменты 4, 6 и 8-13 были успешно получены пользователем «B». Пользователь «B» не имеет возможности указать это пользователю «A». Это приводит к неэффективному использованию сети.

Выборочное подтверждение: SACK

Чтобы преодолеть вышеуказанную проблему, RFC-2018 разработал и определил механизм избирательного подтверждения (SACK). С помощью селективного подтверждения (SACK) пользователь «B» выше использует свое поле параметров TCP для информирования пользователя «A» обо всех сегментах (1,2,4,6,8-13), которые он получил успешно Таким образом, пользователю «А» необходимо повторно передавать только сегменты 3, 5 и 7, тем самым значительно экономя пропускную способность сети и избегая дальнейшей перегрузки.

** CVE-2019-11477 SACK Panic:**
Socket Buffers( SKB ):
Сокетный буфер (SKB) - это самая центральная структура данных, используемая в реализации TCP / IP в Linux. Это связанный список буферов, который содержит сетевые пакеты. Такой список может действовать как очередь передачи, очередь приема, очередь SACK, очередь повторной передачи и т. д. SKB может хранить пакетные данные в виде фрагментов. Linux SKB может содержать до 17 фрагментов.

linux/include/linux/skbuff.h
define MAX_SKB_FRAGS (65536/PAGE_SIZE + 1)  => 17

С каждым фрагментом, хранящим до 32 КБ на x86 (64 КБ на PowerPC) данных. Когда пакет должен быть отправлен, он помещается в очередь отправки, а его детали хранятся в структуре управляющего буфера, например

    linux/include/linux/skbuff.h
struct tcp_skb_cb {
    __u32       seq;                    /* Starting sequence number */
    __u32       end_seq;    /* SEQ + FIN + SYN + datalen */
    __u32       tcp_tw_isn;
        struct {
                u16 tcp_gso_segs;
                u16 tcp_gso_size; 
        };
    __u8        tcp_flags;  /2* TCP header flags. (tcp[13])  */
    …
}

Из них поля tcp_gso_segs и **tcp_gso_size ** используются для информирования драйвера устройства о разгрузке сегментации.

Когда разгрузка сегментации включена и механизм SACK также включен из-за потери пакетов и выборочной повторной передачи некоторых пакетов, SKB может в конечном итоге удерживать несколько пакетов, считая как tcp_gso_segs. Несколько таких SKB в списке объединяются в один для эффективной обработки различных блоков SACK. Это включает перемещение данных из одного SKB в другой в списке. Во время этого перемещения данных структура SKB может достичь своего максимального предела в 17 фрагментов, а параметр tcp_gso_segs может переполниться и выполнить приведенный ниже вызов BUG_ON(), что приведет к проблеме паники ядра.

static bool tcp_shifted_skb (struct sock *sk, …, unsigned int pcount, ...)
{
...
tcp_skb_pcount_add(prev, pcount);
BUG_ON(tcp_skb_pcount(skb) < pcount);   <= SACK panic
tcp_skb_pcount_add(skb, -pcount);

}

Удаленный пользователь может вызвать эту проблему, установив Максимальный размер сегмента (MSS) TCP-соединения на его минимальный предел в 48 байтов и отправив последовательность специально созданных пакетов SACK. Самый низкий MSS оставляет только 8 байтов данных на сегмент, таким образом увеличивая количество сегментов TCP, необходимых для отправки всех данных.

Подтверждения

Джонатан Луни (Информационная безопасность Netflix)

Рекомендации

RFC-2018 - TCP selective acknowledgments  
How SKB’s work

Netflix (reporters) original report.


уязвимости