Перейти к содержимому
New

DeepSeek V4.1 Flash free for 7 days: 10M tokens a day after a top-up of $10 or more. Until Nov 30.

How it works

Certificate Transparency: как найти все сертификаты, выпущенные для вашего домена

Как журналы Certificate Transparency записывают публичные сертификаты TLS и как изучить результаты crt.sh для своего домена, не обращаясь к его хостам.

Начальный8 мин чтенияАвтор: NotHoly

Что такое Certificate Transparency

Certificate Transparency (CT) — это публичный реестр сертификатов TLS. Когда удостоверяющий центр (CA) выпускает публично доверенный сертификат, он записывает его в один или несколько журналов CT. Читать журналы может кто угодно, а незаметно их отредактировать не может никто. Владельцу домена это даёт историю публичных сертификатов для имён в его домене с возможностью поиска, включая сертификаты, запрос которых никто в команде не помнит.

Протокол описан в RFC 9162, «Certificate Transparency Version 2.0», опубликованном в декабре 2021 года. Он заменяет исходную спецификацию RFC 6962. Перед цитированием проверьте строку статуса. RFC 9162 имеет статус Experimental и к спецификациям Internet Standards Track не относится, о чём сказано в самом RFC. Тем не менее он остаётся справочником по работе журналов, и браузеры опираются на тот же дизайн.

CT ничего не шифрует и сама по себе сервер не защищает. Это механизм видимости. Он показывает, какие сертификаты выпущены, когда они записаны в журнал и какие имена покрывают. Работает ли хост, что он отдаёт и кто им управляет сегодня, из него не узнать.

Почему каждый публичный сертификат попадает в журнал

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

Проект CT объясняет порядок действий на странице о принципах работы https://certificate.transparency.dev/howctworks/. В упрощённом виде:

  1. CA готовит предсертификат: запись в форме сертификата, которую браузеры настоящим сертификатом не считают.
  2. CA отправляет предсертификат в один или несколько журналов CT. Каждый журнал возвращает Signed Certificate Timestamp (SCT), подписанное обещание включить запись.
  3. CA выпускает финальный сертификат с приложенными SCT, чтобы браузер мог проверить, что сертификат записан в журнал.
  4. Браузер проверяет SCT. Браузеры вроде Chrome и Safari требуют этого для публично доверенных сертификатов.

Предсертификат решает проблему очерёдности. CA не может получить SCT для финального сертификата, сначала ничего не отправив в журнал, а браузер не должен принимать финальный сертификат без SCT. Предсертификат разрывает этот круг.

Журналы работают только на добавление. Записи можно добавлять, но нельзя удалять, изменять или вставлять задним числом. Каждый журнал ведёт дерево Меркла, которое позволяет любому проверить, что конкретный сертификат включён (доказательство включения) и что журнал со временем только рос (доказательство согласованности). Дерево описано в разделе 2 RFC 9162. Чтобы пользоваться данными, реализовывать его не нужно.

Защитникам важны две детали. Во-первых, гарантия относится к записи в журнал и ничего не говорит о доверии. Записанный сертификат может быть действительным, ошибочным или неправомерно выпущенным, и журнал не скажет, каким именно. Во-вторых, покрытие ограничено сертификатами от публично доверенных CA. Сертификаты частного CA обычно никогда не попадают в публичный журнал, поэтому чистый результат CT не снимает вопросов ко всей инфраструктуре.

Зачем CT защитникам

Снова и снова встречаются три применения.

Инвентаризация. Команды создают имена хостов для тестовых сред, маркетинговых страниц, интеграций с вендорами и старых проектов. Многие из этих имён так и не попадают в файл зоны DNS, который кто-то просматривает. Запрос сертификата оставляет запись, поэтому CT может выявить имена, пропущенные при инвентаризации.

Поиск сертификатов, которые никто не запрашивал. Если для вашего домена появился сертификат, который никто в команде не запрашивал, на него стоит посмотреть. Это может быть вендор, действующий от вашего имени, старая учётная запись, забытый провайдер или атакующий, получивший контроль над способом проверки. Сам по себе журнал не скажет, что именно, поэтому передайте вопрос тем, кто управляет DNS домена и учётными записями сертификатов.

Порядок в жизненном цикле. Истёкшие сертификаты остаются в CT. Эта история полезна. По ней видно, какие имена существовали, и можно найти выведенные из работы сервисы, у которых сохранились записи DNS.

Результат CT служит зацепкой, окончательным выводом он не считается. Имя может устареть, принадлежать вендору, оказаться wildcard, покрывающим много хостов, или появиться из-за опечатки. Каждую зацепку должен подтвердить владелец актива.

Что такое crt.sh

crt.sh — это публичный поисковый интерфейс к журналам CT. Его поддерживает третья сторона. Искать можно в браузере, а JSON можно получить, добавив к запросу output=json. Ваш запрос уходит в этот сервис, поэтому ищите только домены, которые вам разрешено обсуждать. Доменное имя относится к публичной информации. Название ещё не объявленного продукта или внутреннее имя хоста вводить в чужую поисковую строку не следует.

Существуют и другие сервисы поиска по CT. Результаты могут различаться между индексами и в разное время запроса, поэтому записывайте, каким сервисом вы пользовались и когда.

Лабораторная работа: просмотр сертификатов домена

Что понадобится

  • Браузер
  • curl и jq либо Python 3 как запасной вариант
  • Домен, которым вы владеете. Если его нет, возьмите example.com, домен, отведённый для примеров, как в этой работе.

Лабораторная работа только читает публичные данные CT. Вы не подключаетесь ни к одному из найденных хостов. DNS-запрос имени обращён к резолверу и подключением к хосту не считается, но дальше без разрешения владельца не заходите.

Шаг 1: посмотрите результаты в браузере

Откройте в браузере https://crt.sh/?q=example.com. Замените example.com своим доменом. Каждая строка соответствует одному сертификату. Прочитайте издателя, даты действия и перечисленные имена. Затем попробуйте wildcard-форму https://crt.sh/?q=%.example.com, которая запрашивает имена ниже домена. Сравните количество результатов в двух поисках.

Шаг 2: экспортируйте имена

Выполните:

bash
curl -s 'https://crt.sh/?q=example.com&output=json' | jq -r '.[].name_value' | sort -u | head -50

Конвейер состоит из четырёх частей. curl скачивает массив JSON с одним объектом на сертификат. jq -r '.[].name_value' печатает поле name_value каждого объекта без кавычек. В некоторых записях несколько имён, разделённых переводами строк, а sort -u убирает дубликаты. head -50 обрезает вывод, чтобы его было удобно читать.

На моей тестовой машине jq не установлен, поэтому запустить эту строку здесь не удалось. Ту же логику я выполнил на Python 3.12, предварительно скачав JSON через curl:

bash
curl -s -o crt.json 'https://crt.sh/?q=example.com&output=json'
python
import json
import sys

records = json.load(open(sys.argv[1], encoding="utf-8"))
names = set()
for record in records:
    for name in record["name_value"].split("\n"):
        names.add(name.strip())

for name in sorted(names)[:50]:
    print(name)

Сохраните это как crt_names.py и запустите командой python crt_names.py crt.json. Этот вывод получен 2026-11-08. crt.sh вернул HTTP 200 и 85 записей о сертификатах, в которых было 12 разных имён:

text
*.example.com
AS207960 Test Intermediate - example.com
dev.example.com
emudhra-lab.example.com
example.com
m.example.com
m.testexample.com
products.example.com
[email protected]
support.example.com
[email protected]
www.example.com

Выделяются три вещи. Wildcard *.example.com покрывает любой прямой поддомен, но не показывает, какие хосты существуют. Строка «AS207960 Test Intermediate - example.com» не имя хоста. Она выглядит как имя субъекта, скопированное из сертификата тестового CA. Записи [email protected] и [email protected] похожи на идентификаторы email из сертификатов, выпущенных для этой цели. Скрипт, который считает каждую строку именем хоста, создаст шум.

Порядок вывода sort -u зависит от локали, поэтому может отличаться от вывода Python. Важен набор имён.

Шаг 3: сравните имена с зоной DNS

Выгрузите имена от своего DNS-провайдера или из файла зоны, по одному полному имени в строке, в нижнем регистре, без точки в конце. Затем сравните два списка:

bash
LC_ALL=C sort -u zone-names.txt > zone.sorted
LC_ALL=C sort -u ct-names.txt > ct.sorted
LC_ALL=C comm -13 zone.sorted ct.sorted

comm -13 печатает строки, которые есть только во втором файле. Это имена, которые видны в CT, но отсутствуют в вашей зоне. Туда же попадут и wildcard, поэтому проверьте их вручную. Для полного сравнения уберите срез [:50] из скрипта Python перед записью ct-names.txt. На реальной зоне этот шаг не выполнялся, потому что зоной example.com я не управляю. С любым списком имён сравнение работает одинаково.

Некоторые имена легитимны, но находятся вне экспортированной зоны, например в другой зоне у того же провайдера или за CNAME. Считайте «нет в моём файле зоны» вопросом, находкой это ещё не будет.

Шаг 4: проведите триаж каждого имени

Находка Что это может значить Следующий шаг
Есть в зоне, сертификат действует Ожидаемо Запишите и идите дальше
Только в CT, сертификат истёк Выведенный из работы сервис или старое тестовое имя Уточните у владельца и обновите инвентаризацию
Запись wildcard Покрывает имена, которых может не быть в вашем списке Проверьте, какие из ваших имён она защищает
Произвольный текст или идентификатор email Это не имя хоста Уберите из инвентаризации, оставьте в заметках
Неизвестное имя, действующий сертификат Возможно, забытый сервис Спросите владельца. Не зондируйте хост
Сертификат от CA, которым команда никогда не пользуется Возможный неправомерный выпуск или проблема с учётной записью Передайте вопрос тому, кто управляет учётными записями DNS и CA

Шаг 5: сделайте запись

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

text
Domain:
Query and date (UTC):
Source and format (crt.sh, JSON):
Certificates returned:
Unique names:
Names matching the zone:
Names needing owner confirmation:
Owner contacted (who, when):

Частые ошибки

  • Запись в журнале как работающий сервис. CT фиксирует выпуск. Сертификат может существовать для хоста, выключенного много лет назад.
  • Игнорирование срока действия. Прежде чем поднимать тревогу из-за старого имени, проверьте дату not-after.
  • Вера в полноту списка. Отсутствие имени не доказывает, что его нет. Сертификаты частных CA обычно не появляются в публичных журналах, а имя может существовать в DNS без публичного сертификата. Сочетайте CT с записями DNS и собственной инвентаризацией.
  • Зондирование для подтверждения. Подтверждать должен владелец. Подключение к найденному хосту, сканирование его портов или запрос его страниц считается активной работой и требует разрешения владельца.
  • Публикация необработанного вывода. Имена хостов могут раскрыть внутреннюю структуру. Держите исходный список внутри отчёта и показывайте только тем, кому он нужен.
  • Доверие к одному поисковому инструменту без пометки. Записывайте, каким сервисом и когда пользовались, чтобы запрос можно было повторить.

Что дальше

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

Прочитайте разделы 2 и 8 RFC 9162. Раздел 2 посвящён деревьям Меркла, лежащим в основе журналов. Раздел 8 описывает стороны, которые их проверяют, включая мониторы, а для вашего домена важны именно они.

Далее, как написать первый отчёт по безопасности: статья показывает, как превратить такую зацепку в короткий райтап, который владелец актива сможет проверить и использовать.

Источники

Источники

  1. RFC 9162: Certificate Transparency Version 2.0
  2. How Certificate Transparency works
  3. crt.sh

Ещё по теме: OSINT и разведка

OSINT и разведка

OSINT с нуля: ИИ как второй пилот

Повторяемый процесс OSINT по цели, на которую можно смотреть: область, сбор по этапам, корреляция, а чат NotHoly планирует и подводит итог.

Начальный2 мин чтения

OSINT и разведка

Краулинг и сбор URL: gospider, gau, qsreplace

Соберите URL и параметры своей области: gospider, hakrawler, waybackurls и gau, затем фильтр через qsreplace и чат NotHoly.

Начальный2 мин чтения