Серьезная безопасность: как преднамеренные опечатки могут улучшить безопасность DNS

Серьезная безопасность: как преднамеренные опечатки могут улучшить безопасность DNS

За эти годы мы письменный и говорят на Naked Security много раз про острую проблему DNS угон самолета.

DNS, как вы, наверное, знаете, это сокращение от система доменных имен, и вы часто слышите, как его называют «телефонным справочником» или «географическим справочником» Интернета.

Если вы не знакомы со словом географический справочник, это относится к индексу в конце атласа, где вы смотрите, скажем, Монровия, Либерия в удобном алфавитном списке, и там написано что-то вроде 184 - C4. Это говорит вам перейти прямо на страницу 184 и следовать линиям сетки вниз от буквы C в верхней части карты и напротив цифры 4 слева. Там, где пересекаются линии, вы найдете Монровию.

Для большинства пользователей большинство запросов DNS содержат имя сервера, запрашивая ответ, который включает в себя то, что известно как его A-запись или его AAAA-запись.

(А-записи используются для 32-битных интернет-номеров IPv4, таких как 203.0.113.42; AAAA-записи являются эквивалентными ответами для 128-битных IPv6-адресов, таких как 2001:db8:15a:d0c::42 – в этой статье мы будем использовать только A-записи и номера IPv4, но в обоих случаях к процессу поиска применяются одни и те же вопросы безопасности.)

Вот пример, где мы ищем воображаемое доменное имя naksec.test через DNS-сервер, специально созданный для отслеживания и обучения DNS-трафику.

Мы использовали инструмент старой школы Linux dig, Короче для поиск домена в Интернете, чтобы сгенерировать простой DNS-запрос (dig по умолчанию поиск A-записей) для нужного нам сервера:

$ dig +noedns @127.42.42.254 naksec.test ;; РАЗДЕЛ ВОПРОСОВ: ;naksec.test. В ;; РАЗДЕЛ ОТВЕТОВ: NAKSEC.TEST. 5 В А 203.0.113.42;; Время запроса: 1 мс ;; СЕРВЕР: 127.42.42.254#53(127.42.42.254) (UDP) ;; КОГДА: Пн, 23 января, 14:38:42 GMT 2023 ;; РАЗМЕР MSG rcvd: 56

Вот как наш DNS-сервер обработал запрос, показав шестнадцатеричный дамп входящего запроса и успешный ответ, который вернулся:

---> Запрос от 127.0.0.1:57708 до 127.42.42.254:53 ---> 00000000 62 4e 01 20 00 01 00 00 00 00 00 00 06 6e 61 6b |bN. .........нак| 00000010 73 65 63 04 74 65 73 74 00 00 01 00 01 |сек.тест..... | Поиск в DNS: A-запись для naksec.test ==> A=203.0.113.42 <--- Ответ с 127.42.42.254:53 на 127.0.0.1:57708 <--- 00000000 62 4e 84 b0 00 01 00 01 00 00 00 00 06 6e 61 6b |bN...........nak| 00000010 73 65 63 04 74 65 73 74 00 00 01 00 01 06 4e 41 |sec.test......NA| 00000020 4b 53 45 43 04 54 45 53 54 00 00 01 00 01 00 00 |KSEC.TEST.......| 00000030 00 05 00 04 cb 00 71 2a |......q* |

Обратите внимание, что из соображений производительности большинство DNS-запросов используют UDP. Протокол пользовательских датаграмм, который работает по принципу «отправить и надеяться»: вы отправляете UDP-пакет на сервер, с которым хотите поговорить, а затем ждете, вернется ли ответ.

Это делает UDP намного проще и быстрее, чем его двоюродный брат TCP. Протокол управления передачей, который, как следует из его названия, автоматически заботится о множестве деталей, которые UDP не делает.

Примечательно, что TCP имеет дело с обнаружением потери данных и повторным запросом их; обеспечение того, чтобы любые порции данных поступали в правильном порядке; и предоставление единого сетевого соединения, которое после настройки может использоваться для отправки и получения одновременно.

UDP не имеет понятия «соединение», поэтому запросы и ответы по существу перемещаются независимо друг от друга:

  • DNS-запрос поступает на DNS-сервер в собственном пакете UDP.
  • DNS-сервер ведет учет из которых компьютер отправил этот конкретный пакет.
  • Сервер приступает к поиску ответа для отправки обратно, или решить, что его нет.
  • Сервер отправляет ответ исходному отправителю, используя второй пакет UDP.

На уровне операционной системы или сети эти два UDP-пакета выше являются независимыми, автономными передачами — они не связаны вместе как часть одного и того же цифрового соединения.

Сервер должен помнить, какому клиенту отправлять каждый ответ; и клиент должен выяснить, какие ответы относятся к тем запросам, которые он изначально отправил.

Как ты можешь быть уверен?

В этот момент, особенно глядя на крошечный размер DNS-запроса и ответа выше, вы, вероятно, задаетесь вопросом: «Как клиент может быть уверен, что он соответствует правильному ответу, а не тому, который был искажен при передаче или направлен неправильно? по ошибке, случайно или намеренно?»

К сожалению, многие, если не большинство, DNS-запросы (особенно запросы от сервера к серверу, когда первый запрашиваемый сервер не знает ответа и должен найти тот, который знает, чтобы сформулировать ответ) не зашифрованы или в противном случае помечен каким-либо криптографическим кодом аутентификации.

На самом деле, по умолчанию DNS-запросы включают один «идентификационный тег», который в документации по формату данных DNS упоминается просто как ID.

Удивительно, но, несмотря на получение многочисленных обновлений и предложений по улучшению за эти годы, официальный интернет-запрос RFC (запрос комментариев) документ, который действует как спецификация DNS, по-прежнему RFC 1035 (в настоящее время мы занимаемся RFC в середине 9000-х годов), начиная с ноября 1987 года, чуть более 35 лет назад!

В то время и пропускная способность, и вычислительная мощность были в дефиците: типичная частота процессора составляла около 10 МГц; настольные компьютеры имели около 1 МБ ОЗУ; скорость доступа в Интернет для организаций, которые вообще могли выходить в интернет, часто составляла 56 или 64 кбит/сек, разделяемая между всеми; а скорость 1200 бит/сек была доступным выбором для персонального подключения через коммутируемые модемы того времени.

Вот почему заголовки DNS-запроса и ответа были — и до сих пор — сжаты до жалких 12 байтов, из которых ID-тег занимает первые два, как мило RFC 1035. Искусство ASCII проясняет:

 1 1 1 1 1 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +--+--+--+--+--+--+--+--+--+ --+--+--+--+--+--+--+ | ID | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QR | Код операции |AA|TC|RD|RA| Я | РКОД | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QDCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | АККАУНТ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | НСКУНТ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | АРКАУНТ | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

Вы можете увидеть идентификатор в действии в шестнадцатеричных дампах, показанных выше, где и пакет запроса, и пакет ответа начинаются с одних и тех же двух символов. bN, которые соответствуют 16-битному идентификатору 62 4e в шестнадцатеричном формате.

Грубо говоря, эти 16 бит — это столько, сколько официальный протокол DNS предоставляет для «аутентификации» или «обнаружения ошибок».

Вмешательство по догадкам

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

Это включает в себя отправку ответов, которые преднамеренно предоставляют вам неточную информацию, например, ваша ИТ-команда перенаправляет вас с серверов, которые, как им известно, засорены вредоносными программами.

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

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

…с опасно высокими шансами на успех.

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

И если злоумышленники не смогут взломать naksec.test сам сервер, что если бы они регулярно и часто запускали UDP-пакеты на ваш DNS-сервер, используя вымышленный идентификационный тег, который утверждал, что отвечает на вопрос: «Что такое A-запись для naksec.test"?

Таким образом, они могут перехватить DNS-запрос, предоставить поддельный ответ и, следовательно, ввести вас в заблуждение при следующем посещении веб-сайта — по сути, взламывая сам сайт без необходимости атаковать его. naksec.test сервер вообще.

Требуется немного удачи

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

Чтобы добиться успеха, им нужно будет отправить фальшивый DNS-ответ:

  • В период, когда ваш собственный сервер еще не знал ответа на вопрос. Ответы DNS включают 32-битное число, называемое TTL, сокращение от время жить, который говорит, как долго другой конец может повторно использовать ответ. Если вы или кто-либо еще в сети ytour запросили naksec.test недавно ваш DNS-сервер мог иметь ответ в своем кеше. Дальнейший поиск не потребуется, и злоумышленникам не будет исходящего запроса на захват.
  • Между тем, как вы отправили свой запрос, и пришел официальный ответ извне. Даже в старые времена время поиска DNS редко превышало несколько секунд. Сегодня их лучше всего измерять в миллисекундах.
  • С правильным номером в первых 16 битах. Вы можете установить 65536 (216) разных значений в 16 бит, так что злоумышленникам должно повезти. Но при сегодняшней пропускной способности сети одновременная отправка 65536 различных поддельных ответов, охватывая, таким образом, все возможные идентификационные номера, занимает ничтожную долю секунды.

К счастью, приличные DNS-серверы сегодня делают дополнительный шаг, чтобы по умолчанию затруднить перехват.

По крайней мере, так они делают примерно с 2008 года, когда покойный Дэн Камински указал, что многие DNS-серверы в то время были настроены не только на прослушивание входящих запросов на фиксированном порту UDP (почти всегда порт 53, официально назначенный для DNS)…

… но также и для получения входящих ответов на фиксированный порт, часто также на порт 53, хотя бы для создания приятной симметрии в трафике.

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

Используйте номера портов в качестве дополнительного идентификатора

В наши дни почти все DNS-серверы на основе UDP, как всегда, прослушивают порт 53, но они отслеживают так называемый «исходный порт», используемый запрашивающей стороной DNS, который, как ожидается, будет выбран случайным образом.

Исходные порты UDP, которые чем-то напоминают «добавочный номер» в офисной телефонной станции старой школы, предназначены для того, чтобы помочь вам и сети отличать запросы друг от друга.

Порты интернет-протокола (их также использует TCP) могут работать от 1 до 65535, хотя большинство исходящих соединений используют только исходные порты 1024-65535, поскольку номера портов 1023 и ниже обычно зарезервированы для процессов с системными привилегиями.

Идея состоит в том, что отправитель любого поиска DNS должен не только вставлять действительно случайный 16-битный идентификатор в начале каждого запроса, но также выбирать действительно случайный номер исходного порта UDP, на котором он будет прослушивать связанный ответ.

Это добавляет дополнительный уровень догадок, который мошенники должны добавить к своему списку «похитить удачу» выше, а именно, что они должны отправить поддельный ответ, который отмечает все эти поля:

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

И еще кое-что

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

Удивительно, но этот трюк первый предложенный еще в 2008 году, в газете со славным названием Повышенная устойчивость к подделке DNS за счет 0x20-битного кодирования: БЕЗОПАСНОСТЬ С ПОМОЩЬЮ ЗАПРОСОВ LEET.

Идея до странности проста и опирается на две детали протокола DNS:

  • Все ответы DNS должны включать исходный раздел запроса в начале. Запросы, очевидно, имеют пустой раздел ответов, но ответы должны отражать исходный вопрос, что помогает гарантировать, что запросы и ответы не будут случайно перепутаны.
  • Все вопросы DNS нечувствительны к регистру. Если вы просите naksec.testили NAKSEC.TESTили nAksEc.tESt, вы должны получить тот же ответ.

Теперь в протоколе нет ничего, что говорило бы о том, что вы ДОЛЖНЫ использовать одно и то же написание в той части ответа, где вы повторяете исходный запрос, потому что DNS не заботится о регистре.

Но хотя RFC 1035 требует, чтобы вы выполняли сравнения без учета регистра, он настоятельно рекомендует вам на самом деле не меняйте дело любых текстовых имен, которые вы получаете в запросах или извлекаете из собственных баз данных для использования в ответах.

Другими словами, если вы получили запрос на nAKsEC.tEST, и в вашей базе данных он хранится как NAKSEC.TEST, то эти два имени, тем не менее, считаются идентичными и будут совпадать.

Но когда вы формулируете свой ответ, RFC 1035 предлагает вам не меняйте регистр данных, которые вы вводите в свой ответ, хотя вы можете подумать, что это будет выглядеть аккуратнее, и даже если оно все равно будет совпадать на другом конце, благодаря сравнению без учета регистра, требуемому DNS.

Таким образом, если вы случайно перепутаете регистр букв в DNS-запросе перед его отправкой, большинство DNS-серверов будут точно отражать это странное сочетание букв, даже если их собственная база данных хранит имя сервера по-другому, как вы видите здесь. :

$ dig +noedns @127.42.42.254 nAkSEc.tEsT ;; РАЗДЕЛ ВОПРОСОВ: ;nAkSEc.tEsT. В ;; РАЗДЕЛ ОТВЕТОВ: NAKSEC.TEST. 5 В А 203.0.113.42;; Время запроса: 1 мс ;; СЕРВЕР: 127.42.42.254#53(127.42.42.254) (UDP) ;; КОГДА: Пн, 23 января, 14:40:34 GMT 2023 ;; РАЗМЕР MSG rcvd: 56

Наш DNS-сервер хранит имя naksec.test все в верхнем регистре, поэтому раздел ответа включает имя в форме NAKSEC.TEST, а также его номер IPv4 (A-запись) 203.0.113.42.

Но в части ответа «вот данные запроса, возвращенные вам для перекрестной проверки», которую отправляет наш DNS-сервер, мэшап регистра символов, первоначально использовавшийся при поиске DNS, сохраняется:

---> Запрос с 127.0.0.1:55772 на 127.42.42.254:53 ---> 00000000 c0 55 01 20 00 01 00 00 00 00 00 00 06 6e 41 6b |.U. .........nAk| 00000010 53 45 63 04 74 45 73 54 00 00 01 00 01 |SEC.TEST..... | Поиск в DNS: A-запись для nAkSEc.tEsT ==> A=203.0.113.42 <--- Ответ с 127.42.42.254:53 на 127.0.0.1:55772 <--- 00000000 c0 55 84 b0 00 01 00 01 00 00 00 00 06 6e 41 6b |.U...........nAk| 00000010 53 45 63 04 74 45 73 54 00 00 01 00 01 06 4e 41 |SEC.TEST......NA| 00000020 4b 53 45 43 04 54 45 53 54 00 00 01 00 01 00 00 |KSEC.TEST.......| 00000030 00 05 00 04 cb 00 71 2a |......q* |
Серьезная безопасность: как умышленные опечатки могут улучшить безопасность DNS. Разведка данных PlatoBlockchain. Вертикальный поиск. Ай.
Выше. DNS-запрос в Wireshark.
Показан раздел вопросов со смешанным случаем.
Серьезная безопасность: как умышленные опечатки могут улучшить безопасность DNS. Разведка данных PlatoBlockchain. Вертикальный поиск. Ай.
Выше. Ответ DNS в Wireshark.
Обратите внимание, как данные запроса копируются точно из запроса, даже несмотря на то, что база данных сервера предоставила имя ALL-UPPER.

Дополнительная маркировка безопасности, бесплатно

Бинго!

Есть еще несколько «идентификационных тегов», которые может добавить поиск в DNS!

Наряду с 15 или около того битами случайно выбранного исходного порта и 16 битами случайно выбранных данных идентификационного номера запрашивающая сторона может выбирать верхний или нижний регистр для каждого буквенного символа в имени домена.

И, naksec.test содержит 10 букв, каждая из которых может быть написана как в верхнем, так и в нижнем регистре, для дополнительных 10 бит случайной «маркировки».

Чтобы угадать эту дополнительную деталь, злоумышленникам нужно будет угадать время, номер порта UDP, значение тега ID и использование заглавных букв в имени домена, чтобы внедрить поддельный «ответ на перехват», который запрашивающий сервер принял бы.

Кстати, название 0x20-кодирование выше немного шутка: 0x20 в заглавной 00100000 в двоичном формате, и единственный бит в этом байте — это то, что отличает прописные и строчные буквы в системе кодирования ASCII.

Письма A в I, например, от 0x41 до 0x49, а a в i выйти как от 0x61 до 0x69.

 Таблица кодирования ASCII в виде текста ASCII +------+------+------+------+------+------+- -----+------+ |00 ^@ |10 ^P |20 |30 0 |40 @ |50 P |60 ` |70 p | |01 ^A |11 ^Q |21 ! |31 1 |41 А |51 Q |61 а |71 q | |02 ^B |12 ^R |22 " |32 2 |42 B |52 R |62 b |72 r | |03 ^C |13 ^S |23 # |33 3 |43 C |53 S |63 c |73 с | |04 ^D |14 ^T |24 $ |34 4 |44 D |54 T |64 d |74 t | |05 ^E |15 ^U |25 % |35 5 |45 E |55 U |65 e |75 u ||06 ^F |16 ^V |26 & |36 6 |46 F |56 V |66 f |76 v ||07 ^G |17 ^W |27 ' |37 7 | 47 G |57 Вт |67 г |77 Вт | |08 ^H |18 ^X |28 ( |38 8 |48 H |58 X |68 ч |78 x | |09 ^I |19 ^Y |29 ) |39 9 |49 I |59 Y |69 i |79 y | |0A ^J |1A ^Z |2A * |3A : |4A J |5A Z |6A j |7A z ||0B ^K |1B ^ [ |2B + |3B ; 4D ^] |5D - |6D = |7D M |0D ] |1D m |2D } ||3E ^N |4E ^^ |5E .|6E > |7E N |0E ^ |1E n |2E ~ || 3F ^O |4F ^_ |5F / |6F ? |7F O |0F _ |1F o |2F | +------+------+------+--- ---+------+------+------+------+

Другими словами, если вы добавите 0x41+0x20, чтобы получить 0x61, получится A в a; если вычесть 0x69-0x20, чтобы получить 0x49, получится i в I.

Почему именно сейчас?

Вы, наверное, сейчас задаетесь вопросом, «Почему именно сейчас, если идея появилась 15 лет назад, и принесла бы она вообще какую-то пользу?»

Наш внезапный интерес, как это бывает, исходит от последнее общедоступное электронное письмо от технических специалистов Google, признав, что их эксперименты 2022 года с этим старомодным приемом БЕЗОПАСНОСТИ были реализованы в реальной жизни:

Как мы сообщали ранее, Google Public DNS находится в процессе включения рандомизации имен запросов DNS, отправляемых на авторитетные серверы имен. Мы успешно развернули его в некоторых регионах Северной Америки, Европы и Азии, защитив большинство (90%) DNS-запросов в тех регионах, где DNS через TLS не охвачен.

Интересно, что Google предполагает, что основные проблемы, с которыми он столкнулся с этой простой и, по-видимому, бесспорной настройкой, заключаются в том, что, хотя большинство DNS-серверов либо постоянно нечувствительны к регистру (поэтому этот трюк можно использовать с ними), либо постоянно нет (поэтому они занесены в черный список), как и следовало ожидать…

…некоторые серверы основного потока время от времени на короткое время переходят в «чувствительный к регистру» режим, что звучит как своего рода несоответствие, которого, как вы надеетесь, удастся избежать крупным поставщикам услуг.

Это действительно помогает?

Ответ на вопрос, "Стоит ли оно того?" еще не ясно.

Если у вас есть красивое длинное имя службы, например nakedsecurity.sophos.com (22 буквенных символа), то есть много дополнительной сигнальной мощности, потому что 222 различные заглавные буквы означают 4 миллиона комбинаций, которые мошенники должны попробовать, умноженные на 65536 различных идентификационных номеров, умноженные примерно на 32000–64000 различных исходных портов, которые нужно угадать…

…но если вы заплатили небольшое состояние за суперкороткое доменное имя, такое как Twitter t.co, у ваших злоумышленников есть работа, которая в 2x2x2=8 раз сложнее, чем раньше.

Тем не менее, я думаю, мы можем сказать Google «Вводная часть» за то, что попробовали это.

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


Отметка времени:

Больше от Голая Безопасность