[Перевод] Как мне удалось обнаружить уязвимость, связанную со слабыми ключами в Debian
Для новичков в сфере информационных технологий может быть открытием, что в следующем месяце мы отметим 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»
Как популярный и активно развивающийся сервис, 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 интенсивно развивал свой сервис.
Лучиано же нашёл время для глубокого погружения в проблему и её понимания.Тем не менее, похоже, что индустрии повезло, что нашёлся человек с нужными навыками, временем и энергией, который оказался в нужном месте в нужное время для того, чтобы внести значительный вклад.
Возможность углубиться в детальное изучение проблемы является роскошью, которую мало кто может себе позволить. Возможно, одним из недооценённых выводов является то, что нам всем стоит найти время для того, чтобы прислушаться к своему внутреннему голосу и уделить внимание тем моментам, которые вызывают у нас ощущение «что-то здесь не так».
Спасибо за внимание (: