Хакер - Грандиозный факап. Разбираем уязвимости проверки сертификатов SSL/TLS в небраузерном софте
nopaywall
Содержание статьи
Хотели как лучше
В теории, защищенное SSL/TLS-протоколом соединение должно обеспечивать конфиденциальность, достоверность и целостность коммуникаций клиентского и серверного софта, даже если в сеть проник активный продвинутый злоумышленник: когда сеть полностью захвачена врагом, DNS отравлен, а точки доступа и маршрутизаторы, коммутаторы и Wi-Fi контролируются злоумышленником, который, помимо всего прочего, контролирует SSL/TLS-бэкенд. Кроме того, когда клиентский софт пытается подключиться к законному серверу, злоумышленник может подменить сетевой адрес сервера (например, через отравление DNS) и перенаправить клиент вместо законного сервера на свой злонамеренный сервер.
Безопасность коммуникаций в таких суровых условиях, как известно, целиком зависит от адекватности проверки криптографического сертификата, предоставленного сервером при установке соединения. В том числе от адекватности реализации набора шифров (cipher suite), которыми клиент и сервер пользуются при обмене данными. Для того чтобы SSL/TLS-соединение было полностью безопасным, клиентский софт в числе прочего должен тщательно удостовериться в том, что:
- сертификат выдан действующим органом сертификации;
- срок его действия не истек (или сертификат не был отозван);
- в списке перечисленных в сертификате имен присутствует тот домен, к которому производится подключение.
Получилось как всегда: проверка провалена
Однако во многих приложениях и библиотеках, для которых безопасность коммуникаций очень критична, процедура проверки SSL/TLS-сертификата, и даже EV-SSL, сертификата с расширенной проверкой, полностью провальна, причем это справедливо для всех популярных операционных систем: Linux, Windows, Android и iOS. Среди уязвимого софта, библиотек и middleware-сервисов можно выделить следующие:
- Amazon’овская Java-библиотека EC2 и все облачные фронтенд-клиенты, построенные на ее основе;
- Amazon’овский и PayPal’овский торговый SDK, ответственный за доставку платежных реквизитов от сайтов (на которых развернута инфраструктура онлайн-коммерции) к платежным шлюзам;
- интегрированные «корзины», такие как osCommerce, ZenCart, Ubercart и PrestaShop, которые не проверяют сертификаты вообще;
- AdMob-код, используемый мобильным софтом для показа контекстной рекламы;
- интерфейсные фронтенд-компоненты ElephantDrive и FilesAnywhere, ответственные за взаимодействие с облачным хранилищем;
- Android’ная библиотека Pusher и весь софт, который использует Pusher API для управления обменом мгновенными сообщениями (например, GitHub’овский Gaug.es);
- Apache HttpClient (версия 3.x), Apache Libcloud и все клиентские подключения к серверам Apache ActiveMQ и подобным;
- SOAP middleware-сервисы Java, в том числе Apache Axis, Axis 2, Codehaus XFire; а также весь софт, который на базе этих middleware-сервисов построен;
- API-инструменты Elastic Load Balancing;
- Weberknecht-реализация WebSockets’ов;
- а также весь мобильный софт, построенный на базе перечисленных выше библиотек и middleware-сервисов (чтобы понять, что такое middleware-сервисы, смотри слайды); в том числе iOS-клиент хостинг-провайдера Rackspace.
Например, здесь перечислено еще больше сотни уязвимых мобильных приложений. В их числе: Android’s Google Cloud Messaging, Angie’s List Business Center Passwords, AT&T Global Network Client, CapitalOne Spark Pay, Cisco OnPlus (remote access), Cisco Technical Support, Cisco WebEx, Cisco WebEx Passwords, Dominos Pizza, E-Trade, Freelancer, Google Earth, Huntington Mobile (Bank), Intuit Tax Online Accountant, iTunes Connect, Microsoft Skype, Oracle Now, Pinterest, SafeNet (VPN client), SouthWest Airlines, Uber, US Bank — Access Online, Western Union, WordPress, Yahoo! Finance, Yahoo! Mail.
Небольшая выборка из списка уязвимых мобильных приложенийЛогические уязвимости SSL/TLS-протокола
SSL/TLS-соединения всего этого и многого другого софта уязвимы для широкого спектра MitM-атак. При этом MitM-атаку можно провести зачастую даже без подделки сертификатови без похищения приватных ключей, которыми серверы подписывают свои сертификаты. MitM-атаку можно провести, просто эксплуатируя логические уязвимости, которые присутствуют в процедуре проверки SSL/TLS-сертификата на стороне клиентского софта. В результате MitM-злоумышленник может, например, собирать токены авторизации, номера кредитных карт, имена, адреса и прочее — у любого продавца, который использует уязвимые веб-приложения обработки платежей.
Поставщики мобильного софта, которые берут за основу семпл-код AdMob для связи своих приложений с AdMob-аккаунтом, тоже уязвимы — они позволяют атакующему захватывать учетные данные и получать доступ ко всем его Google-сервисам. К примеру, из-за некорректной проверки сертификатов в таких мессенджерах, как Trillian и AIM, MitM-злоумышленник может похитить учетные данные для входа ко всем сервисам Google (включая Gmail), Yahoo и также к сервисам Windows Live (в том числе SkyDrive). Среди других уязвимостей, которыми страдает современный небраузерный веб-софт: использование неправильных регулярных выражений при сравнении имени хоста; игнорирование результатов проверки корректности сертификата; случайное или преднамеренное отключение проверки.
Другие распространенные уязвимости реализации SSL/TLS-протокола
Ну и конечно же, нельзя забывать о том, что даже если в реализации SSL/TLS-протокола нет логических ошибок (если, конечно, кто-то в это еще верит), то защиту можно обойти, похитив приватный ключ, применив 0day-эксплоиты к таким вещам, как клавиатуры, браузеры, операционные системы, утилиты и прошивки, скомпрометировав BGP-маршрутизацию либо атаковав SSL/TLS по аппаратным и/или программным обходным каналам.
Атака на SSL по аппаратным обходным каналамКроме того, злоумышленники могут выполнять практически невидимые MitM-атаки, злоупотребляя механизмом кеширования SSL/TLS-сеансов, реализованным в классе SSLSessionCache. Этот механизм проверяет достоверность сертификатов только при первоначальном соединении, и при этом неспособен должным образом аннулировать сеанс связи после удаления сертификатов с устройства. Кроме того, после перезагрузки Android-устройства (через опции «Перезапуск» или «Отключить питание») можно продолжать видеть зашифрованный трафик части приложений, которые после перезагрузки не запускались, но до перезагрузки работали. Так, например, происходит с Google Maps. В презентации с Black Hat описано, как благодаря этим недочетам кеширования злоумышленник может совершенно прозрачно для пользователя устанавливать и удалять «невидимые сертификаты» и затем устанавливать сетевое соединение с любым приложением.
Ретроспектива уязвимого шифрованияСреди других распространенных уязвимостей реализации SSL/TLS-протокола можно отметить уязвимое шифрование (см. презентацию с Black Hat за 2016 год), повторное использование GCM (Galois/Counter Mode; счетчик с аутентификацией Галуа) (источник — еще одна публикация с Black Hat, тоже за 2016 год), хитрость с CNG (CryptoAPI-NG) в Schannel, некорректную проверку цепочки доверия, некорректную проверку имени хоста.
Хитрость с 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-протокола. Некоторые из этих уязвимостей (но не все) были описаны и/или упомянуты выше. Ознакомиться с упомянутыми, но не описанными уязвимостями можно, почитав материалы, перечисленные в библиографии.
Классификация актуальных для SSL/TLS уязвимостейЧтобы добавить ложку меда в бочку дегтя, стоит отметить, что в указанном выше источникеподробно, понятно, популярно и грамотно описано (со ссылкой на RFC), как SSL должен реализовываться. Лучшего описания, которое было бы технически точным и одновременно понятным, мы не встречали. Также авторы разбирают самые распространенные SSL-библиотеки, с классификацией по уровню абстрагирования (низкоуровневые/высокоуровневые). Все с диаграммами и лаконичными алгоритмами в псевдокоде. Подробно описаны уязвимости конкретных продуктов, с приведением некорректного программного кода и указанием ошибок. Так что если вдруг у кого-то в очередной раз возникнет желание создать такую реализацию SSL/TLS-фреймворка, которая станет исключением из поговорки «хотели как лучше, а получилось как всегда», то материал — идеальное для этого начало.
Библиография
- Martin Georgiev, Rishita Anubhai, Subodh Iyengar. The Most Dangerous Code in the World: Validating SSL Certificates in Non-Browser Software // Proceedings of the 2012 ACM conference on computer and communications security. 2012. P. 38–49.
- Tony Trummer. Mobile SSL Failures // Proceedings of the HITB Security Conference. 2015.
- Kellen Evan Person. How Ciphersuites Work: TLS in Pieces // 2017. URL: https://fly.io/articles/how-ciphersuites-work/ (дата обращения: 15 февраля 2018).
- Catalin Cimpanu. Extended Validation (EV) Certificates Abused to Create Insanely Believable Phishing Sites // BleepingComputer. 2017. URL: https://www.bleepingcomputer.com/news/security/extended-validation-ev-certificates-abused-to-create-insanely-believable-phishing-sites/ (дата обращения: 20 февраля 2018).
- David Adrian. A Retrospective on the Use of Export Cryptography // Black Hat. 2016.
- Sean Devlin. Nonce-Disrespecting Adversaries: Practical Forgery Attacks on GCM in TLS // Black Hat. 2016.
- Jake Kambic. Cunning with CNG: Soliciting Secrets from Schannel // Black Hat. 2016.
- Valeria Bertacco. Torturing OpenSSL // Black Hat. 2012.
- Tom van Goethem. HEIST: HTTP Encrypted Information Can Be Stolen Through TCP-Windows // Black Hat. 2016.
- Artyom Gavrichenkov. Breaking Https With BGP Hijacking // Black Hat. 2016.
- Chris Stone, Tom Chothia. Spinner: Semi-Automatic Detection of Pinning without Hostname Verification // Proceedings of the Annual Computer Security Applications Conference (ACSAC) 2017.
- Marco Ortisi. Recover a RSA Private Key from a TLS Session with Perfect Forward Secrecy // Black Hat. 2016.
Мнение эксперта
Иван Пискунов
Независимый эксперт и практикующий специалист, с опытом 9+ лет в индустрии ИБ. Автор блога ipiskunov.blogspot.com, персональной колонки на SecurityLab. Написал несколько статей по реверсингу для журнала «Хакер», резидент портала anti-malware.ru. Ранее член первой сибирской CTF-команды CraZY Geek$.
Неплохая, злободневная статья по SSL/TSL. В целом ключевые моменты освещены. Мои, что называется, пять копеек:
- К хорошим новостям: SSL используется в качестве сертификата для web-серверов, форсирующих применение HTTP(S)-протокола. Это очень важно, на мой взгляд, так как, по сути, именно возможность шифрованной передачи данных с помощью SSL уберегает нас от снифинга паролей, к примеру где-нибудь в кафешке с бесплатным Wi-Fi (например, можно поднять фейковую точку доступа и перехватывать пароли от VK, Сбера и другие в открытом виде, если бы использовался просто HTTP).
- К плохим новостям: SSL все равно не панацея, поскольку данные могут быть перехвачены путем подмены корневого сертификата и реализации атаки «человек посередине», у меня на эту тему есть статья в блоге «Перехват и расшифровка HTTPS-трафика». Кроме того, в 2014 году правительство США сообщило об уязвимости в текущей версии протокола. SSL должен быть исключен из работы в пользу TLS (см. CVE-2014-3566).
- И снова к хорошим новостям: что мне нравится в асимметричном шифровании — это работа алгоритма Диффи — Хеллмана, когда для шифрования сессии используется сеансовый ключ. На этой фиче я бы остановился подробнее. Уязвимости под этот алгоритм пока что нет!
Читайте ещё больше платных статей бесплатно: https://t.me/nopaywall