November 30, 2018

Анализ SSL/TLS трафика в Wireshark

Как скрыть от посторонних конфиденциальную информацию?

Самое простое – зашифровать.

В Интернет и Интранет-сетях шифрацией данных управляет протокол SSL/TLS.

Солдат спит, служба идет.

Однако иногда возникает необходимость выполнить обратное – расшифровать перехваченный трафик.

Это может потребоваться как для отладки работы приложений, так и для проверки подозрительной сетевой активности.

Или в целях изучения работы SSL/TLS (очевидные, вредоносные цели не обсуждаются).

Как и при каких условиях можно расшифровать дамп SSL/TLS трафика в Wireshark?

Попробуем разобраться.

Разобраться с расшифровкой будет гораздо проще, если есть общие представления о принципах работы протокола SSL/TLS. Рассмотрим упрощённый вариант функционирования SSL/TLS, выделив в нем только самые важные для нас моменты.

Обычно началу обмена шифрованными данными, в SSL/TLS предшествует процесс установки соединения, рукопожатие (SSL handshake).

на хабре есть статья, подробно описывающая процесс установки SSL/TLS соединения (Первые несколько миллисекунд HTTPS соединения) thevar1able

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

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

Для этого существуют различные алгоритмы. Наиболее часто используемые в Интернет – это RSA (самый популярный) и эфемерный Диффи-Хеллмана (DHE/ECDHE).

В момент установки SSL/TLS соединения алгоритм согласования сеансовых ключей выбирает сервер.
Выбор происходит из списка алгоритмов, поддерживаемых клиентом, которые он передает на сервер.

Ниже на диаграмме показан процесс согласования сеансовых ключей в случаях RSA и DHE/ECDHE, а также информация, которую видит сниффер (Wireshark) в перехваченном SSL/TLS трафике.

В первом случае (согласование ключей RSA) в момент установки соединения клиент генерирует случайное число, предварительный секрет (pre-master secret). Шифрует его открытым ключом, полученным в сертификате от сервера.

Отправляет в зашифрованном виде на сервер. Сервер расшифровывает предварительный секрет своим секретным ключом. Далее обе стороны, обладая одинаковым предварительным секретом, конвертируют его в главный и уже из него создают общий сеансовый ключ.

В ассиметричных алгоритмах шифрования (RSA) данные, зашифрованные открытым ключом, могут быть расшифрованы только секретным. При этом, открытый и секретный ключи должны быть связаны между собой определенным математическим образом, являются ключевой парой.

Во втором случае (согласование ключей DHE/ECDHE) все работает немного по-другому.

В момент установки нового соединения клиент и сервер генерируют пару случайных эфемерных (временных) ключей Диффи-Хеллмана.

Пара состоит из открытого и секретного ключей. Стороны обмениваются открытыми ключами.

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

В данном алгоритме постоянный секретный ключ сервера (RSA/DSA/ECDSA) в шифрации не участвует и используется только для подписи открытых DH-ключей. Описание очень общее, есть подробная информация в статье на хабре (Как HTTPS обеспечивает безопасность соединения: что должен знать каждый Web-разработчик) zavg.

Теперь возможно стало немного понятней.

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

Дело в том, что в момент установки SSL/TLS-соединения клиент пересылает серверу зашифрованное значение предварительного секрета.

Предварительный секрет дешифруется секретным ключом сервера, далее вычисляется сеансовый ключ.

Данные расшифровываются полученным сеансовым ключом.

В случае использования алгоритма DHE/ECDHE и обладая секретным ключом сервера, расшифровать данные SSL/TLS трафика уже не получится.

В момент установки соединения передаются только открытые значения DH-ключей.

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

Эфемерные алгоритмы согласования ключей Диффи-Хеллмана (DHE/ECDHE) поддерживают Perfect Forward Secrecy (PFS).

Есть конечно другой, альтернативный вариант.

Подходит для расшифровки SSL/TLS-трафика без секретного ключа сервера, а также если используются алгоритмы DHE/ECDHE, RSA и другие.

В момент установки SSL/TLS-соединения в оперативной памяти клиента и сервера присутствуют открытые значения секретов, предварительного и главного.

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

Конечно, это не всегда просто сделать и не позволяет расшифровать трафик, перехваченный когда-либо ранее.

А теперь посмотрим, как на практике, обладая секретным ключом сервера или значениями секретов сессий, можно расшифровать SSL/TLS-трафик в Wireshark.

Wireshark + cекретный ключ сервера

Собственно, тут все относительно просто.

Загружаем в Wireshark дамп SSL/TLS-трафика обмена клиента с сервером, подключаем секретный ключ сервера и расшифровываем.

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

Для этого находим инициализацию SSL/TLS-соединения (фильтр «ssl.handshake»).

Проверяем, что сервер в сообщении Server Hello в Cipher Suite указывает алгоритм RSA.

В ответном сообщении клиента (Client Key Exchange) присутствует зашифрованное значение предварительного секрета сессии (Encrypted PreMaster).

Выполняем настройки Wireshark.

В меню Edit --> Preferences слева раскрываем ветку со списком протоколов (Protocols) и выбираем SSL.

Проверяем установку флага «Reassemble SSL records spanning multiple TCP segments».

В поле «SSL debug file» указываем путь к логу с отладочной информацией (фиксируются результаты дешифрации, может пригодиться при разборе возникших проблем).

В поле «RSA keys list» жмем кнопку Edit.

В появившемся окне жмем кнопку New и заполняем поля:

IP Address – IP-адрес SSL-сервера в IPv4 или IPv6-формате

Port – номер порта SSL-сервера (для https обычно 443)

Protocol – название протокола, использующего шифрацию SSL (например, http). Если не известен, указываем data

Key File – путь к файлу секретного ключа сервера (файл формата PEM или PKCS#12)

Password – заполняется, только если секретный ключ PKCS#12 и защищен паролем

Подтверждаем выполненные настройки и наслаждаемся просмотром расшифрованного трафика.

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

Также открытая информация доступна на закладке «Decrypted SSL Data», в нижней части окна.

Или выбираем любой пакет из SSL/TLS-сессии, нажимаем правую клавишу мыши, затем в списке – «Follow SSL Stream».

Получаем поток расшифрованных данных из выбранного соединения.

Wireshark + cекреты сессий

Кроме секретного ключа сервера, для расшифровки данных в Wireshark могут использоваться известные значения секретов сессий.

Хорошая возможность для тех, у кого нет секретного ключа сервера или если сервер выбирает алгоритм согласования сеансовых ключей с поддержкой PFS (DHE/ECDHE).

Где и как можно достать секреты сессий?

  1. Wireshark поддерживает экспорт предварительных секретов из загруженного дампа SSL/TLS-трафика.
Wireshark, меню Files -> Export SSL Session Keys
  1. Конечно, перед этим трафик должен быть расшифрован секретным ключом сервера.
  2. Очень важная функциональность.
  3. Дело в том, что Wireshark не умеет сохранять трафик в расшифрованном виде.
  4. Иногда есть необходимость передать расшифрованный трафик кому-то еще, не компрометируя секретный ключ сервера.
  5. Для решения этой проблемы можно, как обычно, расшифровать трафик секретным ключом сервера и экспортировать из него все секреты SSL/TLS -сессий в отдельный файл.
  6. После этого становится возможным повторно расшифровать трафик, используя только файл с секретами.
  7. В некоторых приложениях существует встроенная функциональность, позволяющая сохранять секреты на диск.
Яркий пример таких приложений – это браузеры Chrome и FireFox.
Оба в своей работе используют криптографический модуль NSS, разрешающий логирование секретов в файл.
Формат лога приведён ниже и соответствует первым двум вариантам.
Более подробное описание функциональности есть в статье на хабре (Как легко расшифровать TLS-трафик от браузера в Wireshark) ValdikSS.
В Java-программах секреты могут быть получены из SSL дебаг лога (Дешифрация TLS трафика Java приложений с помощью логов) Toparvion.
Или сразу в формате Wireshark через jSSLKeyLog (Java Agent Library to log SSL session keys to a file for Wireshark)
  1. Другие варианты.
Используя сторонние утилиты, перехватывать секреты сессий в оперативной памяти клиента или сервера.

А теперь – о том, как и в каком виде секреты загружаются в Wireshark.

Значения секретов сессий указываются построчно в обычном текстовом файле в определенном формате.

Существует три возможных формата строк:

  1. Для SSL/TLS-сессий с алгоритмом согласования сеансовых ключей RSA
  2. RSA <hex encrypted pre-master secret> <hex pre-master secret>
<hex encrypted pre-master secret> — зашифрованное значение предварительного секрета сессии (поле Encrypted Premaster в сообщение ClientKeyExchange)
<hex pre-master secret> — расшифрованное значение предварительного секрета
  1. Для SSL/TLS-сессий с алгоритмом согласования сеансовых ключей DHE/ECDHE
  2. CLIENT_RANDOM <hex client_random> <hex master secret>
<hex client_random> — случайное число клиента (Random в сообщение Client Hello)
<hex master secret> — значение главного секрета сессии
  1. Поддержка вывода Master-Key в «openssl s_client»
  2. RSA Session-ID:<hex session id> Master-Key:<hex master secret>
<hex session id> — идентификатор сессии (поле Session ID из Server Hello или Session Ticket из Client Hello)
<hex master secret> — значение главного секрета сессии

И теперь подключаем файл с секретами в Wireshark и дешифруем SSL/TLS-трафик.

Настройки Wireshark аналогичны указанным в предыдущем разделе.

За исключением того, что в настройках протокола SSL в «RSA keys list» не нужно ничего указывать (параметры SSL-сервера и его секретный ключ). Только в поле "(Pre)-Master-Secret log filename" путь к файлу с секретами.

Подтверждаем настройки и смотрим расшифрованный трафик.

Заключение

Надеюсь, представленная информация окажется интересной всем,

кто планирует или уже занимается анализом SSL/TLS-трафика в Wireshark.

Все ссылки по теме:

Wireshark — приручение акулы

Что такое TLSbabayota_kun

Первые несколько миллисекунд HTTPS соединения

Как HTTPS обеспечивает безопасность соединения: что должен знать каждый Web-разработчикzavg

Как легко расшифровать TLS-трафик от браузера в WiresharkValdikSS

Дешифрация TLS трафика Java приложений с помощью логовToparvion

jSSLKeyLog — Java Agent Library to log SSL session keys to a file for Wireshark

Криптосистема с открытым ключом

RSA

Протокол Диффи — Хеллмана

Perfect forward secrecy

by t.me/it_ha