Злой и страшный BEAST
Некоторое время назад в сети появилась информация, что два исследователя Rizzo и Duong придумали атаку на SSL/TLS, которую назвали грозным именем BEAST, что означает Browser Exploit Against SSL/TLS. В данной заметке мы постараемся разобраться что к чему и понять, так ли страшен BEAST на самом деле.
Режим CBC.
Известно, что самый простой способ зашифровать кусок данных блочным шифром – разбить на блоки, удобные для данного блочного алгоритма, и зашифровать каждый блок в отдельности. Такой режим работы блочного шифра называется ECB (Electronic CodeBook, по нашему "режим простой замены"). Этот режим обладает некоторыми недостатками, а именно 2 одинаковых блока открытого текста переходят в 2 одинаковых блока шифрованного текста и, таким образом, в шифртекст просачивается информация об открытом тексте. Это отлично проиллюстрировано на картинке в статье из википедии. Чтобы избежать подобных недостатков, были разработаны другие режимы работы, один из которых называется CBC (cipher-block chaining). Понять принцип его функционирования можно глянув на картинку ниже.

Если кратко, то каждый блок открытого текста (кроме первого) побитово складывается по модулю 2 (XOR) с предыдущим результатом шифрования. Для первого блока используется вектор инициализации, который обычно передается в открытом виде. Более формально процесс описывается следующим уравнением:
C[i_] = E(Key, C[i-1] xor M[i_])
в котором E - функция зашифрования одного блока в режиме ECB, C[i] – блок шифртекста, M[i] – блок открытого текста. Для первого блока:
C[0] = E(Key, IV xor M[0])
где IV - вектор инициализации.
Использование CBC в SSL/TLS.
Все описанное выше подходит для зашифрования одного большого массива данных, состоящего из некоторого количества блоков. Тем не менее, SSL/TLS осуществляет шифрование на канальном уровне и ему приходится обрабатывать серии массивов данных, имеющих определенную структуру (стандартные поля и заголовки вышестоящих по стеку протоколов и т.д.). В этом случае возникает два пути применения CBC:
1. Считать каждый массив данных независимым, генерировать новый вектор нициализации и осуществлять зашифрование, как было описано ранее.
2. Считать все данные большим потоком, который по кускам передается функции зашифрования, и при поступлении нового блока данных просто продолжать применять алгоритм. То есть последний зашифрованный блок предыдущего массива будет вектором инициализации для первого блока следующего массива (срочно смотри схемку CBC
).
SSLv3 и TLS 1.0 используют второй метод, что не есть хорошо, так как в этом случае возникают некоторые проблемы безопасности.
Проблемы безопасности.
Пусть у нас есть защищенный канал связи между Алисой и Бобом, а мы просто наблюдаем за каналом. Пусть у нас есть техническая возможность заставить Алису зашифровать что-нибудь, и пусть мы знаем, что пароль Алисы передается в i-том блоке каждого передаваемого куска данных (блок M[i]). Будем пытаться угадать пароль Алисы.
Наше предположение что пароль это блок P. Теперь, если мы знаем, что блок M[i] будет зашифрован при участии вектора инициализации X, то вместо M[i] мы заставляем Алису зашифровать
X xor C[i-1] xor P
В этом случае:
E(Key, X xor X xor C[i-1] xor P) = E(Key, C[i-1] xor P)
Если пароль мы угадали, что
E(Key, C[i-1] xor P) совпадет с C[i] от предыдущего сообщения. Отметим, что угадать таким образом пароль – невероятно сложная задача, но Rizzo и Duong придумали, как свести угадывание всего пароля к последовательному угадыванию каждого его байта используя некоторую структурность веб-запросов, а также возможности Web Sockets.
Атака Rizzo/Duong-а.
Представим, что атакующий имеет возможность влиять на процесс разбиения данных на блоки. Пусть пароль Алисы составляет всего 8 байт и мы по прежнему пытаемся его угадать. Представим, что протокол обязывает передавать информацию в следующем формате:
username:alice_password:********,
где звездочки это пароль. Мы, как атакующая сторона, заставим комп Алисы разбить данную структуру на блоки следующим образом:
username:a | lice_password:* | *******
теперь во втором блоке при помощи предыдущей атаки угадываем 1 байт (всего-то максимум 256 возможных вариантов). Когда угадаем первый байт, сдвинем структуру разбиения на байт вправо, и будем угадывать еще 1 байт и так далее. Будем сдвигать, пока не угадаем весь пароль. Остается только понять, как найти такую ситуацию на практике. Тут то на помощь приходят веб-сокеты.
Эксплуатация Web Sockets.
Важно помнить, что если мы переходим по ссылке на сайт, например example.com, наш браузер автоматически посылает вместе с запросом все связанные с этим сайтом cookie. Мы как атакующая сторона, естественно хотим эти cookie восстановить.
Пусть Алиса, заходит на наш сайт www.attacker.com, а нас интересуют ее cookie от google.com. Так как Web Sockets позволяют посылать межсайтовые запросы, мы при помощи Java Script на нашей странице инициируем HTTPS соединение c google.com. В соответствии с протоколом Web Sockets в канал связи браузером будет передано что-то типа
Client->Server:
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: <a href="http://example.com">http://example.com</a>
Cookie: 0123456789abcdef
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13а в ответ придет:
Server->Client:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chatпри этом поле Origin мы указываем сами при создании Web Socket, что в частности нам позволяет изменять его длину и, следовательно, влиять на разбиение данных на блоки. Вся атака сводится к тому, что теперь мы будем угадывать каждый байт cookie по отдельности просто наблюдая за каналом связи и постоянно создавая веб-сокеты с новой (увеличенной на байт) длиной поля Origin.
Вот и все. В заключение хочу сказать, что эта атака является ярким примером того, что использование на каждом этапе проектирования системы стойких и надежных компонентов не избавляет нас от возможных ошибок. В данном случае неправильный выбор стратегии использования режима CBC привел к Epic Fail.
На английском про BEAST можно почитать тут.
Надеюсь было понятно 
Evgenij
evgenij.minsk@gmail.com
- Evgenij's блог
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
- 958 просмотров



Комментарии
3 комментария(ев)Дата: ЧТ, 20/10/2011 - 17:32
Да, кстати на ту же тем в ноябрьском хакере будет статья. Я не знаю кто ее автор, но в этом плане VR хакера догнал и перегнал
Дата: ЧТ, 20/10/2011 - 19:25
мне еще интересна была тема по поводу атаки на заголовок пакета (сообщения), вроде на VR проскакивала эта тема, но вскользь.
Дата: ЧТ, 20/10/2011 - 21:53
Надо посмотреть, мне самому было бы интересно разобраться!
Вообще эта пара исследователей в прошлом наделала много шума обнаружив уязвимость в обработке ошибок шифрования в .NET Framework 4.0 и ниже (да и многих других web-фреймворках), что привело к созданию атаки Padding Oracle Attack.