Серйозна безпека: GnuTLS відповідає OpenSSL, виправляє помилку атаки за часом

Серйозна безпека: GnuTLS відповідає OpenSSL, виправляє помилку атаки за часом

Вихідний вузол: 1956368

Минулого тижня ми писали про купу помилки управління пам'яттю які були виправлені в останньому оновленні безпеки популярної бібліотеки шифрування OpenSSL.

Разом із помилками пам’яті ми також повідомили про дубльовану помилку CVE-2022-4304: синхронізація Oracle у дешифруванні RSA.

У цій помилці те саме зашифроване повідомлення знову і знову запускається на сервері, але змінюється заповнення в кінці даних, щоб зробити дані недійсними, і таким чином провокує якусь непередбачувану поведінку…

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

Не всі дані обробляються однаково

Якщо ви надішлете запит, відрахуєте час, який займає відповідь, і віднімете час, витрачений на низькорівневе надсилання й отримання мережевих даних, ви дізнаєтесь, скільки часу знадобилося серверу для виконання внутрішніх обчислень для обробки запиту .

Навіть якщо ви не впевнені, скільки часу витрачається в мережі, ви можете шукати варіації в часі зворотного зв’язку, надсилаючи багато запитів і збираючи безліч зразків.

Якщо мережа достатньо надійна, щоб припустити, що накладні витрати на мережу в основному постійні, ви можете використовувати статистичні методи, щоб зробити висновок, який вид модифікації даних викликає яку додаткову затримку обробки.

З цього ви можете зробити висновок про структуру або навіть вміст вихідних незашифрованих даних, які повинні зберігатися в таємниці в кожному повторюваному запиті.

Навіть якщо ви можете отримати лише один байт відкритого тексту, цього не повинно статися.

Так звані часові атаки такого роду завжди проблематично, навіть якщо вам може знадобитися надіслати мільйони фіктивних пакетів і зафіксувати їх усі, щоб мати хоч якийсь шанс відновити лише один байт даних відкритого тексту...

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

Ви можете подумати, що мільйони зрадницьких пакетів, надісланих вам, скажімо, протягом наступної години, виділятимуться як великий палець.

Але «мільйон пакетів на годину більше або менше, ніж зазвичай» просто більше не є особливо великою варіацією.

Подібна помилка «оракула» в GnuTLS

Що ж, та сама особа, яка повідомила про помилку часу виправлення останніх помилок у 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-10)

Часова мітка:

Більше від Гола безпека