Компания
88,92
рейтинг
10 ноября 2011 в 14:55

Разное → Первая работающая атака на SSL/TLS-протокол

Передаваемые по SSL-соединению данные можно расшифровать! Для этого Джулиану Риццо и Тай Дуонгу удалось использовать недоработки в самом протоколе SSL. И пусть речь пока не идет о полной дешифровке трафика, разработанная ими утилита BEAST может извлечь из зашифрованного потока то, что представляет собой наибольший интерес, — секретные кукисы с идентификатором сессии пользователя.



Что такое BEAST?


Всего 103 секунды потребовалось утилите BEAST (Browser Exploit Against SSL/TLS), чтобы расшифровать секретную кукису для входа в аккаунт PayPal. Посмотреть видеокаст можно на Youtube. Это не фейк. Живая демонстрация утилиты прошла в рамках конференции Ekoparty в Буэнос-Айросе, где исследователи выступили с докладом и показали работающий proof-of-concept. Используемая уязвимость действительно позволяет незаметно перехватывать данные, передаваемые между веб-сервером и браузером пользователя. По иронии судьбы атака эксплуатирует не какую-то новую найденную в протоколе брешь, а уязвимость SSL/TLS десятилетней давности, долгое время считавшуюся чисто теоретической. Но, как говорится, раз в год и палка стреляет, так что уж за десять лет уязвимость точно может перейти из разряда теоретических во вполне себе практическую.

Исследователи пока не публикуют утилиту, но делятся whitepaper'ом о проделанной работе. Программа состоит из двух элементов: снифера, который анализирует HTTPS-трафик, и специального агента, написанного на JavaScript и Java, который должен быть подгружен в браузере жертвы (для этого, к примеру, необходимо заставить пользователя открыть страницу с нужным кодом). Агент нужен для того, чтобы особым образом внедрять данные в тот же безопасный канал связи, который используется для передачи секретных кукисов. Как это позволяет дешифровать данные? Вот здесь вступает давно известная уязвимость SSL 3.0/TLS 1.0, на которой мы остановимся подробнее.


Проблема режима простой замены



Особенности шифрования SSL 1.0


Протокол SSL 1.0/TLS 3.0 позволяет использовать шифрование симметричным ключом, используя либо блочные, либо потоковые шифры. На практике, однако, обычно используется блочные шифры, и описываемая нами атака применима именно для них. Чтобы вникнуть в суть, нужно хорошо представлять себе базовые понятия.

Принцип работы блочного шифра заключается в отображении блоков открытого текста в зашифрованные блоки того же размера. Проще всего представить блочный шифр в виде гигантской таблицы, содержащей 2^128 записей, каждая из которых содержит блок текста М и соответствующий ему зашифрованный блок С. Соответственно, для каждого ключа шифрования будет отдельная такая таблица. Далее мы будем обозначать шифрование в виде функции:

C = E(Key, M), где M — исходные данные, Key — ключ шифрования, а C — полученные зашифрованные данные.

Блоки имеют небольшой размер (как правило, 16 байт). Поэтому возникает вопрос: как зашифровать длинное сообщение? Можно разбить сообщение на блоки одинаковой длины (те же самые 16 байт) и зашифровать каждый блок в отдельности. Такой подход называется режимом простой замены (ECB, Electronic codebook), но используется редко. На то есть причина: если мы будем шифровать два одинаковых по содержимому блока, то в результате и на выходе получим два одинаковых зашифрованных блока. Это влечет за собой проблему сохранения статистических особенностей исходного текста, которая хорошо продемонстрирована на иллюстрации. Для избегания такого эффекта был разработан режим сцепления блоков шифротекста (СВС, Cipher-block chaining), в котором каждый следующий блок открытого текста XOR'ится с предыдущим результатом шифрования:

Ci = E(Key, Mi xor Ci-1)

Во время шифрования первого блока исходный текст XOR’ится некоторым вектором инициализации (Initialization Vector, IV), который заменяет результат предыдущего шифрования, которого по понятной причине нет. Как видишь, все довольно просто. Однако эта теория описывает ситуацию для одного большого объекта, такого, например, как файл, который легко разбивается на блоки. В свою очередь, SSL/TLS является криптографическим протоколом — ему необходимо шифровать не отдельный файл, а серию пакетов. SSL/TLS-соединение может быть использовано для отправки серии HTTPS-запросов, каждый из которых может быть разбит на один или более пакетов, которые, в свою очередь, могут быть отправлены в течение как нескольких секунд, так и нескольких минут. В данной ситуации есть два способа использовать режим CBC:

  1. обрабатывать каждое сообщение как отдельный объект, генерировать новый вектор инициализации и шифровать по описанной схеме.
  2. обрабатывать все сообщения как будто они объединены в один большой объект, сохраняя CBC-режим между ними. Этого можно достичь, используя в качестве вектора инициализации для сообщения n последний блок шифрования предыдущего сообщения (n-1).

Внимание, важный момент. Протокол SSL 3.0/TLS 1.0 использует второй вариант, и именно в этом кроется возможность для проведения атаки.


Принцип действия CBC-шифра



Предсказуемый вектор инициализации


Атака строится на нескольких допущениях, но опыт создателей BEAST показал, что их вполне реально реализовать в реальной жизни. Первое допущение: злоумышленник должен иметь возможность снифать трафик, который передает браузер. Второе допущение: плохой парень каким-то образом должен заставить жертву передавать данные по тому же самому безопасному каналу связи. Зачем это нужно? Рассмотрим случай, когда между компьютерами Боба и Элис установлено безопасное соединение. К нам попадает сообщение, i-блок которого, как мы предполагаем, содержит, пароль Элис (или секретную кукису — неважно). Обозначим зашифрованный блок как Ci, соответственно Mi — ее пароль. Напомню, что Ci = E (Key, Mi xor Ci-1). Теперь предположим, что ее пароль — это Р. Главная идея в том, что мы можем проверить правильность нашего предположения!

Итак, мы знаем (так как смогли перехватить) вектор инициализации, который будет использоваться для шифрования первого блока следующего сообщения. Это, соответственно, последний блок предыдущего сообщения (в зашифрованном виде) — обозначим его IV. Мы также перехватили и знаем значение блока, идущего перед Ci — обозначим его Ci-1. Эти данные нам очень нужны. С их помощью мы особым образом формируем сообщение так, чтобы первый блок был равен следующему:

M1 = Ci-1 xor IV xor P

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

C1 = E(Key, M1 xor IV) =
= E(Key, (Ci-1 xor IV xor P) xor IV)
= E(Key, (Ci-1 xor P))
= Сi


Все, что я сделал, — это использовал полную форму записи M1, после чего упростил формулу, используя тот факт, что (IV xor IV) уничтожится (замечательное свойство XOR'а). Получается, что если наше предположение относительно пароля Элис верное (то есть M действительно равен P), то первый зашифрованный блок нового сообщения C1 будет равен ранее перехваченному Ci! И наоборот: если предположение неверное, равенства не будет. Так мы можем проверять наши предположения.


Передача запроса на сервер для реализации атаки на SSL



Особенности перебора


Если предположить, что у нас есть кучу времени и множество попыток, мы можем повторять эту технику вновь и вновь, пока не найдем верное значение M. Однако на практике блок M — 16 байтов в длину. Даже если мы знаем значение всех байт кроме двух, на то, чтобы отгадать оставшиеся байты, нам понадобится 2^15 (32 768) попыток. А если мы не знаем вообще ничего? Короче говоря, техника может сработать лишь в единственном случае — если у тебя есть некоторое ограниченное количество предположений относительно значения M. Еще точнее: мы должны знать большую часть содержимого этого блока — это единственный способ использовать описанную уязвимость. Тут есть одна хитрость.
Предположим, что злоумышленник может контролировать, каким образом данные будут располагаться в шифруемом блоке. Вернемся опять к примеру с Элис. Допустим, мы знаем, что длина ее пароля — 8 символов. Если злоумышленник может расположить пароль таким образом, чтобы в первый блок попал только один символ, а оставшиеся семь попали в следующий. Идея в том, чтобы передать в первых 15 байтах первого блока заведомо известные данные — тогда можно будет подобрать только последний байт, являющийся первым символом пароля. Например, допустим, что нужно отправить строку вида: «user: alice password: ********», где "********" — непосредственно сам пароль. Если злоумышленнику удастся передать строку так, чтобы она была разбита на следующие блоки "[lice password: *] [*******.........]", то подбор первого символа пароля уже не кажется невыполнимой задачей. Напротив, в худшем случае нам понадобится жалкие 256 попыток. А в случае особой удачи и вовсе одна :)! Подобрав первый байт, можно сдвинуть границу разбиения на один символ: то есть передавать в первом сообщении 14 заранее известных байт. Блок теперь будет заканчиваться двумя первыми байтами пароля, первый из которых мы уже подобрали. И опять: получаем 256 необходимых попыток для того, чтобы угадать второй его байт. Процесс можно повторять до тех пор, пока пароль не будет подобран. Этот принцип используется и в BEAST для подбора секретной кукисы, а в качестве известных данных используются модифицированные заголовки запроса. Подбор ускоряется за счет сужения возможных символов (в запросе можно использовать далеко не все), а также за счет предположений имени кукисы.


Всего 103 секунды потребовалось для расшифровки секретной кукисы PayPal



Реализация атаки


Впрочем, сама уязвимость и оптимизированный способ для выполнения дешифрования описаны уже давно. Что действительно удалось разработчикам BEAST, так это реализовать все необходимые условия для выполнения атаки:
  1. атакующий должен иметь возможность прослушивать сетевые соединения, инициированные браузером жертвы;
  2. у атакующего должна быть возможность внедрить агент в браузер жертвы;
  3. агент должен иметь возможность отправлять произвольные (более-менее) HTTPS-запросы;
В самом начале материала я уже говорил, что важной частью BEAST является так называемый агент, который сможет передавать нужные злоумышленнику запросы на сервер (по защищенному протоколу). Исследователи составили список различных технологий и браузерных плагинов, который могут выполнить это условие. Как оказалось, их довольно много: Javascript XMLHttpRequest API, HTML5 WebSocket API, Flash URLRequest API, Java Applet URLConnection API, и Silverlight WebClient API. Однако в первом приближении некоторые из них оказались непригодны из-за наличия ограничений, препятствующих реализации атак. В результате остались только HTML5 WebSocket API, Java URLConnection API, и Silverlight WebClient API. В момент, когда исследователи сообщили о своем баге вендорам, у них на руках был работающий агент на базе HTML5 WebSockets. Но технология эта постоянно развивается, а сам протокол постоянно меняется. В результате работающий агент банально перестал работать. Текущая версия BEAST, которую парни представили общественности, состоит из агента, написанного на Javascript/Java, и сетевого снифера.
Незаметно внедрить апплет или JavaScript пользователю на самом деле не является такой уж сложной задачей. Но остается небольшой нюанс — для того, чтобы скрипт или апплет могли отправлять данные по установленному жертвой соединению, необходимо обойти еще и ограничения SOP (same-origin policy, правило ограничения домена). Это важная концепция безопасности для некоторых языков программирования на стороне клиента, таких как JavaScript. Политика разрешает сценариям, находящимся на страницах одного сайта, доступ к методам и свойствам друг друга без ограничений, но предотвращает доступ к большинству методов и свойств для страниц на разных сайтах. Проще говоря, запущенный на одной странице клиент не сможет делать запросы к нужному сайту (скажем, Paypal.com). Чтобы обойти политику SOP, авторы нашли в виртуальной машине Java 0day-уязвимость и написали для нее работающий сплоит. Только не думай, что это позволяет читать существующие кукисы. Если бы это было так, тогда зачем нужен был весь этот сыр-бор с зашифрованным трафиком? Используя сплоит для обхода SOP, можно отправлять запросы и читать ответы сервера (в том числе ответы с новыми кукисами), но нельзя считывать существующие кукисы, которые сохранены в браузере. Разработчики делятся целой историей о создании агента в своем блоге.

Respect


В заключение хочется отметить огромный труд исследователей, которые не только сумели использовать уязвимость, забытую всеми десять лет назад, но также приложили много труда для того, чтобы заставить свою утилиту работать. В рамках этого материала мы довольно сильно упростили описания используемых техник, пытаясь передать основную идею. Но мы получили истинное удовольствие от прочтения детального документа от исследователей, в которых они в деталях рассказывают о реализованной атаке. Good job!


Масштабы проблемы


Итак, каковы же масштабы бедствия? Или иными словами — кто уязвим? Практически любой сайт, использующий TLS1.0, который является наиболее распространенным протоколом безопасности. Забавно, что после всей этой шумихи с BEAST, многие стали проявлять интерес к более новым версиям протокола — TLS 1.1 и выше. Но многие ли сайты уже сейчас поддерживают эти протоколы? Да практически никто! Посмотри на иллюстрацию. Даже несмотря на то, что TLS 1.1 уже пять лет, его используют единицы!



Другой вопрос: как обезопасить себя? На самом деле, паниковать нет смысла — уязвимость уже исправлена в большинстве браузеров. Но если паранойя берет верх, можешь попробовать отключить небезопасные протоколы в браузере (TLS 1.0 и SSL 3.0), а заодно и Java. Правда, не стоит в этом случае сильно удивляться, что многие сайты перестанут работать.


image
Журнал Хакер, Ноябрь (11) 154
Коллективный разум
.

Подпишись на «Хакер»
Автор: @gorl

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

  • +8
    Даже несмотря на то, что TLS 1.1 уже пять лет, его используют единицы!
    Дык в OpenSSL поддержки нет, вот и не используют.
    • 0
      В снапшотах версии openssl-1.0.1-stable поддержка TLS1.1 и 1.2 уже имеется.
      • +1
        В репах повсеместно 1.0.0 пока что. Будет доступна 1.0.1, начнут и серваки держать.
  • 0
    Версии протоколов SSL и TLS перепутаны в некоторых местах, надеюсь это только здесь, на бумаге все норм.
  • +2
    > На практике, однако, обычно используется блочные шифры, и описываемая нами атака применима именно для них.

    На большинстве сайтов с https, которыми я регулярно пользуюсь:

    Для аутентификации сообщений используется AES_256_CBC c SHA1, для обмена ключами используется DHE_RSA.
    Который хоть и является блочным, не должен быть подвержен уязвимости если я правильно понимаю её характер.

    > у атакующего должна быть возможность внедрить агент в браузер жертвы

    Почему бы ему тогда не стырить куку через этот агент?
    • +2
      Я так понял, что агент может быть с другого сайта. А прочитать чужую куку нельзя.
      • +3
        Но остается небольшой нюанс — для того, чтобы скрипт или апплет могли отправлять данные по установленному жертвой соединению, необходимо обойти еще и ограничения SOP (same-origin policy, правило ограничения домена). Это важная концепция безопасности для некоторых языков программирования на стороне клиента, таких как JavaScript. Политика разрешает сценариям, находящимся на страницах одного сайта, доступ к методам и свойствам друг друга без ограничений, но предотвращает доступ к большинству методов и свойств для страниц на разных сайтах. Проще говоря, запущенный на одной странице клиент не сможет делать запросы к нужному сайту (скажем, Paypal.com). Чтобы обойти политику SOP, авторы нашли в виртуальной машине Java 0day-уязвимость и написали для нее работающий сплоит. Только не думай, что это позволяет читать существующие кукисы. Если бы это было так, тогда зачем нужен был весь этот сыр-бор с зашифрованным трафиком? Используя сплоит для обхода SOP, можно отправлять запросы и читать ответы сервера (в том числе ответы с новыми кукисами), но нельзя считывать существующие кукисы, которые сохранены в браузере.

        Вообще через Java-аплеты и без всяких уязвимостей много лишнего делать можно. Если нашли одну уязвимость на установку кук, могли бы найти и другую на чтение… :-)
  • +5
    Скажите, если в браузере уже есть агент злоумышленника, что ему мешает просто скопировать куки?
    • +13
      тссс…
    • +8
      Подразумевается, что агент внедряется не с атакуемого сайта и что у него нет доступа к чужим кукисам.
  • 0
    Интересно что Paypal принимает регистрацию с мыльником на mailinator. Спасибо за статью, respect to Juliano and Thai.
  • +13
    Порадовало, что для того, чтобы обойти ограничения same-origin policy исследователи заодно нашли уязвимость в java машине и использовали её. Действительно, если уж находить уязвимости, то пачкой. Молодцы исследователи.
  • –2
    «— …и специального агента, написанного на JavaScript и Java, который должен быть подгружен в браузере жертвы…»

    Дальше не читал, сделайте это первой строкой текста, а то, дойдя до того места, я почти поверил.
    (ладно, читал я дальше, читал)
    С таким же успехом можно найти еще уязвимость в java или где-нибудь еще с запуском кода произвольного на жертве и скопировать что надо, так хоть с шифрованием возиться не надо.
    • +3
      в одно вкладке у вас открыт вконтактик с iframe приложением, в другой вы открыли paypal чтобы купить подарок девушке, с которой общаетесь в первой вкладке… нэ?
      • 0
        lashtal все правильно сказал. Внедренный левый яваскрипт тем более с явой — уже пропущенная уязвимость. Открыв «вконтактик с iframe приложением» Вы фактически доверили все куки (читай акк) от вконтактика создателям iframe приложения. А данная уязвимость просто расширяет зону доверия.

        Чтоб защититься от данной уязвимости совсем не обязательно ждать openssl 1.0.1. Достаточно:
        1) FF+noscript+request policy
        2) Юзайте платежные сайты (я.деньги, вебмани, пейпал и т.п.) в отдельном профиле броузера\отдельном броузере.
        3) Не юзайте вконтактикНа левые сайты лазайте из-под другого отдельного профиля броузера. Т.е.: один профиль основной, один — «платежный», один — «левак».

        Да-да, это сложно для рядового пользователя. Что ж, каждый сам себе злобный буратино. Но не стоит преувеличивать масштабы уязвимости.
        • 0
          Я конечно опоздал на два года :)
          Но смысл был в том, что вы доверили iframe не только куки контакта (это как раз понятно), но и возможность отправлять любую фигню в PayPal (правда, из-за проблемы с SOP).
          Это все еще выглядит невероятным стечением обстоятельств, но тем не менее уже реализуется хотя бы в лаборатории.
  • +4
    Не знаю как у вас, у меня давно во всех браузерах запрещена java. Я не знаю ни одного сайта, где она нужна, но зато знаю, что в ней куча дыр. К сожалению, аморальные маркетологи из сан/оракл впаривают свое решето всем пользователям без спроса при установке явы или явосодержащих программ. Вот кто они такие после этого?

    • НЛО прилетело и опубликовало эту надпись здесь
    • +1
      Например интернет-банки подписывают ЭЦП документы из браузера с помощью джавы.
      • 0
        Не так. Клиент-банки многих банков реализованы как java-апплеты. Ключи хранятся на е-токенах. Но популярный метод взлома — это формирование поручений в рамках клиента как клиент, прятать их от клиента и давать возможным проводить банку. Вопрос в том, что встроиться в систему.
      • 0
        А иначе практически никак. Служба кртиптографии должна общаться с токеном и браузером. На стороне браузера это либо Java Applet, который вызывает методы этой службы и пользуется ЭЦП (который должен бы быть на usb-токене), либо как-то так же с ActiveX. Браузер передаёт документ на подпись, подписанный документ отправляется на сервер.
        Можно было бы рассмотреть вариант с плагином для браузера, но там потенционально не меньше дыр.
    • –1
      А у меня мало того, что запрещена, так если даже разрешить — всё равно не работает ни на одном компе. IE8, Firefox 3.6, Firefox 5, Opera 11, Epiphany 3.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разное