Для новичков в сфере информационных технологий может быть открытием, что в следующем месяце мы отметим 16-ю годовщину одного знаменательного события: было выявлено, что в течение 18 месяцев пакет OpenSSL в Debian вырабатывал полностью предсказуемые приватные ключи, что в то время стало сенсационной новостью.

Недавно возникшая угроза, связанная с xz-stential (благодарю @nixCraft за привлечение внимания к этой проблеме), побудила меня вспомнить о собственном неожиданном опыте обнаружения серьезной уязвимости. Учитывая, что срок для юридического преследования, скорее всего, уже прошел, я решил поделиться своим опытом как примером того, как непредвзятое "хм, это странно" может привести к выявлению серьезных угроз безопасности — при условии, что у вас, конечно, есть время и терпение распутывать эту нить дальше.

Начнем погружение в историю

Мой рассказ берёт своё начало в марте 2008 года. В те времена я был частью команды Engine Yard (EY), компании, которая когда-то занимала лидирующие позиции в области хостинга приложений на Rails и внесла значительный вклад в развитие этого направления. Одним из наиболее запоминающихся достижений EY было предоставление поддержки небольшой, но перспективной платформе для хостинга кода, которую сегодня знают многие — предоставив бесплатную инфраструктуру в то время, когда она была всего лишь маленьким мигом в океане интернета.

Речь идёт, конечно же, о продукте, который теперь принадлежит Microsoft — GitHub.

GitHub появился на рынке вовремя со своим предложением, который многим пришёлся по вкусу, и благодаря этому стал быстро расти и расширять свою аудиторию. С ростом популярности приходят и новые проблемы, и одной из них, которую мы сегодня рассмотрим, было время авторизации через SSH. Так же, как и сейчас, GitHub обеспечивал доступ к размещённым репозиториям git через SSH-соединение с git@github.com и аутентификацией посредством открытых ключей. Для управления ключами использовался стандартный метод — файл ~/.ssh/authorized_keys, который со временем стал причиной проблем из-за неуклонно растущего количества ключей.

В процессе SSH-аутентификации система сканирует файл ~/.ssh/authorized_keys на наличие ключа, соответствующего предъявленному пользователем. Обычно этот последовательный поиск не вызывает затруднений, поскольку мало кто добавляет в файл больше нескольких ключей. Но что происходит, когда ключей становится слишком много?

"Разумный человек не добавит более нескольких ключей в ~/.ssh/authorized_keys"
"Разумный человек не добавит более нескольких ключей в ~/.ssh/authorized_keys"

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

Руководство Engine Yard было нацелено на обеспечение стабильной работы GitHub и, несмотря на то что проблема не касалась хостинга напрямую, выразило готовность помочь её решить. Почему-то великий и ныне покойный Эзра Зигмунтович решил направить GitHub ко мне, предоставив мне возможность погрузиться в эту проблему вместе с их командой. После обдумывания различных подходов мы пришли к мнению, что наименее плохим решением будет внесение изменений в OpenSSH, чтобы ключи искались в базе данных MySQL с индексацией по отпечаткам ключей.

Данное решение было принято не спонтанно — мы не подходили к этому как к лёгкому "давайте просто изменим OpenSSH и посмотрим, что будет". Мы осознавали, что такой подход мог бы стать катастрофическим, если что-то пошло бы не так, так что можете представить себе, насколько ужасны были другие опции. Мы приложили немало усилий для того, чтобы обеспечить безопасность при внесении изменений. В конечном итоге, нововведение было реализовано в начале апреля, и вуаля! Вход через SSH стал значительно быстрее и мы были уверены, что эта проблема не потревожит нас в ближайшем будущем.

Можно было бы подумать, что "внесение изменений в OpenSSH для ускорения массовой аутентификации через SSH" само по себе является достойной историей. Но нет, это было лишь начало.

Заряжаем чеховское ружье

Давайте отмотаем время назад к первым дням мая 2008 года, что было чуть менее чем через месяц после событий, описанных ранее. Я получил сообщение от члена команды GitHub, в котором указывалось, что пользователи каким-то образом получали доступ к чужим репозиториям через SSH. Учитывая, что мы недавно реализовали специальный патч для OpenSSH, влияющий именно на эту область, код, который я разработал, естественно стал главным подозреваемым. В связи с этим я был немедленно призван помочь в решении проблемы.

Их называют "обычными подозреваемыми" по определенной причине, но иногда ситуация разворачивается так, что в центре внимания оказывается кто-то вроде Кейзера Сёзе
Их называют "обычными подозреваемыми" по определенной причине, но иногда ситуация разворачивается так, что в центре внимания оказывается кто-то вроде Кейзера Сёзе

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

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

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

"Мы оказались в Зазеркалье, люди."
"Мы оказались в Зазеркалье, люди."

Как только мы с полной уверенностью исключили патч OpenSSH из списка возможных причин проблемы, моя роль в её решении фактически закончилась. Поскольку я не являлся сотрудником GitHub и в Engine Yard было множество других клиентов, нуждающихся в моей поддержке, я не мог активно участвовать в дальнейшем расследовании загадки повторяющихся ключей.

Тем не менее, команда GitHub продолжала взаимодействие с затронутыми пользователями и выявила одну общую черту: все они заявляли, что их системы работали на Debian или Ubuntu, на которых, предположительно, были сгенерированы их SSH-ключи.

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

Заряженное ружье стреляет

Когда было выпущено обновление DSA-1571-1, всё стало ясно. В результате хорошо задуманного, но катастрофического в своих последствиях исправления уязвимости в коде генерации случайных чисел OpenSSL, которое проводилось командой Debian, разработчик случайно сократил количество потенциальных ключей, доступных для генерации каждому пользователю, с "bazillions" до чуть более 32 000. Учитывая, что множество людей регистрировались на GitHub и многие, вероятно, следуя рекомендациям безопасности, генерировали уникальные ключи, неудивительно, что произошли перекрёстные совпадения ключей.

Можно легко представить ощущение "а-ха" среди тех, кто осознал проблему. Лично я испытал облегчение от того, что были найдены окончательные доказательства невиновности моего патча для OpenSSH. Тем не менее, я ещё не осознавал, насколько глубоко мне предстоит погрузиться в проблему уязвимых ключей Debian в будущем. Это включало управление огромной базой данных компрометированных ключей и их использование для выявления недобросовестного поведения сертификационных центров, среди прочего.

Извлеченные уроки

Не существует точной хронологии того, как Лучиано Белло выявил уязвимость, позже получившую обозначение CVE-2008-0166, но я предполагаю, что он столкнулся с ней задолго до её публичного раскрытия и, вероятно, до того, как она стала известна GitHub. Учитывая, что уязвимая версия Debian была выпущена за год до этого, у Лучиано было достаточно времени, чтобы заметить повторяющиеся ключи и начать расследование, которое в конце концов привело к решению загадки.

Такой же подход "что-то здесь не так" и последующее углублённое исследование привели к обнаружению недавней уязвимости в XZ. Однако ключевым моментом здесь является возможность посвятить себя такому тщательному расследованию.

Оглядываясь назад на моё столкновение с проблемой слабых ключей Debian, я осознаю, что не провел столь же глубокого анализа. Интересно размышлять о том, сколько времени пройдёт до того, как уязвимость была бы найдена, если бы Лучиано не сделал своего открытия. Возможно, команда GitHub продолжила бы своё расследование, и возможно, они или я в конечном итоге нашли бы её. Но у каждого из нас было множество других задач — я занимался поддержкой клиентов в Engine Yard, а GitHub интенсивно развивал свой сервис.

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

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

Спасибо за внимание(:

Комментарии (2)


  1. tchkEn
    16.04.2024 17:00
    +7

    Время. Вот пожалуй то что нельзя купить и его всегда не хватает на все задуманное. Постоянно приходится "обрезать" все в попытках успеть главное.


    1. numb13
      16.04.2024 17:00

      За деньги можно нанять кого-нибудь. Не обязательно всё делать самому.