Уязвимости SSL и TLS-протокола в небраузерном софте

Безопасность SSL иконка

SSL/TLS-соединения софта уязвимы для широкого спектра MitM-атак. При этом MitM-атаку можно провести зачастую даже без подделки сертификатов и без похищения приватных ключей, которыми серверы подписывают свои сертификаты. MitM-атаку можно провести, просто эксплуатируя логические уязвимости, которые присутствуют в процедуре проверки SSL/TLS-сертификата на стороне клиентского софта.

Еще по теме: Как включить TLS 1.3 в Windows

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

Поставщики мобильного софта, которые берут за основу семпл-код AdMob для связи своих приложений с AdMob-аккаунтом, тоже уязвимы — они позволяют атакующему захватывать учетные данные и получать доступ ко всем его Google-сервисам. К примеру, из-за некорректной проверки сертификатов в таких мессенджерах, как Trillian и AIM, MitM-злоумышленник может похитить учетные данные для входа ко всем сервисам Google (включая Gmail), Yahoo и также к сервисам Windows Live (в том числе SkyDrive).

Среди других уязвимостей, которыми страдает современный небраузерный веб-софт: использование неправильных регулярных выражений при сравнении имени хоста; игнорирование результатов проверки корректности сертификата; случайное или преднамеренное отключение проверки.

Другие распространенные уязвимости реализации SSL/TLS-протокола

Ну и конечно же, нельзя забывать о том, что даже если в реализации SSL/TLS-протокола нет логических ошибок (если, конечно, кто-то в это еще верит), то защиту можно обойти, похитив приватный ключ, применив 0day-эксплоиты к таким вещам, как клавиатуры, браузеры, операционные системы, утилиты и прошивки, скомпрометировав BGP-маршрутизацию либо атаковав SSL/TLS по аппаратным и/или программным обходным каналам.

ssl уязвимость
Атака на SSL по аппаратным обходным каналам

Кроме того, злоумышленники могут выполнять практически невидимые MitM-атаки, злоупотребляя механизмом кеширования SSL/TLS-сеансов, реализованным в классе SSLSessionCache. Этот механизм проверяет достоверность сертификатов только при первоначальном соединении, и при этом неспособен должным образом аннулировать сеанс связи после удаления сертификатов с устройства.

Кроме того, после перезагрузки Android-устройства (через опции «Перезапуск» или «Отключить питание») можно продолжать видеть зашифрованный трафик части приложений, которые после перезагрузки не запускались, но до перезагрузки работали. Так, например, происходит с Google Maps. В презентации с Black Hat описано, как благодаря этим недочетам кеширования злоумышленник может совершенно прозрачно для пользователя устанавливать и удалять «невидимые сертификаты» и затем устанавливать сетевое соединение с любым приложением.

ssl уязвимость
Ретроспектива уязвимого шифрования

Среди других распространенных уязвимостей реализации SSL/TLS-протокола можно отметить уязвимое шифрование (см. презентацию с Black Hat за 2016 год), повторное использование GCM (Galois/Counter Mode; счетчик с аутентификацией Галуа) (источник — еще одна публикация с Black Hat, тоже за 2016 год), хитрость с CNG (CryptoAPI-NG) в Schannel, некорректную проверку цепочки доверия, некорректную проверку имени хоста.

tls уязвимость
Хитрость с CNG: вытягиваем секреты из Schannel

Некорректная проверка цепочки доверия представляет собой ситуацию, когда веб-приложение принимает абсолютно любой сертификат, в котором указано корректное имя хоста, не проверяя при этом, каким центром сертификации он был подписан. Это позволяет перехватывать и дешифровывать пароли и/или номера кредитных карт. А в некоторых случаях даже делать инъекцию вредоносного кода. В Android-софт данная уязвимость проникает, например, когда создается кастомизированный X509TrustManager-интерфейс, который игнорирует исключения CertificateException. Или когда разработчик софта вставляет в код WebViews-компонента вызов метода SslErrorHandler.proceed().

Корень зла SSL/TLS

Главная причина подавляющего большинства перечисленных уязвимостей — ужасный API-дизайн SSL/TLS-библиотек (в том числе JSSE, OpenSSL и GnuTLS). А заодно и не менее ужасный дизайн библиотек передачи данных (таких как cURL, Apache HttpClient и urllib), каждая из которых представляет собой высокоуровневую обертку для SSL/TLS-библиотек. Не говоря уже о middleware-сервисах (таких как Apache Axis, Axis 2 или Codehaus XFire), еще более высокоуровневых обертках, которые увеличивают «снежный ком» ужасного дизайна.

Вместо того чтобы вести с прикладным разработчиком (зачастую далеким от системного программирования) диалог на понятном ему языке (в терминах конфиденциальности и аутентификации), абстрагируясь от низкоуровневых подробностей реализации SSL/TLS-протокола, эти API вываливают на бедолагу кучу низкоуровневых SSL/TLS-параметров, непонятных ему. Требуют от высокоуровневого софта, чтобы он правильно выставлял низкоуровневые опции, реализовывал функции проверки имени хоста и заботился об интерпретации возвращаемых низкоуровневыми операциями значений.

В результате прикладные разработчики используют SSL/TLS API неправильно: ошибочно интерпретируют многообразие их параметров, опций, побочных эффектов и возвращаемых значений. Например:

  • Amazon’овская PHP-библиотека Flexible Payments Service пытается включить проверку имени хоста посредством установки параметра CURLOPT_SSL_VERIFYHOST в значение TRUE (в cURL-библиотеке). Однако корректное значение по умолчанию для этого параметра — 2; если же присвоить ему значение TRUE, то этому параметру незаметно для разработчика присваивается значение 1, и таким образом проверка сертификата отключается;
  • PHP-библиотека PayPal Payments Standard приобрела ту же самую ошибку; причем в тот момент, когда предыдущая, уязвимая реализация обновлялась (то есть одну ошибку убрали, другую добавили);
  • другой пример — это Lynx, текстоориентированный браузер. Он проверяет самоподписанные сертификаты, но только в том случае, если GnuTLS’ная функция проверки сертификата возвращает отрицательное значение. Однако эта самая функция для некоторых ошибок возвращает 0; в том числе в тех случаях, когда сертификаты подписаны недоверенным органом. Из-за этого цепочка проверки доверия в Lynx оказывается нарушена.

Кроме того, прикладные разработчики зачастую неправильно понимают, какие именно гарантии безопасности предоставляет та или иная SSL/TLS-библиотека. Поэтому в дикой природе можно встретить клинические случаи, когда в приложениях, принципиально нуждающихся в защищенных коммуникациях (например, взаимодействующих с платежным процессором), используется SSL/TLS-библиотека, которая не проверяет SSL/TLS-сертификаты вообще.

Более прозаичные, но еще более убийственные случаи — это когда разработчик какого-нибудь из промежуточных слоев софта молча отключает процедуру проверки SSL/TLS-сертификатов (он может сделать это, например, для тестирования системы, а после тестирования — забыть вновь включить ее). При этом высокоуровневый программный код, использующий этот промежуточный слой, уверен, что проверка сертификатов производится. Таким образом, ошибки SSL/TLS часто бывают скрыты в глубине одного или сразу нескольких промежуточных слоев-библиотек — из-за чего обнаружить данную проблему становится практически невозможно.

Например, в JSSE (Java Secure Socket Extension) расширенный интерфейс SSLSocketFactory API молча пропускает проверку имени хоста, если поле algorithm в SSL-клиенте установлено в NULL или в пустую строку, а не в HTTPS. Хотя данное обстоятельство упоминается в справочном руководстве JSSE, многие Java-реализации SSL-протоколов используют SSLSocketFactory без выполнения проверки имени хоста…

Ложка меда в бочку дегтя

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

tls уязвимость
Классификация актуальных для SSL/TLS уязвимостей

Чтобы добавить ложку меда в бочку дегтя, стоит отметить, что в указанном выше источнике подробно, понятно, популярно и грамотно описано (со ссылкой на RFC), как SSL должен реализовываться. Лучшего описания, которое было бы технически точным и одновременно понятным, мы не встречали. Также авторы разбирают самые распространенные SSL-библиотеки, с классификацией по уровню абстрагирования (низкоуровневые/высокоуровневые). Все с диаграммами и лаконичными алгоритмами в псевдокоде. Подробно описаны уязвимости конкретных продуктов, с приведением некорректного программного кода и указанием ошибок.

Так что если вдруг у кого-то в очередной раз возникнет желание создать такую реализацию SSL/TLS-фреймворка, которая станет исключением из поговорки «хотели как лучше, а получилось как всегда», то материал — идеальное для этого начало.

Еще по теме: Как работает DNS over HTTPS и кому нужен?

Дима (Kozhuh)

Эксперт в кибербезопасности. Работал в ведущих компаниях занимающихся аналитикой компьютерных угроз. Анонсы новых статей в Телеграме.

Добавить комментарий