О беззащитности сертификатов
Как работает электронная подпись? Берётся этот самый документ и прогоняется через хэш-функцию. У хэш-функции же есть две особенности
Зашифровал и спи спокойно? Не совсем так. В одном из своих блогов пользователь cat_mucius предложил животрепещущий вопрос о сертификатах. Один из них настоящий, другой – поддельный, при этом подпись у них одинакова. Далее - текст автора, который мы старались сохранить максимально оригинальным.
Краткая напоминалка, как это всё работает: сертификат – это электронный документ, удостоверяющий в сети кого-то или что-то: вебсайт, компьютер, юзера, адрес мейла. Для того, чтобы этому документу кто-то доверял, надо, чтобы он был подписан каким-то гарантом, к которому доверие уже есть. Такими гарантами выступают фирмы вроде VeriSign и Comodo, которые этим и занимаются – продают сертификаты. Называют их CA (certification authorities).
Как работает электронная подпись? Берётся этот самый документ и прогоняется через хэш-функцию. У хэш-функции же есть две особенности:
● для каждого значения на входе она должна выдать уникальное значение на выходе. В идеале, не должно быть двух разных наборов данных, для которых функция выдаст одинаковый хэш. Ситуация, когда такое всё же происходит, называется collision и говорит о том, что функция плоха;
● из хэша на выходе не должно быть возможности узнать, что было «скормлено» функции на входе.
Авторы схемы защиты вируса Gauss использовали вторую особенность, здесь же нас интересует первая.
Итак, берётся сертификат и вычисляется его хэш. После чего CA, что подписывает сертификат (скажем, VeriSign), шифрует его своим секретным ключом. Результат шифрования – это и есть электронная подпись, которая прилагается к сертификату. Тот же, кто хочет подпись проверить (скажем, браузер):
● вычисляет хэш по тем же данным;
● расшифровывает подпись открытым ключом того, кто её зашифровал;
● сравнивает результат.
Если в сертификате или подписи был изменён хотя бы один бит, то сравнение проваливается, и значит, подпись поддельная, и доверять ей нельзя.
Нетрудно заметить, что если у двух сертификатов будет одинаковый хэш, то и результат шифрования тайным ключом удостоверителя выйдет одинаков. Если я могу взять сертификат, удостоверяющий сайт https://mail.google.com/, и составить свой с таким же именем и таким же хэшем, то мне совершенно необязательно знать секретный ключ фирмы VeriSign, подписавшей сертификат Гугла – я могу просто скопировать подпись из сертификата Гугла и добавить к своему. После чего построить липовый сайт, выдающий себя за https://mail.google.com и перехватывать пароли. Именно поэтому требование неповторяющихся значений на выходе хэш-функции настолько важно: уникальный хэш = уникальная подпись.
Амбула
Так вот, в 2008-м группа из семи исследователей именно этого и добилась – сумела сгенерировать пару сертификатов так, чтобы хэш у них вышел одинаковый. После чего подсунула один из них на подпись к одному из CA – фирме Equifax / GeoTrust. Поскольку критериям CA сертификат вполне удовлетворял (несмотря на указанное в нём имя сайта i.broke.the.internet.and.all.i.got.was.this.t-shirt.phreedom.org), то GeoTrust его автоматически подмахнула за малую мзду. После чего остался последний ход: подпись просто взяли и приставили ко второму сертификату, который GeoTrust не подписала бы. А не подписала бы потому, что второй был выписан не на какой-то там вебсайт, настоящий или липовый, а на дочерний CA, который автоматом наследует весь капитал доверия, которым располагает GeoTrust. То есть хозяева поддельного сертификата получили прекрасную возможность выписывать в свою очередь любые другие сертификаты, которым бы браузеры доверяли автоматически.
Выгорело дело, кстати, потому, что GeoTrust полагалась на хэш-функцию по нынешним временам слабую – MD5. Первую полноценную коллизию в MD5 нашли ещё в 2004-м, но от того, чтобы просто найти два каких-то куска информации с одинаковым хэшем и до того, чтобы подобрать таким образом два куска нужной информации – дистанция огромного размера, и великолепная семёрка её преодолела. Всякие смачные детали, вроде вычислений на кластере из двухсот игровых консолей, можете почитать здесь, а я скажу о последствиях.
Что могло бы выйти
Последствий особых не было, разве что все СA бросились срочно менять MD5 на более стойкий алгоритм – SHA1. Но не было лишь потому, что авторы работы, из социальной ответственности, постарались собственные результаты всячески обезвредить. Во-первых, отказались разгласить ключ, с помощью которого могли бы выписывать дочерние сертификаты. Во-вторых, свой липовый сертификат предусмотрительно создали «дохлым» с рождения – со сроком жизни всего-то в август 2004-ого. И в третьих, просто не опубликовали некоторые секретные тонкости своей технологии.
Ну а если бы они решили пуститься во все тяжкие? Тут последствия могли бы быть огромные. Корневым сертификатам Equifax / GeoTrust доверяют подавляющее большинство компьютеров в мире (и твой собственный, дорогой читатель – не веришь, запусти certmgr.msc и полюбуйся на список в "Trusted Root Certification Authorities"), они поставляются вместе с операционными системами и браузерами, такими, как Firefox. Это значит, что дочернему – липовому CA они доверяли бы точно так же. А это открывает большие возможности, например, можно:
● выписать сертификат абсолютно на любой сайт – хоть на https://www.Facebook*.com/, хоть на https://www.paypal.com. После чего с помощью MitM-атаки или фишинга красть пароли, личную информацию, коммерческие секреты, просто деньги. Причём совершенно неважно, что Paypal сертификат выписал не GeoTrust, а вовсе даже VeriSign, и без всякого MD5;
● подписывать какой-нибудь malware. Сегодня туча программ подписывается каким-нибудь CA, чтобы юзер не боялся запускать их на своей машине. Windows при попытке поставить программку без подписи уже и предупреждение выкатывает... Так вот, берём любого троянского коня, любой spyware, и снабжаем его подписью – создано Microsoft. После чего хочешь – ботнет строй, хочешь – пароли кради, ну и деньги, опять же;
● перехватывать шифрованные каналы IPsec / VPN, можно ловить пароли от корпоративных WiFi-сеток;
● тот же malware рассылать подписанными / шифрованными мэйлами, чтобы спаморезки пропускали, и юзеры ловились, а то и проводить сложные мошеннические схемы с фальшивыми документами, но это скорее экзотика.
В общем, нехило оторваться можно. Причём в любую из этих ловушек не то что обычный юзер, но и админ-параноик вденется в полный рост. Что, кто-то помнит наизусть, какой CA выписал сертификат его банку?
Контрмеры
Хорошо, допустим, какие-то атаки бы удались – но потом началось бы расследование, и на свет божий выплыло бы существование липового CA. Насколько эффективно можно было бы свести возможность повторных атак на нет?
Вообще-то, не особенно. Основной способ борьбы с сертификатами, попавшими не в те руки, это “чёрные списки”, называемые CRL (certificate revocation list). Каждый CA публикует такой список, куда вносит сертификаты, которым призывает больше не доверять. В теории, браузеры или любые иные программы, желающие проверить сертификат, должны прочесть свежий CRL от того CA, что подписал сертификат и убедиться, что его серийного номера нет в списке.
То есть GeoTrust могли бы взять серийник нашего липового сертификата и забить его в свой список (вот он, кстати - https://crl.geotrust.com/crls/globalca1.crl).
Проблема в том, что способ этот очень ограничен:
- Как браузер вообще узнаёт, где искать CRL? Ответ: URL к нему публикуется прямо в том же сертификате, который браузер и хочет проверить. Бредово? В общем, да: основано это на предположении, что подделать сертификат нельзя, и призвано для защиты от иных сценариев (утечка ассоциированного с сертификатом секретного ключа, в основном).
Ну а наш поддельный сертификат адреса CRL вообще не содержит, и привет. И ни один браузер по этому поводу не заверещит, потому как ситуация эта нормальна: нет требования, чтобы любой сертификат непременно содержал линк к CRL. И даже если бы такое требование было, обойти его было бы легко: достаточно поставить неработающий линк, или работающий, но на битый CRL, или даже вполне целый, с отменной подписью законнейшего CA, только ... устаревший. Браузеры не склонны портить user experience предупреждающими воплями лишь потому, что не удалось прочесть самый свежий CRL, да ещё и не первый в цепочке.
- Тем не менее, есть способы, которыми CRL может дойти до потенциальных жертв:
2.1. Допустим, браузер открыл сайт, защищённый легальным сертификатом от того же Equifax, в ходе проверки скачал CRL и закэшировал его. Тогда, покамест CRL хранится в кэше, попытки подсунуть фальшак провалятся.
Проблема в том, что это чисто вероятностная штука.
2.2. Иные механизмы, такие, как Windows Update. После того, как иранский хакер смог заполучить сертификаты к набору разных важный сайтов два года назад, этот способ и использовался: вместе с заплатками к операционке на компьютер спускался CRL c номерами забаненных сертификатов и сами эти сертификаты.
Проблема в том, что далеко не все компы получают регулярно обновления.
- Не все браузеры вообще удосуживаются проверять CRL, поскольку это замедляет загрузку страниц – нужно дополнительно побегать по линкам и проверить подписи.
- Наконец, есть сценарии, когда проверить CRL просто невозможно. Например, когда сертификат используется для защиты доступа в сетку WiFi. Как клиенту убедиться, что сертификат не отозван, когда у него и IP-адреса ещё даже нет?
В общем, вполне можно ожидать, что даже месяцы и годы спустя обнаружения первых атак, процентов этак 20-30 компьютеров в мире принимали бы липовые сертификаты за милую душу.
Вот какая неприятность может произойти всего-то из того, что хэш-функция для двух input’ов выдала один output. :-)
Выводы
1. Всякий, имеющий дело с сертификатами с MD5 – да отряхнёт их прах с рук своих.
2. Да и на SHA1 лучше не полагаться. Если его завтра вот так ломанут, это будет ОЙ! – потому как почти все сертификаты подписываются с SHA1RSA.
3. Сисадмин, помни, что иерархия доверия – вообще-то – необходимое зло, призванное решать проблему scalability, а не нечто прекрасное само по себе. Если есть возможность установить точечное доверие к конечному сертификату, а не полагаться на цепочку подписей – стоит это делать.
4. Доверять стопроцентно одной лишь технологии никогда не стоит. Защищать передачу юзерского пароля одним лишь SSL – плохая идея, лучше использовать дополнительную схему типа digest / NTLM / Kerberos, даже если обмен идёт по шифрованному каналу.
5. Нужен способ проверки CRL-ей и цепочек доверия сверху вниз, от корневого CA, а не наоборот. Логичный кандидат для этого, кстати, есть – DNSSEC.
6. PKI чрезмерно полагается на предположение, что подделать подпись нельзя, и должен быть передизайнен с дополнительными защитами.
Источник: https://cat-mucius.livejournal.com
* - организация, признанна экстремистской на территории РФ
Комментарии 12
Если сходить из того, что проверка будет осуществляться по отпечатку (хешу), а не по полному телу сертификата, а также из того, что отпечатки могут подвержены коллизиям (что сложно достичь), то такой возможности нет.
Если вести белый список сертификатов, и сравнение с этим списком выполнять по полному телу сертификата, а не по отпечатку - то возможность есть.
Также можно выполнять мониторинг. Допустим, выполняем мониторинг корректности отсоединённых подписей. Раз в неделю, проверить все электронные подписи - извлечь сертификаты из них, сопоставить эти сертификаты с белым списком (например, списком сертификатов, который сопоставлен списку пользователей информационной системы), сравнение выполнять сначала по отпечатку, а потом по телу сертификата.
При этом выполнять проверки на:
Аналог периодической графологической экспертизы.
А что касается шифрования. То для успешного перехвата трафика есть более простые способы, чем искать коллизии в функциях хеширования. Защищённое соединение часто реализуется неверно, неполностью. Сайт позволяет работать и по https и по http. Конечный пользователь может и не заметить, если его перенаправит с https на на http (третья сторона, прослушивающая трафик, может предложить пользователю использовать незащищёнынй протокол). Для выявления таких моментов есть расширения к браузерам, как HTTPS Everywhere (но доверие к расширениям браузеров - такой же вопрос, как и доверие к удостоверяющим центрам и собственным чувствам). Коротко об ошибках использования SSL можно посмотреть в выступлении: "Как разработать защищенное веб-приложение и не сойти при этом с ума" (Владимир Кочетков, ведущий специалист группы анализа защищенности веб-приложений Positive Technologies) http://www.ptsecurity.ru/ics/Kak_razrabotat_zaschischenoe_web-prilojenie_i_ne_soiti_pri_etom_s_uma.pdf, см. раздел "Защищенность транспортного слоя".
Monk, вы прямо как разработчики Яндекс.Диска:
- А как нам уникально идентифицировать файл?
- Хешом, конечно, md5, например.
- А вдруг коллизия будет?
- Ну тогда давайте добавим еще размер файла.
- А вдруг все равно коллизия? Я тут посчитал вероятность. Мало ли чего, вдруг случится.
- Ну тогда давайте сделаем размер файла и два хеша: md5 и sha1!
Куда уж проще - поменять практически все ПО, работающее с сертификатами как на клиентской, так и на серверной стороне...
Скорее у него меньше широко известных уязвимостей. Просто потому, что его исследовали всяко меньше, чем два последних перечисленных.
Я не к тому, что комбинация SHA-1 + MD5 плоха. Нет, она очень хороша, но уж больно забавно это выглядит. На докладе по новому API Яндекс.Диска реально смеялся весь зал.
Я думал в его сторону. Но алгоритм довольно молод и очень мало исследований по его безопасности.
Уязвимости в хэш-алгоритмах и их реализациях очень сложно коррелировать с надежностью сертификатов и доверием к TLS. Все-таки малореально используя уязвимость хэш-функции ненарушить цепочку сертификации.
Нет, это будет крах всей системы доверия на базе PKI. Но как это сделать практически!?
Действительно, ошибок очень много :-)
Все-таки, хэш в сертификате лишь скромная часть технологии цифровой подписи, а не основной механизм защиты в модели доверия PKI. Не надо уязвимостями забугорных хэш-функций пугать людей! Злоумышленнику гораздо проще добиться установки "левого" корня - вот что важно :-)
1. Самое простое. Перенаправить пользователя с защищённого соединения на незащищённое. Пользователь набирает в адресной строке https://почта, ему в ответ приходит 302 код и предложение перенаправления на http://почта. Для этого сайт должен поддерживать https для галочки - опционально (так многие и делают, к сожалению).
Так как есть продвинутые пользователи, которые заметят, что адресная строка изменилась. То для них придумывали такое - замена favicon сайта на иконку с замком, мол, соединение всё ещё защищённое. На что разработчики браузером придумали следующее - перестали отображать favicon в адресной строке (хотя, уже не помню - отображалось ли раньше, IE8 точно отображает, а на счёт лидеров - не помню). А факт наличия https стали выделять иначе, например, зелёная подсветка в Chrome.
2. Также простое. Если контроллировать канал. Стать для клиента ssl-proxy. Шифровать трафик между клиентом и собой (своим, недоверенным сертификатом - все обратят на это внимание, но после того, как окажется, что все сайты стали с битыми сертификатами, то пользователь согласится работать по битому). Расшифровывать у себя (что естественно). Пересылать запросы клиента узлам, к которым обращается клиент. Или можно аналогично варианту 1 ответить клиенту, что надо перейти на http. Даже если узел не поддерживает http, а поддерживает только https, то при наличие возможности контроля канала, клиент об этом не узнает. SSLstrip.
3. Дать клиенту свой доверенный сертификат. Например, Mozilla Firefox при получении ответа с content-type == application/x-x509-ca-cert отображает диалог установки сертификата в список браузера. А какую кнопку нажимает пользователь в типичном диалоге? Да - кнопку Ок. Даже если таких пользователей окажется меньшинство - такое сделать можно, для меньшинства.
Далее - дело техники.
4. DLP-системы (полу-легальный MITM). Для некоторых железячных DLP-решений, некоторые (некоторый) удостоверяющие центры запросто выдавали сертификаты промежуточных удостоверяющих центров. А имея промежуточный сертификат и закрытый ключ, DLP, в целях прелюстрации, уже анализирует трафик. Канал DLP<->клиент шифруется на ключе, который генерируется для посещаемого узла на лету. Канал сайт<->DLP шифруется так, как захочет сайт (для сайта DLP - обычный клиент). Удостоверяющий центр уличённый в такой деятельности пожурили, но он работает всё ещё.
5. SSL можно и расшифровать. Например, сайт принимает запросы пользователя малыми порциями и отправляет данные малыми порциями. Формат, допустим, известен. При передаче трафика используется сжатие. Сжатие добавляет определённые синнатуры в каждый запрос и ответ (как заголовок архива). Значит для успешной расшифровки пакета, содержащего токен пользователя надо добиться того, что при расшифровке нескольких первых байт пакета получилась сигнатура сжатых данных. Это требует времени. Но если пользователь сидит на узле долго, то время есть.
И, вообще, раз есть контроль над каналом - есть тысячи вариантов. Например, можно ответить на запрос файлов обновления для популярного ПО (так, у Notepad++ небезопасный механизм обновления), И надеяться, что используется административная учётная запись.
Написаное мною выше - результат сложной смеси из эндорфинов (тренировка), избытка кислорода (прогулялся потом), усталости (не спал долго) и переизбытка молчания (не сказал то, что должен был сказать), и может рассматриваться исключительно как художественный текст лишенный всякого смысла.
Ага, вспомнил. Вот здесь есть разбор с картинками: http://habrahabr.ru/post/111714/
Был еще случай, когда удалось сымитировать сертификат Google, но там тоже не было прямого взлома существующих сертификатов.
1. В защищенных системах всегда применяется двусторонняя аутентификация для борьбы с MITM.
2. Защита начинается с защиты корневого сертификата (и соответствующего хранилища корневых сертификатов), как базового элемента инфраструктуры.