Атака SAD DNS для подстановки фиктивных данных в кэш DNS


Группа исследователей из Университета Цинхуа и Калифорнийского университета в Риверсайде разработали новый вид атаки (CVE-2020-25705), позволяющей осуществить подстановку фиктивных данных в кэш DNS-сервера, что может использоваться для подмены IP адреса произвольного домена и перенаправления обращений к домену на сервер злоумышленника. Атака позволяет обойти защиту, добавленную в DNS-серверы для блокирования классического метода отравления кэша DNS, предложенного в 2008 году Дэном Камински (Dan Kaminsky).

Метод Каминского манипулирует незначительным размером поля с идентификационным номером запроса DNS, который составляет всего 16 бит. Для подбора корректного идентификатора, необходимого для спуфинга имени хоста, достаточно отправить примерно 7000 запросов и симулировать около 140 тысяч фиктивных ответов. Атака сводится к отправке на DNS-резолвер большого числа пакетов с фиктивной привязкой к IP и с разными идентификаторами DNS-транзакции. Для предотвращения кэширования первого ответа в каждом фиктивном ответе указывается немного изменённое имя домена (1.example.com, 2.example.com, 3.example.com и т.п.).

Для защиты от данного вида атаки производители DNS-серверов реализовали случайное распределение номеров исходных сетевых портов, с которых отправляются запросы резолвинга, что компенсировало недостаточно большой размер идентификатора (для отправки фиктивного ответа кроме подбора 16 битного идентификатора стало необходимо подобрать и один из 64 тысяч портов, что увеличило число вариантов для подбора до 2^32).

Атака SAD DNS позволяет кардинально упростить определение номера порта, воспользовавшись утечкой сведений об активности сетевых портов. Проблема проявляется во всех современных операционных системах (Linux, Windows, macOS и FreeBSD) и при использовании разных DNS-серверов (BIND, Unbound, dnsmasq). Утверждается, что атаке подвержены 34% всех открытых резолверов, а также 12 из 14 протестированных крупных DNS-сервисов, включая сервисы 8.8.8.8 (Google), 9.9.9.9 (Quad9) и 1.1.1.1 (CloudFlare), а так же 4 из 6 проверенных маршрутизаторов от известных производителей.

Проблема вызвана особенностью формирования ответных ICMP-пакетов, позволяющей определить обращение к неиспользуемым и активным сетевым портам по протоколу UDP. Данная особенность даёт возможность очень быстро сканировать открытые UDP-порты и эффективно обходить защиту на основе случайного выбора исходных сетевых портов, сводя число вариантов перебора к 2^16+2^16 вместо 2^32.

Источником проблемы является механизм ограничения интенсивности отправки ICMP-пакетов в сетевом стеке, в котором применяется предсказуемое значение счётчика, на основе которого начинает действовать ограничение отправки. Указанный счётчик является общим для всего трафика, включая как поддельный трафик атакующего, так и реальный трафик. По умолчанию в Linux отправка ICMP-ответов ограничена интенсивностью в 1000 пакетов в секунду. Для каждого запроса, пришедшего на закрытый сетевой порт, сетевой стек увеличивает счётчик на 1 и отправляет ICMP-пакет с данными от недостижимости порта.

Таким образом, если отправить 1000 пакетов на разные сетевые порты, все из которых закрыты, то сервер на секунду ограничит отправку ICMP-ответов и атакующий может быть уверен, что среди перебранных 1000 портов нет открытых. Если пакет отправлен на открытый порт, сервер не вернёт ICMP-ответ и не изменит значение счётчика, т.е. после отправки 1000 пакетов ограничение на интенсивность ответов не будет достигнуто.

Так как фиктивные пакеты осуществляется с поддельного IP, атакующий не может получить ICMP-ответы, но благодаря общему счётчику может после каждых 1000 поддельных пакетов отправить запрос к несуществующему порту с реального IP и оценить приход ответа - если ответ пришёл, значит в одном из 1000 пакетов угадан верный порт, если нет - сработал лимит и все порты закрыты. Каждую секунду атакующий может отправлять 1000 поддельных пакетов на разные порты и достаточно быстро определить в каком блоке находится открытый порт, после чего cузить выборку и определить конкретный порт.

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

Для успешного совершения атаки необходимо использовать спуфинг IP (отправку с поддельного адреса). По данным CAIDA в 2019 году 30.5% автономных систем не выполняли блокировку пакетов с поддельным исходным IP-адресом (отмечается, что найти дешёвый хостинг у провайдера, не блокирующего спуфинг не составляет труда).

В ядре Linux проблема решена при помощи патча, который рандомизирует параметры ограничения интенсивности отправки ICMP-пакетов, что вносит шум и минимизирует утечку данных по сторонним каналам. Статус устранения уязвимости в дистрибутивах можно оценить на данных страницах: Debian, RHEL, Fedora, SUSE, Ubuntu. В качестве обходных путей защиты можно временно отключить отправку ICMP-пакетов, изменить значение rate-лимита и таймаута в сетевом стеке, а также использовать DNSSEC или DNS cookie.

Источник: https://www.opennet.ru/opennews/art.shtml?num=54091


Comments 0