В статье хотим рассказать про технологию TLS fingerprinting, про которую недостаточно материалов в русскоязычном сегменте. Попробуем это исправить. Статья частично переводит тематические материалы авторов описываемых методов (тут и тут), а также содержит описание практической реализации от Акрибии.
Не будем глубоко погружаться в детали работы SSL/TLS (далее будем говорить TLS), но кратко поясним детали.
Использование TLS само по себе благо, так как с его помощью шифруются данные. Но с обратной стороны создатели вредоносов используют его же, чтобы скрываться в шифрованном трафике (в данной статье как раз будет уклон в эту сторону) и затруднять их обнаружение и нейтрализацию.
Чтобы инициировать сеанс TLS, клиент отправляет «пакет» приветствия серверу после трёхстороннего установления связи TCP. Этот «пакет» и способ его создания зависят от пакетов и методов шифрования, используемых при создании клиентского приложения. Если сервер принимает соединение TLS, он ответит пакетом приветствия, тем самым продолжая согласование шифрования.
Поскольку согласование шифрования TLS передаётся в открытом виде, то можно отследить и идентифицировать клиентские приложения.
В этом и суть технологии TLS fingerprinting, если кратко. А теперь немного подробнее.
TLS fingerprinting
Суть технологии в захвате элементов пакета приветствия клиента, которые остаются статичными от сеанса к сеансу для каждого клиента. На их основе можно создать «отпечаток пальца» для распознавания конкретного клиента в последующих сеансах. Записываются следующие поля:
версия TLS;
версия записи TLS;
наборы шифров;
параметры сжатия;
список расширений.
Кроме того, данные собираются из трех конкретных расширений (если они доступны):
алгоритмы подписи;
алгоритм для шифрования данных;
хэш функция для проверки содержимого.
Использование такого набора данных позволяет с большой точностью идентифицировать используемый клиент (например, браузер).
Почему это круто:
Пакет приветствия клиента — это первый пакет в любом TLS-соединении. Это позволяет принимать решение о последующих мерах в начале сеанса до того, как потребуется подмена протокола или эмуляция.
Можно захватывать пакеты приветствия клиента TLS с высокой степенью точности по всем портам с абсолютно нулевым требованием для захвата обоих направлений потока. Это означает, что датчики в среде с асимметричной маршрутизацией или с ограничениями ресурсов, потенциально вызывающими отбрасывание пакетов, все равно могут собирать пакеты приветствия клиента, независимо от того, были ли они скрыты из-за работы на нестандартных портах.
Пакеты приветствия клиента возникают достаточно редко, поэтому дополнительная обработка хэшей не повлечет значительных затрат.
Наиболее очевидное использование TLS Fingerprinting – пассивное обнаружение. Технология позволяет обнаруживать широкий спектр потенциально нежелательного трафика, не требуя доступа к конечным точкам. Можно обнаруживать как конкретные вредоносы по их поведению и/или обращениям к командным центрам, так и обычный софт, используемый не по назначению или в обход действующих правил.
Например, к серверу Exchange могут обращаться только почтовые клиенты или браузер, если используется OWA, поэтому соединение из скрипта на Python будет подозрительным.
Итого: TLS Fingerprinting предназначен для быстрой идентификации известных TLS-соединений и отслеживания неизвестных TLS-соединений. Входные данные принимаются либо посредством прослушивания трафика, либо при чтении PCAP файлов.
Есть несколько готовых реализаций, наиболее поддерживаемых комьюнити:
пассивный метод с использованием хэшей JA3 и JA3S;
активный инструмент снятия отпечатков пальцев с сервера TLS – хэши JARM.
JA3 и JA3S
Метод JA3 используется для сбора десятичных значений байтов для следующих полей в пакете приветствия клиента: версия TLS, набор шифров, список расширений протоколов TLS, эллиптические кривые и форматы эллиптических кривых. Затем он объединяет эти значения вместе по порядку, используя символ «,» для разграничения каждого поля и «-» для разграничения каждого значения в каждом поле.
Порядок полей следующий:
TLSVersion,Ciphers,Extensions,EllipticCurves,EllipticCurvePointFormats
Пример:
771,49196-49162-49195-52393-49161-49200-49172-49199-52392-49171-159-57-56-107-158-52394-51-50-103-22-19-157-53-61-156-47-60-10,0-23-65281-10-11-13-28,29-23-24-25,0
Если в ClientHello нет расширений TLS, поля остаются пустыми:
769,4–5–10–9–100–98–3–6–19–18–99,,,
Эти строки затем хэшируются MD5. Пример отпечатка JA3:
c8446f59cca2149cb5f56ced4b448c8d
JA3S – это хэш идентификации сервера. Метод JA3S заключается в сборе десятичных значений байтов для следующих полей в пакете приветствия сервера: версия TLS, набор шифров и список расширений протоколов TLS. После сбора значений, происходит процесс объединения этих значений вместе по порядку, используя «,» для разграничения каждого поля и «-» для разграничения каждого значения в каждом поле.
Порядок полей, следующий:
TLSVersion,Cipher,Extensions
Пример:
769,47,65281–0–11–35–5–16
Если в Server Hello нет расширений TLS, поля остаются пустыми.
Пример:
769,47,
Эти строки затем хэшируются MD5 для создания 32-символьного отпечатка пальца.
Это отпечаток JA3S:
4835b19f14997673071435cb321f5445
JA3 и JA3S – это методы снятия отпечатков TLS. JA3 отслеживает способ, которым клиентское приложение обменивается данными через TLS, а JA3S отслеживает ответ сервера. Вместе они создают отпечаток криптографического согласования между клиентом и сервером.
Теперь перейдем к описанию активного метода JARM.
JARM
JARM работает, активно отправляя 10 пакетов приветствия клиента TLS на целевой сервер и фиксируя определенные атрибуты ответов приветствия сервера. Затем агрегированные ответы сервера TLS хэшируются определенным образом для получения отпечатка JARM. JARM отправляет разные версии, шифры и расширения TLS в разном порядке для сбора уникальных ответов. Хэш JARM представляет собой гибридный нечеткий хэш, он использует комбинацию обратимого и необратимого алгоритма хеширования для создания 62-символьного отпечатка.
Отпечатки JARM можно использовать:
убедиться, что все серверы в группе имеют одинаковую конфигурацию TLS;
сгруппировать разрозненные серверы в сети Интернет по конфигурации, указав, например, что сервер может принадлежать Google, Yandex или Apple;
определить приложения или инфраструктуру по умолчанию;
выявить командные центры и других вредоносные серверы в сети Интернет.
Первые 30 символов состоят из шифра и версии TLS, выбранных сервером для каждого из 10 отправленных приветствий клиента. «000» означает, что сервер отказался согласовывать приветствие с этим клиентом. Остальные 32 символа представляют собой усеченный хэш SHA256 совокупных расширений, отправленных сервером, без учета данных сертификата x509. При сравнении отпечатков JARM, если первые 30 символов совпадают, но последние 32 отличаются, это будет означать, что серверы имеют очень похожие конфигурации, принимают одинаковые версии и шифры, но используют различные расширения, что не позволяет их считать полностью идентичными.
Исторически так сложилось, что индустрия кибербезопасности была сосредоточена в основном на индикаторах компрометации (IOC) и индикаторах атаки (IOA). То есть когда вредоносное ПО/хост и т.п. будут кем-то обнаружены, исследователи или вендоры платформ TI вычленяют уникальные или не очень признаки выявленного вредоноса или атаки типа IP, домена, хэша файла и т.п. и публикуют их в «чёрных списках». Проблема в том, что к этому моменту вредоносное ПО уже распространено, и специалисты ИБ автоматически переходят в оборону.
Интернет-сканирование JARM в сочетании с другими метаданными и историческим анализом даёт возможность упреждающей идентификации IOC для новых вредоносов. Например, можно сканировать Интернет с помощью JARM, сопоставлять известные результаты JARM с историей домена, IP и репутацией вместе с данными сертификата для создания черного списка. Это позволяет перейти к возможности программного создания высокоточных списков блокировки до того, как первая вредоносная программа будет распространена.
Можно использовать JARM автоматически сканируя все хосты назначения, детектируемые в сети компании, для обогащения событий, и использовать сводную таблицу, чтобы не сканировать одни и те же хосты несколько раз. Затем можно запускать запросы заведомо плохих JARM или использовать список для корреляции.
Чтобы упростить процесс, можно использовать готовое решение. В настоящее время хэши JARM умеют считать продукты Palo Alto Networks и используют их API для обогащения целевого JARM.
Примеры реализации
Если нет возможности или желания использовать готовые решения от Palo Alto и пр., можно реализовать в своей инфраструктуре свое средство мониторинга трафика, например, на основе Zeek (ранее назывался Bro) – популярного open-source продукта, заточенного специально для этого.
Zeek собирает огромное количество информации из первоначального согласования TLS, т.к. оно обрабатывается в открытом виде. Таким образом, хотя мы не можем видеть всё, что связано с шифрованием TLS, мы всё же можем получить общее представление о том, что происходит.
Zeek умеет выполнять снятие отпечатков TLS с помощью хэша JA3\JA3S.
Если у нас уже есть Zeek, в него попадает трафик, то для полноценного мониторинга нам понадобится SIEM (можно обойтись и без SIEM, но тогда обрабатывать логи Zeek’а придется вручную). Допустим, SIEM у нас все же есть. Помимо инструментов обработки трафика и событий Zeek нам еще потребуются списки готовых хэшей, чтобы было с чем сравнивать.
В случае в JA3 – все просто. Есть готовый инструмент, к которому можно обращаться по API для проверки выявленного хэша JA3 и принятия решения – нормально это или не очень.
Хэши JA3S, соответствующие вредоносам, достать чуть сложнее. Есть, например, небольшая подборка тут, есть и еще, нужно только искать или считать самостоятельно.
С хешами JARM еще немного сложнее, если у вас нет Palo Alto, их нужно собирать по разрозненным отчетам аналитиков или считать самостоятельно и вести собственные белые и черные списки. Но на github тоже попадаются тематические подборки, например, эта. Мы ее задействуем в дальнейшем при проработке правил по JARM.
Далее приведем некоторые описания правил, которые мы реализуем у себя. Также есть неплохой доклад от Splunk с примерами алгоритмов и правил мониторинга по хэшам JA3/JA3S. Доступен здесь. Правила можно адаптировать под любую SIEM.
Выявление признака конкретного вредоноса по хэшам JA3\JA3S. Вот, например, готовые значения для Emotet и TrickBot:
JA3 = 4d7a28d6f2263ed61de88ca66eb011e3 (Emotet) JA3S = 80b3a14bccc8598a1f3bbe83e71f735f (C2 Server Response) JA3 = 6734f37431670b3ab4292b8f60f29984 (Trickbot) JA3S = 623de93db17d313345d7ea481e7443cf(C2 Server Response)
Выявления нового хэша JA3, ранее не появляющегося в сети.
Список клиентского ПО в любой сети, как правило, достаточно статичен, и, если появится что-то новенькое – это однозначно повод разобраться. Правда, это может быть новая версия уже известного ПО, тогда ее нужно добавить в белый список.
Выявления хэшей JA3 не из белого списка.
Общее правило, которое позволит обратить внимание на любую активность, которая явно не помечена заранее как разрешенная. Сюда могут попасть, как новые ранее неизвестные клиентские устройства или приложения, так и вредоносы, попавшие к вам в сеть. В любом случае – трекать это стоит.
Выявления хэшей JA3\JA3S из чёрного списка.
Это правило нацелено на выявление хэшей заведомо вредоносного ПО.
Выявление обращений к C&C по хэшам JARM.
При выявлении обращения к TLS-серверу, неизвестному нам или ранее не появляющемуся в логах, необходимо посчитать его JARM хэш (можно вручную, можно скриптом или с использованием SOAR), при совпадении с хэшем, соответствующим известному C&C серверу, блокируем соединение, изолируем хост и расследуем инцидент.
Выявление JA3 хэшей, не характерных для системы.
При появлении на хостах с Windows JA3 хэшей, характерных для Linux или смартфонов (Android/IOS), стоит обратить внимание на такие хосты. Это может являться признаком работы вредоносов (ну или запущенного эмулятора/виртуалки в режиме NAT). Кейс особенно заслуживает внимание, если выявлен на рабочей станции обычного пользователя, далекого от мира IT.
Выявление JA3 хэшей, характерных для разных браузеров одного семейства.
Сейчас достаточно сложно на один хост поставить две разные версии Firefox или Chrome (виртуальные машины в режиме NAT не в счёт). Такое выявление может свидетельствовать о том, что злоумышленники пытались адаптироваться под установленный софт, но после обновления софта не успели или забыли обновить свой Fingerprint. Хост лучше изолировать и провести расследование.
Выявление JA3 хэшей, характерных для популярных сетевых библиотек языков программирования.
Ни для кого не секрет, что сейчас ВПО пишется не только на C/C++. Часто встречаются образцы, которые написаны на Python или Golang. Стандартные библиотеки, такие как requests (для python) или http (для Golang), имеют характерные отпечатки в рамках нескольких версий. В случае выявления такого хэша на рабочем месте разработчиков, вероятно, это нормально. Но, если хэши «всплывут» на рабочем компьютере рядового пользователя, то точно следует провести тщательную проверку, так как с большой вероятностью это будет свидетельством активности вредоноса. Также стоит поддерживать списки актуальных JA3 хэшей для популярных сетевых библиотек, чтобы минимизировать ложные срабатывания.
Важно: Список хэшей JARM (и JA3S тоже) необходимо регулярно пополнять новыми выявленными C&C серверами, полученную самостоятельно или от сторонних исследователей.
При использовании средств защиты сети, которые умеют вычислять хэши JARM самостоятельно и на лету, соединения с серверами из черных списков можно и нужно блокировать автоматически.
В завершении хотим подчеркнуть, что развитие и популяризация технологии TLS Fingerprinting, по нашему мнению, совсем не за горами, и способствует этому внедрение TLS 1.3.
В версиях стандарта TLS до 1.3 у клиента была возможность сообщать, к какому серверу он хочет обратиться — SNI (Server Name Indication). Чаще всего в HTTPS для этого использовалось поле HOST, чтобы на одном IP и порту могли работать несколько HTTPS-сайтов. Соответственно и так, без всяких fingerprint, было видно, кто куда идет. Понятно, что речь идёт про легитимные обращения, атакующие всегда могли подделать SNI.
В стандарте TLS 1.3 появилась возможность шифровать имя запрашиваемого сайта – Encrypted SNI (ESNI), и безопасники потеряли возможность видеть, куда идёт обращение.
Правда ESNI уже запретили в Китае, и были попытки блокировок в России. Однако ESNI стал часто встречаться, в том числе в инструментах злоумышленников, и без TLS fingerprinting становится сложно понимать, куда происходят обращения в сети.
Авторы статьи:
Михаил Кравченко, SOC-аналитик;
Александр Минин, руководитель направления Threat Intelligence @AAMinin;
Анна Шестакова, руководитель направления мониторинга ИБ.