воскресенье, 22 ноября 2015 г.

Разбор уязвимости DNS Каминского

Оригинал: Understanding Kaminsky's DNS Bug
Автор: Кори Райт (Cory Wright)

За последние дни всплыли подробности о природе уязвимости DNS, о которой Дэн Камински объявил две недели назад. Да, она настолько крупная и страшная, как и сообщалось.

Как вам, может быть, известно, Каминский согласовал объявление со многими крупными разработчиками программного обеспечения и обещал не раскрывать способ эксплуатации уязвимости до 6 августа, когда состоится ежегодная конференция специалистов по компьютерной безопасности Black Hat (чёрная шляпа) в Лас-Вегасе. У провайдеров было 30 дней, чтобы исправить их системы и защитить своих пользователей. Каминский также попросил членов сообщества по компьютерной безопасности воздержаться от публикации подробностей проблемы, пока не будет опубликовано официальное заявление. Возможно он попросил слишком многого, потому что уже через 13 дней проблема стала достоянием общественности.

Теперь стали известны подробности, а сам Каминский предоставил комментарии. Давайте изучим проблему и попытаемся понять, насколько она серьёзная.

Основы DNS

Для начала, нам нужно понять основы обмена данными DNS. Обычно имеется три действующих стороны:
  • ваш компьютер,
  • рекурсивные серверы DNS вашего провайдера, и
  • авторитативные DNS-серверы веб-сайта.
Авторитативные серверы DNS публикуют IP-адреса доменных имён. Рекурсивные серверы DNS общаются с авторитативными серверами DNS, чтобы найти адреса опубликованных ими доменных имён. Ваш компьютер общается только с рекурсивными серверами DNS, которые ищут для вас адрес доменного имени. Ваш компьютер и рекурсивные серверы DNS вашего провайдера представляют собой две разновидности клиентов, которые запрашивают информацию извне. Конечно, это упрощённое представление процесса, но для наших целей этого достаточно.

Давайте рассмотрим типичные DNS-запрос и ответ. Для этого мы воспользуемся доменным именем example.com и парой выдуманных серверов DNS. (Ненужные фрагменты вывода dig вырезаны).
$ dig @ns1.example.com www.example.com
;; ANSWER SECTION/РАЗДЕЛ ОТВЕТА/:
www.example.com. 120 IN A 192.168.1.10
;; AUTHORITY SECTION/АВТОРИТЕТНЫЙ РАЗДЕЛ/:
example.com. 86400 IN NS ns1.example.com.
example.com. 86400 IN NS ns2.example.com.
;; ADDITIONAL SECTION/ДОПОЛНИТЕЛЬНЫЙ РАЗДЕЛ/:
ns1.example.com. 604800 IN A 192.168.2.20
ns2.example.com. 604800 IN A 192.168.3.30
Здесь мы обратились к авторитетному серверу DNS, ns1.example.com, и спросили у него адрес www.example.com. Как можно видеть, ответ содержит IP-адрес www.example.com наряду с двумя другими наборами записей - авторитетными и дополнительными. Авторитетный раздел содержит список авторитативных серверов DNS для домена из запроса. Дополнительный раздел содержит IP-адреса этих серверов. То, что вся эта информация возвращается в одном ответе, имеет непосредственное отношение к недавней уязвимости.

Проверка зоны ответственности

Рассмотрим следующую аналогию. Предположим, что мы с вами путешествуем по скоростной автомагистрали и наша машина ломается. Я спрашиваю у вас телефонный номер ближайшей мастерской, а вы отвечаете: "Я не знаю их номер телефона. Вам нужно позвонить им, чтобы его найти." Но как узнать номер мастерской, если её номер ещё не известен?

Теперь представим ту же ситуацию применительно к DNS. Мы хотим найти адрес www.example.com, поэтому мы просим у корневого сервера DNS список DNS-серверов для .com. Корневой сервер DNS даёт нам список DNS-серверов .com, из которого мы берём один и спрашиваем у него список DNS-серверов для example.com. Если серверы .com просто ответят, что это ns1.example.com и ns2.example.com, мы окажемся в тупике. Мы хотели найти информацию об example.com, но по дороге узнали, что должны обратиться за ответом к DNS-серверам example.com. Чтобы решить проблему курицы и яйца, в дополнительном разделе предоставляются две записи "A", которые являются недостающим звеном. Они называются связующими записями.

Связующие записи - это обычные записи типа "A", которые предоставляются вместе с ответом. В ответе выше вполне могли оказаться посторонние записи:
$ dig @ns1.example.com www.example.com
;; ANSWER SECTION/РАЗДЕЛ ОТВЕТА/:
www.example.com. 120 IN A 192.168.1.10
;; AUTHORITY SECTION/АВТОРИТЕТНЫЙ РАЗДЕЛ/:
example.com. 86400 IN NS ns1.example.com.
example.com. 86400 IN NS ns2.example.com.
;; ADDITIONAL SECTION/ДОПОЛНИТЕЛЬНЫЙ РАЗДЕЛ/:
ns1.example.com. 604800 IN A 192.168.2.20
ns2.example.com. 604800 IN A 192.168.3.30
www.linuxjournal.com. 43200 IN A 66.240.243.113
Заметили дополнительную строку в конце? Мы запросили информацию о чём-то в домене example.com, но подлый сервер добавил в ответ информацию о www.linuxjournal.com. Этот сервер действительно имеет право отвечать на DNS-запросы к linuxjournal.com? Чтобы определить, принимать или не принимать эти дополнительные записи, клиенты используют приём, который называется проверкой зоны ответственности. Это просто означает, что игнорируются любые записи не из этого же домена. Если мы попросили информацию о ftp.example.com, то из дополнительного раздела мы примем информацию только об example.com.

Начиная с 1997 года, почти все современные клиенты DNS используют проверку зоны ответственности, чтобы защититься от этой разновидности атаки заражения кэша.

UDP и идентификаторы запросов

Большая часть трафика DNS отправляется поверх UDP, который является протоколом без установки соединения. Это означает, что клиент (ваш компьютер или рекурсивный сервер DNS) отправляет запрос и просто ждёт, когда кто-нибудь ответит. Обычно несколько запросов DNS выполняются одновременно, поэтому клиенту нужен способ сопоставить отправленные запросы с полученными ответами. Для этого каждый запрос снабжается числом от 0 до 65536, которое называется идентификатором запроса. Сервер всегда отправляет ответ с тем же идентификатором запроса, какой он получил в запросе.

Существовали эксплойты, угадывающие идентификатор запроса. Раньше клиенты просто увеличивали идентификатор запроса, поэтому угадать его было предельно просто. После появления эксплойтов, большинство DNS-клиентов начали использовать в качестве идентификаторов запросов псевдослучайные числа. Поскольку идентификатор запроса - это 16-битное число, чисел для выбора не так уж много (всего 65536). Исследователи в области компьютерной безопасности продемонстрировали методы предсказания этих случайных чисел.

Эксплойт

После того, как мы разобрались с основами, перейдём к эксплойту Каминского.

Представим, что клиент запрашивает IP-адрес doesnotexist.example.com. Атакующий отправляет ответ, который выглядит следующим образом:
$ dig doesnotexist.example.com
;; ANSWER SECTION/РАЗДЕЛ ОТВЕТА/:
doesnotexist.example.com. 120 IN A 10.10.10.10
;; AUTHORITY SECTION/АВТОРИТЕТНЫЙ РАЗДЕЛ/:
example.com. 86400 IN NS www.example.com.
;; ADDITIONAL SECTION/ДОПОЛНИТЕЛЬНЫЙ РАЗДЕЛ/:
www.example.com. 604800 IN A 10.10.10.20
Атакующий пытается обмануть клиента, заставив его поверить, что www.example.com теперь находится за 10.10.10.20 и это нужно запомнить на 604800 секунд (7 дней). Проверка зоны ответственности проходит успешно, поскольку домены в авторитетном и дополнительном разделах являются доменами из запроса. Однако вспомним, что клиент примет ответ только с тем идентификатором, который был отправлен в запросе. Поскольку в большинстве случаев трафик передаётся через UDP, ничто не мешает атакующим наводнить ответами клиента. Но отправка ответов на несуществующие запросы бессмысленна. Поэтому нужно чтобы ответ атакующего был получен до настоящего ответа.

Но атакующий не может просто угадать отправленные запросы. Чтобы не угадывать запросы, атакующий может настроить веб-страницу с большим количеством картинок, указывающих на различные домены. Вот так:
<img src="http://aaaa.example.com/image.jpg"/>
<img src="http://aaab.example.com/image.jpg"/>
<img src="http://aaac.example.com/image.jpg"/>
Когда браузер попытается отобразить эту страницу, он попросит клиента DNS найти адреса aaaa.example.com, aaab.example.com и так далее, пока пока не будут найдены адреса для всех 1000 картинок. По ходу поиска он будет отправлять запросы с разными идентификаторами запросов, от 1 до 65535. Если атакующий будет постоянно отправлять ответы с одним и тем же идентификатором запроса, например - 12345, в конечном итоге этот идентификатор совпадёт с идентификатором из одного из настоящих запросов и будет принят. (Для наглядности можно представить, что атакующий отправляет обратно одновременно 65536 ответов с разными идентификаторами запросов, и тогда уж точно один из ответов будет принят.)

А как же проверка зоны ответственности? Вспомним, что атакующий не контролирует example.com, он просто отправляет свои собственные ответы клиенту DNS, чтобы поддельные ответы прошли проверку зоны ответственности. Ответы могут выглядеть следующим образом:
;; ANSWER SECTION/РАЗДЕЛ ЗАПРОСА/:
aaaa.example.com. 120 IN A 10.10.10.10
;; AUTHORITY SECTION/АВТОРИТЕТНЫЙ РАЗДЕЛ/:
example.com. 86400 IN NS www.example.com.
;; ADDITIONAL SECTION/ДОПОЛНИТЕЛЬНЫЙ РАЗДЕЛ/:
www.example.com. 604800 IN A 10.10.10.20
Атакующий отправил ответ вашему клиенту DNS и указал ему на 7 дней сохранить 10.10.10.20 в качестве IP-адреса www.example.com. Все последующие DNS-запросы будут отправляться по этому адресу, потому что запись NS тоже попадёт в кэш.

Для эксплойта не имеет значения, каким был запрос, потому что авторитетный и дополнительный разделы всегда будут одними и теми же. Важно лишь, чтобы ответ прибыл до реального ответа на любой из этих запросов. Наводняя клиента ответами, атакующий увеличивает вероятность того, что один из ответов будет принят, а какой именно - не важно. Каминский обнаружил способ соединить слабость идентификаторов запросов с прохождением проверки зоны ответственности для заражения кэша.

До выпуска недавних исправлений уязвимости все клиенты провайдера (Comcast, AT&T, Verizon и т.п.) оказались бы уязвимыми, если один из них посетил бы веб-страницу атакующего. Рекурсивные DNS-серверы провайдера могли бы слать весь трафик www.bankofamerica.com на IP-адрес, который управляется кем-то, обладающим сомнительной репутацией.

Реальность эксплойта

Да, эксплойт реален и серьёзен. Крикет Ли, признанный эксперт и автор широкой известной книги "DNS и BIND" издательства O'Reilly, предположил, что это может быть самой значительной проблемой безопасности DNS в истории Интернета, а большинство других экспертов с ним согласились. Дэн Камински упомянул, что обмануть систему можно менее чем за 10 секунд. Это означает, что Дэн мог в считанные секунды заполучить контроль над вашим банковским счётом, электронной почтой, учётной записью на ebay или чем угодно, чем вы активно пользуетесь. И вы ничего не смогли бы с этим поделать. Каждый из тысяч или сотен тысяч пользователей вашего провайдера мог поставить под угрозу всех остальных клиентов, включая вас. Вот почему было так важно, чтобы эти системы были вовремя исправлены.

Перейдите на веб-сайт Дэна Камински, DoxPara Research, и щёлкните по кнопке "Check my DNS" ("Проверить мой DNS") справа, чтобы проверить, безопасен ли ваш провайдер. Если он всё ещё уязвим, вам стоит подумать о временном использовании OpenDNS.

Комментариев нет: