Мы рассмотрим принципы работы DNS, а затем попробуем смоделировать угрозу. Клиент хочет найти некий сервер, скажем, www.example.com. Он посылает запрос DNS–серверу с просьбой сообщить IP–адрес (или несколько адресов), соответствующий доменному имени www.example.com. Важно отметить, что служба DNS работает по протоколу UDP, так что вы лишены даже той эфемерной защиты, которую предоставляет протокол TCP. Получив запрос, DNS–сервер смотрит, есть ли у него готовый ответ. Ответ имеется двух случаях: если данный сервер является руководящим (authoritative) для домена example.com или сохранил в кэше ответ на вопрос о том же имени, поступивший от какого–то другого компьютера. Если ответа нет, сервер запросит у одного из корневых серверов, где найти руководящий сервер имен для домена example.com (это может повлечь за собой еще один запрос к серверу домена .com, если example.com отсутствует в кэше). Узнав адрес руководящего сервера, первоначальный сервер пошлет ему еще один запрос и на этот раз получит окончательный ответ. К счастью, в систему DNS встроена избыточность: на каждом уровне работает несколько серверов, что позволяет защититься от случайных сбоев, не связанных с атаками. Но, как мы видели, шагов много, так что злоумышленник может нанести удар в разные места.
Во–первых, откуда вы знаете, что ответил действительно ваш сервер имен? Вы послали запрос на некоторый IP–адрес с определенного порта в вашей системе. Вы знаете, какое имя указали в запросе. Если бы все было хорошо, то, получив в ответ на запрос об адресе сервера www.example.com адрес сервера evilattackers.org, ответ следовало бы отбросить. Да еще с запросом связан 16–разрядный идентификатор – но предназначен он вовсе не для защиты, а чтобы не путать запросы от нескольких приложений, работающих на одной и той же машине.
Теперь посмотрим, что может пойти не так. Прежде всего, адрес настоящего сервера имен. Противнику нетрудно узнать этот адрес, особенно если он находится в той же сети, что и вы; почти наверняка в этом случае вы используете один и тот же DNS–сервер. Другой способ заключается в том, чтобы заставить систему запрашивать IP–адрес у DNS–сервера, контролируемого противником. Возможно, вам кажется, что это условие трудновыполнимо, но, принимая во внимание историю некоторых реализаций DNS–серверов, приходится с сожалением признать, что перспектива напороться на контролируемый противником сервер имен реальна. Итак, предположим, что противнику известен IP–адрес вашего DNS–сервера. Думаете, клиент будет настаивать на том, чтобы ответ пришел именно с того IP–адреса, на который был послан запрос? Увы, иногда ответы поступают с другого адреса по естественным причинам, поэтому некоторые определители имен не требуют соблюдения этого условия.
Далее, ответ должен прийти на тот же порт, с которого был отправлен запрос. Теоретически существует 64К портов, но на практике их меньше. В большинстве операционных систем динамические порты выделяются из ограниченного диапазона, в случае Windows это номера от 1024 до 5000, так что область поиска ограничена 12 битами вместо 16. Хуже того, номера портов обычно начинаются с 1024 и возрастают на единицу. Поэтому можно считать, что противник без особого труда сможет угадать номер порта.
Есть еще идентификатор запроса, но во многих реализациях он тоже возрастает монотонно, так что и его угадать несложно. Если противник находится в той же подсети, что и клиент, то атака становится тривиальной. Даже при наличии в сети коммутатора противник может увидеть запрос и получить всю информацию, необходимую для изготовления подложного ответа.
Но – полагаете вы – если мы просили адрес одной системы, а получили адрес совсем другой, то определитель должен проигнорировать непрошеную информацию. Увы, в большинстве случаев это не так. Но если мы просили IP–адрес одной системы, а получили ответ для другой, но с затребованным нами IP–адресом, то уж тогда–то клиент точно отбросит лишние данные, ведь так? И снова ответ отрицательный: может и принять.
Сейчас вы, наверное, недоумеваете, как же при таких условиях Интернет вообще умудряется работать, и думаете, что хуже уже и быть не может. Разочаруем вас. Следующая проблема в том, что в каждом DNS–ответе есть время кэширования. И угадайте, кто контролирует время, в течение которого мы можем доверять результату? В пакете, содержащем ответ, эта информация хранится в поле TTL (time–to–live – время жизни), и клиенты обычно слепо ему доверяют.
Далее, можно задаться вопросом, откуда DNS–сервер знает, что получает ответы на свои запросы именно от руководящего сервера. В этом случае DNS–сервер выступает в роли клиента, а стало быть, уязвим для всех описанных выше атак против клиента. Впрочем, есть все–таки хорошая новость – обычно DNS–серверы более тщательно проверяют непротиворечивость ответов, среди современных серверов вряд ли хоть один «поведется» на подлог.
Возможно, вы слыхали о DNSSEC, то есть безопасном DNS, и думаете, что с его помощью сможете решить все проблемы. Только беда в том, что он обещает эти проблемы решить вот уже десять лет, так что уж извините наш скептицизм. Прекрасное обсуждение этой проблемы имеется на странице www.watersprings.org/ pub/id/draft–itf–dnsext–dns–threats–07.txt. Вот выдержка из реферата:
Хотя система DNS Security Extensions (DNSSEC) разрабатывается уже десять лет, IETF так и не сформулировал конкретные угрозы, от которых DNSSEC должен защитить. Не говоря уже о прочих недостатках, эта ситуация с «телегой впереди лошади» затрудняет оценку того, достиг ли DNSSEC заявленных при проектировании целей, поскольку эти цели не были явно специфицированы.
Что еще плохого может случиться? Примите во внимание, что в наши дни большая часть клиентов пользуется протоколом динамического конфигурирования хостов (DHCP – Dynamic Host Configuration Protocol) для получения своего IP–адреса и адреса обслуживающего DNS–сервера. Часто по тому же протоколу они извещают DNS–сервер о своем имени. По сравнению с DHCP система DNS выглядит неприступной крепостью. Не будем вдаваться в детали, отметим лишь, что имя клиентской системы можно принять лишь условно, но считать эту информацию надежной было бы опрометчиво.
Как видите, атака на службу разрешения имен не особенно трудна, хотя и не тривиальна. Если терять вам особо нечего, можете не принимать ее в расчет. Если же ваши активы достойны защиты, то следует заложить при проектировании предположение о ненадежности DNS и отсутствии доверия к этой службе. Ваши клиентские программы могут быть направлены на подложные серверы, идентификация клиента по его доменному имени столь же недостоверна.