Серьезная безопасность: GnuTLS следует за OpenSSL, исправляет ошибку атаки по времени

Серьезная безопасность: GnuTLS следует за OpenSSL, исправляет ошибку атаки по времени

Исходный узел: 1956368

На прошлой неделе мы писали о множестве ошибки управления памятью которые были исправлены в последнем обновлении безопасности популярной библиотеки шифрования OpenSSL.

Наряду с этими ошибками памяти, мы также сообщили об ошибке, получившей название CVE-2022-4304: Синхронизация Oracle в расшифровке RSA.

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

… не будет занимать постоянное количество времени, если предположить, что вы находитесь близко к цели в сети, и вы можете достоверно предположить, сколько времени займет часть процесса передачи данных.

Не все данные обрабатываются одинаково

Если вы отправляете запрос, определяете, сколько времени занимает ответ, и вычитаете время, затраченное на низкоуровневую отправку и получение сетевых данных, вы знаете, сколько времени потребовалось серверу для выполнения внутренних вычислений для обработки запроса. .

Даже если вы не уверены, сколько времени израсходовано в сети, вы можете найти различия во времени приема-передачи, отправив множество запросов и собрав множество образцов.

Если сеть достаточно надежна, чтобы предположить, что сетевые накладные расходы в значительной степени постоянны, вы можете использовать статистические методы, чтобы сделать вывод, какое изменение данных вызывает какую дополнительную задержку обработки.

Из этого вы можете сделать вывод о структуре или даже содержании исходных незашифрованных данных, которые должны храниться в секрете при каждом повторном запросе.

Даже если вы можете извлечь только один байт открытого текста, этого не должно произойти.

Так называемые время атаки такого рода всегда неприятны, даже если вам может понадобиться отправить миллионы фиктивных пакетов и рассчитать время их всех, чтобы иметь шанс восстановить хотя бы один байт данных в виде открытого текста…

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

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

Но «миллион пакетов в час больше или меньше, чем обычно» просто больше не является особенно большим разбросом.

Похожая ошибка «оракула» в GnuTLS

Что ж, тот же человек, который сообщил об ошибке времени fix-at-last в OpenSSL, также сообщил о похожая ошибка в GnuTLS примерно в то же время.

У этого есть идентификатор ошибки CVE-2023-0361.

Хотя GnuTLS не так популярен или широко используется, как OpenSSL, у вас, вероятно, есть ряд программ в вашей ИТ-инфраструктуре или даже на вашем собственном компьютере, которые используют или включают его, возможно, включая FFmpeg, GnuPG, Mplayer, QEMU. , Rdesktop, Samba, Wget и Wireshark.

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

Как видно из разницы кода (Разница) ниже, программист знал, что любые условные (if ... then), используемая для проверки и обработки ошибки дешифрования, может привести к изменению времени выполнения, потому что процессорам обычно требуется разное количество времени в зависимости от того, каким образом ваш код следует за инструкцией «ветвления».

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

Отличие кода gnutls-3.7.8/lib/auth/rsa.c от 3.7.9

Но программист по-прежнему хотел зафиксировать, что может произойти атака, которая произойдет, если if (ok) вышеприведенный тест терпит неудачу и переходит в else { ... } .

В этот момент код вызывает _gnutls_debug_log() функция, которая может занять некоторое время, чтобы сделать свою работу.

Поэтому кодировщик намеренно вставил вызов _gnutls_no_log() в then { ... } часть кода, которая делает вид, что регистрирует «атаку», когда ее нет, чтобы попытаться выровнять время, затрачиваемое кодом в любом направлении, в котором if (ok) ветка инструкция можно взять.

Очевидно, однако, что два пути кода не были достаточно похожи по времени, которое они израсходовали (или, возможно, _gnutls_debug_log() функция сама по себе была недостаточно последовательной при работе с различными типами ошибок), и злоумышленник мог начать различать контрольные сигналы дешифрования примерно после миллиона попыток.

Что делать?

Если вы программист: Исправление ошибки здесь было простым и следовало принципу «меньше значит больше».

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

… и код, который не скомпилирован, никогда не запустится, будь то случайно или намеренно.

Если вы пользователь GnuTLS: недавно выпущенная версия 3.7.9 и «вкус нового продукта» 3.8.0 включите это исправление вместе с другими.

Если вы используете дистрибутив Linux, проверьте наличие обновлений для любой версии GnuTLS с централизованно управляемой общей библиотекой, а также для приложений, которые имеют собственную версию.

В Linux ищите файлы с именем libgnutls*.so чтобы найти любые общие библиотеки, лежащие поблизости, и выполнить поиск gnutls-cli чтобы найти любые копии утилиты командной строки, которые часто входят в состав библиотеки.

Вы можете запустить gnutls-cli -vv узнать какая версия libgnutls он динамически связан с:

 $ gnutls-cli -vv gnutls-cli 3.7.9 <-- мой дистрибутив Linux получил обновление в прошлую пятницу (2023 февраля 02 г.)

Отметка времени:

Больше от Голая Безопасность