Аудит качества ключей SSH пользователей GitHub
Перевод статьи - Auditing GitHub users’ SSH key quality
Автор - Ben Cox
Источник оригинальной статьи:
Если вы недавно получили электронное письмо об отзыве ваших ключей, то это из-за меня, и если у вас есть, вы должны действительно пройти и убедиться, что никто не сделал вам ничего страшного, так как вы открыли Вы сами для людей, которые совершают для вас очень плохие поступки в течение, вероятно, очень долгого времени.
Немного известной особенностью GitHub является возможность просмотра открытых ключей SSH, которые другие пользователи установили для авторизации на своей учетной записи (например, https://github.com/torvalds.keys).
Это отличная функция отладки и, кроме того, отличный способ делиться открытыми ключами SSH (например, когда вы даете кому-то учетную запись пользователя на вашем сервере, и вы доверяете GitHub не вмешиваться в содержимое).
Однако одним из других побочных эффектов этого является то, что это означает, что все могут видеть ваши открытые ключи, и, если кому-то это небезразлично, собрать обширную базу данных ключей SSH каждого.
Я попробовал сделать это в 2013 году, но обнаружил, что слишком много людей не используют GitHub в режиме SSH и поэтому не имеют установленных ключей. Однако на этот раз (с новой программой, использующей API событий) я обнаружил, что у большинства активных пользователей есть некоторые SSH-ключи.
Я начал запускать стример в 2014-12-27, и теперь 2015-01-09 у меня довольно много ключей:
mysql> SELECT COUNT(*) FROM `keys`; +----------+ | COUNT(*) | +----------+ | 1376262 | +----------+ 1 row in set (0.00 sec)
Теперь первое, что нужно проверить сколько людей не имеют ключей:
mysql> SELECT COUNT(*) FROM `keys` WHERE `key` = ''; +----------+ | COUNT(*) | +----------+ | 142180 | +----------+ 1 row in set (0.38 sec)
Это удивительно мало. Это означает, что только около 30% приверженных пользователей GitHub не имеют открытых ключей SSH в своей учетной записи.
Если разбить его на ключевые типы, мы увидим, что RSA является наиболее используемым (не удивительно, поскольку он уже давно является стандартом):
mysql> SELECT COUNT(*) as cnt,LEFT(`key`,17) as keytype FROM `keys` GROUP BY keytype ORDER BY cnt;
+---------+-------------------+
| cnt | keytype |
+---------+-------------------+
| 21 | ecdsa-sha2-nistp3 |
| 210 | ssh-ed25519 AAAAC |
| 336 | ecdsa-sha2-nistp2 |
| 502 | ecdsa-sha2-nistp5 |
| 27683 | ssh-dss AAAAB3Nza |
| 142180 | |
| 1205330 | ssh-rsa AAAAB3Nza |
+---------+-------------------+
7 rows in set (0.00 sec)
По-прежнему большое количество пользователей, имеющих ключи DSA, и довольно небольшое количество пользователей, имеющих ключи ECDSA.
Что касается всего остального, вот (наблюдаемая) ключевая доля битового возраста, используемая пользователями GitHub:
Путешествие вниз по страшному переулку
После этого я хотел выяснить, сколько ключей было опасно слабым до такой степени, что взлом был тривиальным.
Я написал программу для анализа всех ключей в базе данных и заполнения столбца «Биты» в базе данных.
То, что я нашел, было не так плохо, как могло бы быть, но все равно было довольно плохо. (Я отредактировал полные открытые ключи и полные имена пользователей.)
mysql> SELECT LEFT(Username,3),LEFT(`key`,30),Bits FROM `keys` WHERE Bits < 1023 AND Bits != -1 ORDER BY Bits ASC;
+------------------+--------------------------------+------+
| LEFT(Username,3) | LEFT(`key`,30) | Bits |
+------------------+--------------------------------+------+
| Mar | ssh-rsa AAAAB3NzaC1yc2EAAAABJQ | 256 |
| Gl2 | ssh-rsa AAAAB3NzaC1yc2EAAAABJQ | 256 |
| rdp | ssh-rsa AAAAB3NzaC1yc2EAAAABIw | 512 |
| MrM | ssh-rsa AAAAB3NzaC1yc2EAAAABJQ | 512 |
| pun | ssh-dss AAAAB3NzaC1kc3MAAABBAM | 512 |
| ryo | ssh-rsa AAAAB3NzaC1yc2EAAAABIw | 512 |
| ilj | ssh-dss AAAAB3NzaC1kc3MAAABBAO | 512 |
| del | ssh-dss AAAAB3NzaC1kc3MAAABBAI | 512 |
| meg | ssh-dss AAAAB3NzaC1kc3MAAABBAK | 512 |
| gal | ssh-rsa AAAAB3NzaC1yc2EAAAABJQ | 767 |
| gol | ssh-rsa AAAAB3NzaC1yc2EAAAABJQ | 767 |
| jnw | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 768 |
| ken | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 768 |
| txc | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 768 |
| Pha | ssh-rsa AAAAB3NzaC1yc2EAAAABIw | 768 |
| too | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 768 |
| hir | ssh-dss AAAAB3NzaC1kc3MAAABhAO | 768 |
| lur | ssh-rsa AAAAB3NzaC1yc2EAAAABIw | 768 |
| lik | ssh-dss AAAAB3NzaC1kc3MAAABhAN | 768 |
| mku | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 768 |
| tra | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 768 |
| mas | ssh-dss AAAAB3NzaC1kc3MAAABhAO | 768 |
| fox | ssh-rsa AAAAB3NzaC1yc2EAAAABJQ | 768 |
| and | ssh-rsa AAAAB3NzaC1yc2EAAAABIw | 768 |
| aus | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 768 |
| Sky | ssh-rsa AAAAB3NzaC1yc2EAAAABIw | 768 |
| coc | ssh-dss AAAAB3NzaC1kc3MAAABhAI | 768 |
| coc | ssh-dss AAAAB3NzaC1kc3MAAABhAI | 768 |
| coo | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 768 |
| Vis | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 768 |
| Vis | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 768 |
| sai | ssh-dss AAAAB3NzaC1kc3MAAABhAJ | 768 |
| and | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 768 |
| Mat | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 768 |
| x89 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 768 |
| nao | ssh-dss AAAAB3NzaC1kc3MAAABhAO | 768 |
| exp | ssh-dss AAAAB3NzaC1kc3MAAABhAJ | 768 |
| Ric | ssh-rsa AAAAB3NzaC1yc2EAAAABIw | 768 |
| bil | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 768 |
| kat | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 768 |
| Tyr | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 768 |
| jac | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 768 |
| asu | ssh-rsa AAAAB3NzaC1yc2EAAAABIw | 768 |
| bou | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 768 |
| bou | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 768 |
| bey | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 770 |
| ser | ssh-rsa AAAAB3NzaC1yc2EAAAABIw | 799 |
| akD | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 800 |
| ccw | ssh-rsa AAAAB3NzaC1yc2EAAAABJQ | 919 |
| sky | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 1000 |
| dtg | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 1000 |
| phi | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 1000 |
| phi | ssh-rsa AAAAB3NzaC1yc2EAAAADAQ | 1000 |
+------------------+--------------------------------+------+
53 rows in set (0.34 sec)
Здесь мне торчат 9 ключей. Есть 2 ключа с 256 битами и еще 7 с 512.
Известно, что 512-битные ключи менее чем за 3 дня. Основным примером этого является сломанный ключ подписи прошивки калькулятора Texas Instruments, позволяющий сообществу моддинга загружать любые прошивки, которые они хотят.
Я сам попытался создать 256-битный ключ и вычислить его, и процесс занял менее 25 минут от открытого ключа SSH до факторинга простых чисел (на сегодняшнем стандарте на подпроцессорном процессоре, а затем еще несколько минут до преобразовать их обратно в ключ SSH, с помощью которого я мог бы войти в системы.
Этот риск не только реален, если кто-то собрал воедино лучших математиков или суперкомпьютеров, и 256-битный ключ, который я учел, был учтен на i5-2400 за 25 минут.
Ошибка Debian снова кусается
После того, как я понял, что у меня есть база данных открытых ключей большинства пользователей GitHub, я вспомнил об ошибке Debian OpenSSH, которая произошла в мае 2008 года, когда источник случайности был скомпрометирован до такой степени, что система могла генерировать только один из 32k ключей в наборе.
Я использовал набор ключей g0tmi1k для сравнения с тем, что было в моей базе данных, и нашел очень большое количество пользователей, которые все еще используют уязвимые ключи, и, что еще хуже, имеют доступ к некоторым действительно большим и широким проектам, включая:
- Публичные репозитории Spotify (и любые частные репозитории, к которым имели доступ эти сотрудники)
- Публичные репозитории Яндекса (и любые частные репозитории, к которым у человека был доступ)
- Крипто библиотеки в Python
- Джанго
- Ядро питона
- публичные репозитории gov.uk (и любые приватные репозитории, к которым у человека был доступ)
- Couchbase (и любые частные репозитории, к которым у человека был доступ)
- Рубиновый драгоценный камень, который используется в большом количестве систем CI (компрометация этого означает компрометацию вашего сервера сборки и, возможно, вашей внутренней сети)
Я не проверял, смогу ли я потянуть какие-либо частные репозитории на них.
Самая страшная часть этого заключается в том, что любой мог просто перебрать все эти ключи, просто пытаясь войти в GitHub по SSH, чтобы увидеть баннер, который он вам дает.
Можно было бы с уверенностью предположить, что из-за низкого барьера входа для этого, что пользователи, которые имеют плохие ключи в своих учетных записях, должны быть скомпрометированы, и все, что позволило такой ввод ключа, могло быть взломано злоумышленником.
GitHub ответ
Хотя мне бы хотелось получить еще одну запись на странице охотников за головами , похоже, что GitHub не считает это чем-то подходящим. Я вижу, откуда они берутся, поскольку это, в основном, ошибка пользователя, однако мы обычно защищаем клиентов от таких ошибок, как, например, Amazon AWS, сканирующий GitHub для ключей API.
Я понимаю ответ (или, в данном случае, отсутствие формального), но я думаю, что на каком-то этапе компании должны иметь некоторую защиту для своих пользователей, которые делают глупости и обнаруживают то, что следует ожидать от сервиса (поскольку OpenSSH делает это для вас самого) не происходящее должно быть помечено как проблема безопасности.
Лента новостей
[27 декабря 2014] Сканирование клавиш началось
[28.02.2015] Раскрыта проблема с младшими битами для однорангового участника на GitHub
[1 марта 2015] Обнаружены слабые ключи Debian (и раскрыты)
[5 мая 2015] Ключи Debian отозваны, электронные письма отправлены
[1 июня 2015] Отменены слабые и некачественные ключи
Я буду подробно описывать свои выводы в одном из моих следующих постов в ближайшие несколько недель / месяцев. Вы можете рассмотреть возможность использования RSS-канала сайта