Статья Как Mozilla упустила (не)очевидную уязвимость

Admin

Администратор

Как Mozilla упустила (не)очевидную уязвимость​

В 2021 году всем хорошим багам нужно цепляющее название, и у этой уязвимости появилось имя BigSig. Сначала объясню, как она нашлась, а затем попытаюсь понять, почему её так долго упускали.

Анализ​

Network Security Services (NSS) — популярная кросс-платформенная криптографическая библиотека от Mozilla. Когда проверяется зашифрованная цифровая подпись ASN.1, в NSS создаётся структура VFYContext для хранения необходимых данных — открытого ключа, хеш-алгоритма и самой подписи.
Код:
struct VFYContextStr {
   SECOidTag hashAlg; /* the hash algorithm */
   SECKEYPublicKey *key;
   union {
       unsigned char buffer[1];
       unsigned char dsasig[DSA_MAX_SIGNATURE_LEN];
       unsigned char ecdsasig[2 * MAX_ECKEY_LEN];
       unsigned char rsasig[(RSA_MAX_MODULUS_BITS + 7) / 8];
   } u;
   unsigned int pkcs1RSADigestInfoLen;
   unsigned char *pkcs1RSADigestInfo;
   void *wincx;
   void *hashcx;
   const SECHashObject *hashobj;
   SECOidTag encAlg;    /* enc alg */
   PRBool hasSignature;
   SECItem *params;
};
Структура VFYContext из NSS

Сигнатура максимального размера, которую обрабатывает эта структура, равна наибольшему элементу объединения, здесь это RSA в 2048 байтов, то есть 16 384 бита. Это достаточно много, чтобы вместить сигнатуры даже невероятно больших ключей. А что, если сделать сигнатуру больше этой? Произойдёт повреждение памяти. Да, так есть. Ненадёжная сигнатура просто копируется в этот буфер фиксированного размера, перезаписывая соседние элементы произвольными данными, которые контролируются злоумышленником.

Баг прост в воспроизведении и влияет на несколько алгоритмов. Проще всего показать RSA-PSS:
Код:
# We need 16384 bits to fill the buffer, then 32 + 64 + 64 + 64 bits to overflow to hashobj,
# which contains function pointers (bigger would work too, but takes longer to generate).
$ openssl genpkey -algorithm rsa-pss -pkeyopt rsa_keygen_bits:$((16384 + 32 + 64 + 64 + 64)) -pkeyopt rsa_keygen_primes:5 -out bigsig.key
# Generate a self-signed certificate from that key
$ openssl req -x509 -new -key bigsig.key -subj "/CN=BigSig" -sha256 -out bigsig.cer
# Verify it with NSS...
$ vfychain -a bigsig.cer
Уязвимость BigSig за три простых команд

Код, который вызывает повреждение, зависит от алгоритма. Вот код для RSA-PSS. Баг заключается в том, что проверки границ просто нет вообще: sig и key — это большие двоичные объекты произвольной длины, контролируемые злоумышленником, а cx->u — это буфер фиксированного размера:
Код:
case rsaPssKey:
               sigLen = SECKEY_SignatureLen(key);
               if (sigLen == 0) {
                   /* error set by SECKEY_SignatureLen */
                   rv = SECFailure;
                   break;
               }

               if (sig->len != sigLen) {
                   PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
                   rv = SECFailure;
                   break;
               }

               PORT_Memcpy(cx->u.buffer, sig->data, sigLen);
               break;
Уязвимость вызывает ряд вопросов:
  • Связана ли она с недавним изменением кода или это регрессия, которая проявилась только сейчас? Нет, исходный код был проверен поддержкой ECC 17 октября 2003 года, но его нельзя было использовать до рефакторинга, проведённого в июне 2012 года. В 2017 году была добавили поддержка RSA-PSS, при этом допустили ту же ошибку.
  • Много ли времени требуется, чтобы сгенерировать ключ, который вызывает баг? Нет, в приведённом примере генерируются реальный ключ и сигнатура, но это может быть мусор: переполнение происходит до проверки сигнатуры. Несколько килобайтов символа А работают без проблем.
  • Требуется ли для доступа к уязвимому коду сложное состояние, с которым у техник тестирования и статических анализаторов были бы трудности при синтезе, например хеши или контрольные суммы? Нет, должен быть правильный DER, вот и всё.
  • Уязвимости трудно достичь в смысле кода? Нет, в Firefox этот путь кода не используется для сигнатур RSA-PSS, но точка входа по умолчанию для проверки сертификата в NSS — CERT_VerifyCertificate() — уязвима.
  • Она характерна исключительно для алгоритма RSA-PSS? Нет, она влияет и на сигнатуры DSA.
  • Этой уязвимостью нельзя воспользоваться или же она имеет ограниченное воздействие? Нет, может быть затёрт элемент hashobj. Этот объект содержит указатели функции, которые сразу же используются.
Это не сбой процесса: вендор всё сделал правильно. В Mozilla работают специалисты мирового класса по обеспечению безопасности. Они первыми внедрили программу вознаграждений за обнаруженные уязвимости, вкладываются в обеспечение безопасной работы с памятью, автоматизацию тестирования безопасности и покрытие кода тестами.

NSS был одним из первых проектов, включённых в oss-fuzz: по крайней мере поддерживался официально с октября 2014 года. В Mozilla сами также проводят автоматизацию тестирования безопасности NSS с помощью libFuzzer и представили собственную коллекцию методов-модификаторов, а также основу корпуса покрытия. Есть обширный тестовый комплект и ночные сборки ASAN.

Я в общем скептически отношусь к статическому анализу, но это похоже на простую недостающую проверку границ, которую должно быть легко найти. Coverity отслеживает NSS по крайней мере с декабря 2008 года и тоже, кажется, не смогла обнаружить уязвимость.

До 2015 года в Google Chrome использовали NSS и поддерживали собственную инфраструктуру тестового комплекта и автоматизации тестирования безопасности, независимую от Mozilla. Сегодня в платформах Chrome используется BoringSSL, но порт NSS ещё поддерживается.
  • Было ли в Mozilla хорошее тестовое покрытие уязвимых областей? Да.
  • Были ли в корпусе автоматизации тестирования безопасности Mozilla / Chrome / oss-fuzz соответствующие входные данные? Да.
  • Есть ли метод-модификатор, способный расширить эти ASN1_ITEM? Да.
  • Является ли это внутриобъектным переполнением или другой формой повреждения, которую ASAN было бы трудно обнаружить? Нет, это классическое переполнение буфера, которое ASAN может обнаружить легко.

Как я нашёл баг?​

Экспериментировал с альтернативными методами измерения покрытия кода, чтобы узнать, можно ли их как-то использовать на практике в автоматизации тестирования безопасности. В технике тестирования, с помощью которой удалось обнаружить эту уязвимость, применялось сочетание двух подходов: покрытие стека и выделение объектов.

Покрытие стека​

Самый распространённый метод измерения покрытия кода — покрытие блоков или покрытие границ, когда доступен исходный код. Интересно, всегда ли этого достаточно? Например, возьмём простую таблицу диспетчеризации с сочетанием надёжных и ненадёжных параметров, как показано в листинге:
Код:
#include <stdio.h>
#include <string.h>
#include <limits.h>
 
static char buf[128];
 
void cmd_handler_foo(int a, size_t b) { memset(buf, a, b); }
void cmd_handler_bar(int a, size_t b) { cmd_handler_foo('A', sizeof buf); }
void cmd_handler_baz(int a, size_t b) { cmd_handler_bar(a, sizeof buf); }
 
typedef void (* dispatch_t)(int, size_t);
 
dispatch_t handlers[UCHAR_MAX] = {
    cmd_handler_foo,
    cmd_handler_bar,
    cmd_handler_baz,
};
 
int main(int argc, char **argv)
{
    int cmd;
 
    while ((cmd = getchar()) != EOF) {
        if (handlers[cmd]) {
            handlers[cmd](getchar(), getchar());
        }
    }
}
Покрытие команды bar — это надмножество команды foo, поэтому ввод, содержащий foo, будет отброшен при минимизации корпуса. Есть уязвимость, недоступная через команду bar, которая может быть не обнаружена никогда. Покрытие стека корректно сохранит оба ввода1.

Чтобы решить эту проблему, я отслеживал стек вызовов во время выполнения.

Наивная реализация слишком медленная, но после многих оптимизаций я создал практичную библиотеку, достаточно быструю, чтобы интегрировать её в автоматизацию тестирования безопасности, ориентированную на покрытие. Я тестировал, как она работает с NSS и другими библиотеками.

Выделение объектов​

Многие типы данных создаются из записей меньшего размера. Файлы PNG состоят из фрагментов, файлы PDF — из потоков, файлы ELF — из разделов, а сертификаты X.509 — из элементов ASN.1 TLV. Если в технике тестирования заложено представление о базовом формате, то с её помощью можно выделить эти записи и извлечь те, что приводят к обнаружению новой трассировки стека.

Техника тестирования, которую я использовал, способна выделять и извлекать интересные новые идентификаторы объекта ASN.1, последовательности SEQUENCE, целые числа INTEGER и т. д. После извлечения они могут случайным образом комбинироваться или вставляться в данные шаблона. На самом деле идея не новая, новая — реализация. Планирую в будущем сделать этот код общедоступным.

Работают ли эти подходы?​

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

Что в итоге?​

Как обширная, настраиваемая автоматизация тестирования безопасности с впечатляющими показателями покрытия не выявила этот баг?

Что пошло не так?​

1. Нет сквозного тестирования​

NSS — модульная библиотека. Многоуровневый дизайн отражён в подходе автоматизации тестирования безопасности, ведь каждый компонент тестируется независимо. Например, декодер QuickDER проходит расширенное тестирование, но при использовании техники тестирования объекты просто создаются, отбрасываются и никогда не используются:
Код:
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
char *dest[2048];

for (auto tpl : templates) {
PORTCheapArenaPool pool;
SECItem buf = {siBuffer, const_cast<unsigned char *>(Data),
static_cast<unsigned int>(Size)};

PORT_InitCheapArena(&pool, DER_DEFAULT_CHUNKSIZE);
(void)SEC_QuickDERDecodeItem(&pool.arena, dest, tpl, &buf);
PORT_DestroyCheapArena(&pool);
}
При использовании техники тестирования QuickDER объекты просто создаются и отбрасываются. Так проверяется синтаксический анализ ASN.1, но не корректность работы с получаемыми объектами других компонентов.
С этой техникой тестирования можно было создать SECKEYPublicKey, который бы достал в уязвимый код. Но баг так и не был бы обнаружен, ведь результат никогда не использовался для проверки сигнатуры.

2. Произвольные ограничения по размеру​

Для ввода автоматизированного тестирования задаётся произвольное ограничение в 10 000 байтов. В NSS такого ограничения нет: у многих структур этот размер возможно превысить. В случае с этой уязвимостью ошибки происходят на границах, поэтому ограничение следует выбирать с умом.
Приемлемым вариантом может быть 224–1 байтов, т. е. максимально возможный сертификат, предоставляемый сервером во время согласования рукопожатия TLS.
Хотя в NSS обрабатываются объекты даже большего размера, TLS задействовать нельзя, а это снижает общую степень серьёзности любых пропущенных уязвимостей.

3. Метрики и заблуждения​

Все техники тестирования NSS представлены в объединённых показателях покрытия oss-fuzz, а не в их индивидуальных покрытиях. Эти данные оказались неверными, так как уязвимый код проходит расширенное автоматизированное тестирование, но с помощью техник тестирования, которые не могли генерировать соответствующие входные данные.
Почему? Потому что в техниках тестирования типа tls_server_target используются фиксированные, жёстко заданные сертификаты. При этом выполняется код, относящийся к проверке сертификата, но проводится автоматизированное тестирование лишь сообщений TLS и изменений состояния протокола.

Что всё-таки сработало?​

  • Благодаря дизайну библиотеки проверки корректности сертификатов mozilla::pkix не было допущено ухудшение ситуации с этим багом. К сожалению, она не используется вне Firefox и Thunderbird.
Сложно сказать, удача это или нет. Вероятно, RSA-PSS в mozilla::pkix будет разрешён.

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

Эта проблема свидетельствует о том, что даже в очень хорошо поддерживаемом C/C++ могут быть фатальные, простейшие ошибки.

Краткосрочные рекомендации​

  • Увеличить максимальный размер объектов ASN.1, создаваемых с помощью libFuzzer, с 10 000 до 224–1 = 16 777 215 байтов.
  • При использовании техники тестирования QuickDER должны вызываться соответствующие API с любыми успешно созданными объектами, прежде чем они будут уничтожены.
  • Показатели покрытия кода oss-fuzz нужно разделить по технике тестирования, а не по проекту.

Решение​

Эта уязвимость, CVE-2021-43527, закрыта в NSS 3.73.0. Если вы вендор, распространяющий NSS в своих продуктах, то вам, скорее всего, потребуется заменить библиотеку или применить патч.
 
Похожие темы
Admin Интересно ДНК эмбриона теперь можно редактировать как опечатку в документе. Новости в сети 0
Admin Интересно Историки опровергли роль Томаса Эдисона как отца звукозаписи. Новости в сети 0
Admin Интересно Приёмник смотрит вправо, а удар прилетел слева. Как физика из школьного двора ломает радиозащиту. Новости в сети 0
Admin Интересно Узнайте, как злоумышленники видят вашу сеть: вебинар с HD Moore. Новости в сети 0
Admin Интересно Скидки-оборотни: как бонусные баллы превращаются в инструмент мошенничества. Новости в сети 0
Admin Интересно Искусственный интеллект сокращает временные рамки эксплуатации уязвимостей. Как с этим справиться?. Новости в сети 0
Admin Интересно Тест-драйв: как избавиться от сомнений в выборе ИБ-решения за 7 дней. Новости в сети 0
Admin Интересно Как управлять скрытыми ИИ-инструментами без замедления работы сотрудников. Новости в сети 0
Admin Интересно Ошибка из 2018 и подставные аккаунты. Рассказываем, как популярный пакет art-template начал атаковать айфоны. Новости в сети 0
Admin Интересно Сотрудник ушёл, а доступ остался. Как забытая учётка открыла хакерам путь к водоснабжению целого города. Новости в сети 0
Admin Интересно Роботы научились двигаться как живая материя. Новости в сети 0
Admin Интересно Идентификация как основной вектор атак в современных системах безопасности. Новости в сети 0
Admin Интересно Студенты возмущены после того, как ИИ пропустил сотни имён на выпускной церемонии. Новости в сети 0
Admin Интересно Как небольшая группа пользователей может ухудшить рекомендации в TikTok. Новости в сети 0
Admin Интересно Как небольшая группа пользователей может испортить рекомендации на TikTok. Новости в сети 0
Admin Интересно Как снизить риск фишинга до того, как он приведёт к сбоям в бизнесе. Новости в сети 0
Admin Интересно Как автоматизация ИБ закрывает угрозы без рутины. Новости в сети 0
Admin Интересно VPN, просевший трафик и минус 7 млрд руб. Как новые требования Минцифры ударили по маркетплейсам. Новости в сети 0
Admin Интересно Как анализ собственных инструментов помогает снизить риски кибератак. Новости в сети 0
Admin Интересно Практический вебинар: Как PT NGFW защищает от атак в реальном времени. Новости в сети 0
Admin Интересно ИИ уходит на дно: плавучие серверы в океане как новый этап развития технологий. Новости в сети 0
Admin Интересно Мы искали инопланетян не там? Жизнь прячется не в молекулах, а в том, как они организованы. Новости в сети 0
Admin Интересно Как спрятать секрет с помощью недоказуемой математики? Учёный обошёл 30-летний запрет в криптографии. Новости в сети 0
Admin Интересно Anthropic рассказала, как отучила искусственный интеллект угрожать людям. Новости в сети 0
Admin Интересно Безопасность КИИ: что изменилось и как выстроить защиту. Новости в сети 0
Admin Интересно Звездные каннибалы и космические ДТП. Как во Вселенной появляются самые тяжелые черные дыры. Новости в сети 0
Admin Интересно Азбука Морзе, Grok и $200 000: как один пост в X заставил ИИ-агента перевести токены. Новости в сети 0
Admin Интересно ФБР также читает чаты. Как переписка в мессенджере стоила хакеру восьми лет свободы. Новости в сети 0
Admin Интересно Защита или цензура? История о том, как Касперский стал личным Роскомнадзором на MacBook. Новости в сети 0
Admin Интересно Первый удар по VPN в США: как Юта хочет запретить анонимность, не имея на это технических средств. Новости в сети 0
Admin Интересно Исследователь показал, как отследить австралийских полицейских через Bluetooth. Новости в сети 0
Admin Интересно Галактике 400 миллионов лет, но она выглядит на миллиарды. Уэбб нашёл невозможного красного монстра — и астрономы не понимают, как он успел повзрослет Новости в сети 0
Admin Интересно Целились в Starlink — попали в iPhone. Как новый запрет на спутниковое оборудование создал правовую неопределённость для всего рынка смартфонов. Новости в сети 0
Admin Интересно СМС, которую вы никогда не прочитаете. Как спецслужбы находят «важных персон» за пару часов. Новости в сети 0
Admin Интересно Скафандры не готовы, Луна ждёт. Как бюрократия срывает планы NASA вернуться на Луну. Новости в сети 0
Admin Интересно ИИ врёт так же, как раньше. Но теперь он делает это мило — и вы ему доверяете. Новости в сети 0
Admin Интересно Азартные игры, долги и переписка двух гениев. Как ссора из-за 100 долларов создала современную математику. Новости в сети 0
Admin Интересно Приключения казаха в южнокорейских сетях. Как жадность довела взломщика до тюрьмы. Новости в сети 0
Admin Интересно Что скрыто за вымогательством: как работает индустрия ransomware. Новости в сети 0
Admin Интересно Режиссёры защищают использование ИИ для воссоздания Вэла Килмера в новом фильме как «этичное». Новости в сети 0
Admin Интересно Частица, которая спасла бы физику. Стерильное нейтрино искали 30 лет — как жаль, что оно оказалось миражом. Новости в сети 0
Admin Интересно Вашему RDP поставили «лайк». История о том, как горстка серверов прочесала Интернет и нашла все изъяны. Новости в сети 0
Admin Интересно Русские хакеры против картошки фри. Как взлом кассы самообслуживания обернулся годом условно. Новости в сети 0
Admin Интересно Тройная порция шантажа под соусом анонимности. Как одна банда притворяется сразу тремя разными группировками. Новости в сети 0
Admin Интересно Как соседей России заставляют выбирать между Европой и личным спокойствием. Новости в сети 0
Admin Интересно Позвони мне через пылесос. Как выживает рунет после блокировки мессенджеров. Новости в сети 0
Admin Интересно Ускоритель частиц размером с карандаш. Мощность — как у километрового. И это работает. Новости в сети 0
Admin Интересно Война правок и логотипов: Как Euro-Office поссорился с ONLYOFFICE из-за лицензии. Новости в сети 0
Admin Интересно Цифры врали. Не специально — просто их сложили неправильно. Вот как парадокс Симпсона ломает статистику. Новости в сети 0
Admin Интересно Цифровые активы после смерти: как управлять рисками для цифрового наследства. Новости в сети 0

Название темы