8.2. Основные компоненты атаки

Прежде всего мы рассмотрим базовые компоненты, из которых состоит сетевая атака. Практически все они проводятся по определенному «рецепту», где эти «ингредиенты» ловко смешиваются в разных вариациях.


8.2.1. Разведка

Представьте, что вы — хакер, и в одно прекрасное утро вы решили взломать компьютерную систему организации X. С чего начать? Вы мало что знаете об этой организации и физически находитесь далеко от нее, что исключает изучение содержимого мусорных корзин или подсматривание через плечо. Конечно, вы всегда можете применить методы социальной инженерии и попытаться выманить конфиденциальную информацию у сотрудников, отправляя им электронные письма (спам) и общаясь с ними по телефону или в социальных сетях, но нас больше интересуют технические аспекты, связанные с компьютерными сетями. Например, сможете ли вы узнать, сколько компьютеров использует организация, как они подключены к сети и какие службы на них запущены?

Для начала предположим, что злоумышленник располагает IP-адресами нескольких компьютеров компании, включая веб-серверы, серверы имен, серверы авторизации и прочие устройства, взаимодействующие с внешним миром. Сначала злоумышленник должен изучить сервер. Какие TCP- и UDP-порты открыты? Чтобы это выяснить, нужно просто попытаться установить TCP-соединение, используя все возможные номера портов. Установление соединения показывает, что порт прослушивается соответствующей службой. Например, если компьютер реагирует на использование порта 25, это говорит о наличии SMTP-сервера, если удается установить соединение с портом 80, значит, имеется веб-сервер, и т.д. Это справедливо и для UDP-портов. К примеру, если исследуемый компьютер реагирует на использование UDP-порта 53, мы понимаем, что на нем запущена служба DNS, поскольку этот порт зарезервирован для нее.


Сканирование портов

Исследование компьютера на предмет активности портов называется сканированием портов (port scanning) и может оказаться довольно сложным. Описанный выше метод сканирования подключением (connect scan) или открытого сканирования (open scan), при котором злоумышленник пытается установить полное TCP-соединение с нужным компьютером, напротив, предельно прост. Однако, будучи вполне эффективным, он имеет крупный недостаток — он слишком заметен для службы безопасности. Многие серверы регистрируют все успешные TCP-соединения в журнале, и попадание в такой журнал на этапе разведки отнюдь не входит в планы злоумышленника. Чтобы избежать этого, он может предпринимать заведомо неудачные попытки соединения, используя метод полуоткрытого сканирования (half-open scan). При таком сканировании злоумышленник лишь делает вид, что хочет установить соединение: он отправляет TCP-пакеты с флагом SYN, содержащим интересующие его номера портов, и в ответ получает от сервера соответствующие сегменты SYN/ACK для открытых портов, но после этого так и не завершает процесс «тройного рукопожатия». Большинство серверов не регистрирует в журнале неудачные попытки подключения.

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

Как при сканировании подключением, так и при полуоткрытом сканировании предполагается, что можно инициировать TCP-соединение с любого компьютера, расположенного за пределами сети, в которой находится цель атаки. Но на практике брандмауэр может не позволить установить соединение с компьютера злоумышленника. В частности, он может блокировать все сегменты SYN. В этом случае хакеру придется прибегнуть к более экзотическим методам сканирования. Например, метод FIN-сканирования (FIN scan) сводится к тому, чтобы вместо сегмента SYN передавать TCP-сегмент FIN, который обычно применяется для закрытия соединения. На первый взгляд это не имеет смысла, ведь у нас нет ни одного соединения. Тем не менее ответ на пакет FIN может отличаться в зависимости от того, открыт ли порт (и прослушивается ли соответствующей службой) или закрыт. Так, многие реализации TCP отправляют TCP-пакет RST, если порт закрыт, и молчат, если он открыт. Три описанных базовых метода сканирования показаны на илл. 8.2.

Илл. 8.2. Базовые методы сканирования портов. (а) Сканирование подключением. (б) Полуоткрытое сканирование. (в) FIN-сканирование

Сейчас вы, вероятно, задаетесь вопросом: «Если мы можем сканировать компьютер с помощью флагов SYN и FIN, можно ли применять для этого и другие флаги?» Вы абсолютно правы. Можно использовать любую конфигурацию флагов, если она приводит к разным ответам для открытых и закрытых портов. Еще один широко известный вариант сводится к одновременной установке сразу нескольких флагов: FIN, PSH и URG. Этот метод называется Xmas-сканированием (Xmas scan)41, потому что пакет при этом сверкает, как рождественская елка.

На илл. 8.2 (а) установление соединения означает, что порт открыт. На илл. 8.2 (б) об этом говорит ответ SYN/ACK. Наконец, на илл. 8.2 (в) ответ RST сообщает, что порт закрыт.

Поиск открытых портов является лишь первым шагом. После этого нужно выяснить, какой именно сервер работает на конкретном порте, с каким программным обеспечением (и какой версии) и под какой операционной системой. Допустим, мы узнали, что открыт порт 8080. По всей вероятности, его использует веб-сервер, но у нас нет в этом уверенности. Даже если это веб-сервер, то какой именно — Nginx, Lighttpd или Apache? Хакеру могут быть известны только, к примеру, уязвимости сервера Apache в версии 2.4.37 для ОС Windows. Поэтому выяснение всех этих деталей, то есть снятие цифрового отпечатка (fingerprinting), играет очень важную роль. Так же как и при сканировании портов, получить эти сведения можно благодаря различиям (зачастую незначительным) в ответной реакции для разных серверов и операционных систем. Если вам это кажется очень сложным, не пугайтесь. Как и в случае многих других сложных вещей в сфере компьютерных сетей, уже нашлась добрая душа, объединившая для вас все эти методы сканирования и снятия цифровых отпечатков в удобные и многофункциональные программы, например netmap и zmap.


Утилита traceroute

Итак, хакер может выяснить, какие службы активны на одном компьютере, но что насчет остальных устройств в сети? Отталкиваясь от первого IP-адреса, злоумышленник может «прощупать» окружение этого компьютера и посмотреть, какие еще компьютеры доступны. Например, если первый компьютер использует IP-адрес 130.37.193.191, можно также проверить адреса 130.37.193.192, 130.37.193.193 и все другие возможные адреса в этой локальной сети. Зло­умышленник также может воспользоваться программой traceroute, чтобы выяснить, по какому пути данные идут к исходному IP-адресу. Утилита traceroute последовательно отправляет целевому компьютеру небольшие партии UDP-пакетов с временем жизни (TTL), равным единице, двум, трем и т.д. Первый маршрутизатор уменьшает значение TTL и сразу же удаляет первую партию пакетов (потому что TTL становится равным нулю), после чего отправляет назад ICMP-сообщение об ошибке, в котором говорится, что время жизни пакетов истекло. Второй маршрутизатор делает то же самое для следующей партии пакетов, третий — для третьей, и т.д., пока, наконец, определенные UDP-пакеты не дойдут до нужного компьютера. Собрав воедино эти пакеты ICMP-сообщений и соответствующие IP-адреса источников, утилита traceroute может определить общий маршрут. На основе полученных результатов хакер может попытаться выявить дополнительные мишени, проверив диапазоны адресов маршрутизаторов, расположенных поблизости от целевого компьютера, и тем самым получив общее представление о топологии сети.


8.2.2. Прослушивание и перехват (и немного подмены данных)

Многие сетевые атаки начинаются с перехвата сетевого трафика. Использование этого компонента предполагает, что хакер имеет доступ к сети жертвы. Он может, например, принести ноутбук в зону действия ее Wi-Fi-сети или получить доступ к ПК в проводной сети. Прослушивание в таких широковещательных сетях, как сети Wi-Fi или первая версия сети Ethernet, не представляет большого труда: нужно просто подключиться к каналу в подходящем для этого месте, а затем прослушивать поступающий поток битов. Для этого злоумышленники переводят свои сетевые интерфейсы в неизбирательный режим (promiscuous mode), что позволяет принимать все идущие через канал пакеты, включая предназначенные для других хостов, и перехватывать трафик с помощью таких инструментов, как tcpdump и Wireshark.


Прослушивание в коммутируемых сетях

Однако в сетях других типов дело часто обстоит далеко не так гладко — взять хотя бы сеть Ethernet. В отличие от первых реализаций, современная версия Ethernet уже не является сетью с разделяемой средой. Связь носит коммутируемый характер, и даже в случае подключения злоумышленников к какому-то сегменту сети они никогда не получат Ethernet-фреймы, предназначенные для других хостов этого сегмента. В частности, как вы помните, коммутаторы Ethernet способны самообучаться и быстро создают таблицу пересылки. Принцип самообучения прост и эффективен: при поступлении фрейма Ethernet от хоста A на порт 1 коммутатор фиксирует, что трафик для хоста A должен направляться именно на этот порт. Теперь он знает, что весь трафик, содержащий MAC-адрес хоста A в поле назначения заголовка Ethernet, должен пересылаться на порт 1. Аналогично он будет передавать трафик для хоста B на порт 2, и т.д. После составления полной таблицы пересылки коммутатор уже не будет передавать трафик, явно адресованный хосту B, на какой-то другой порт помимо порта 2. А чтобы прослушать трафик, злоумышленники должны каким-то образом этого добиться.

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

Первый метод, клонирование MAC-адреса (MAC cloning), сводится к тому, чтобы продублировать MAC-адрес хоста, трафик которого вам нужно прослушать. Если вы сообщите, что обладаете нужным MAC-адресом (отправляя фреймы Ethernet, в которых он указан), то коммутатор исправно запишет это в свою таблицу, после чего будет отсылать на ваш компьютер весь трафик, адресованный жертве. Конечно, сначала нужно узнать этот адрес. Его можно извлечь из ARP-запросов, которые отправляет интересующий вас компьютер (поскольку они рассылаются всем хостам в сегменте сети). Другая сложность заключается в том, что сопоставление с вашим компьютером будет удалено коммутатором, как только настоящий владелец MAC-адреса возобновит коммуникацию. Таким образом, отравление таблицы коммутатора (switch table poisoning) придется повторять постоянно.

Существует альтернативный, но схожий подход, при котором используется одна особенность: таблица коммутатора имеет ограниченный размер. Злоумышленник «заваливает» коммутатор фреймами Ethernet с поддельными адресами отправителей. Не зная, что они фальшивые, коммутатор фиксирует их, пока таблица не заполнится и для размещения новых записей не потребуется удаление старых. Поскольку теперь у коммутатора нет записи для целевого хоста, предназначенный для этого хоста трафик начинает рассылаться по всей сети. Лавинная рассылка MAC-адресов (MAC flooding) снова превращает сеть Ethernet в широковещательную среду, какой она была в далеком 1979 году.

Вместо того чтобы вводить коммутатор в заблуждение, злоумышленник может напрямую атаковать хост с помощью метода подмены ARP (ARP spoofing) или отравления ARP (ARP poisoning). Как упоминалось в главе 5, протокол ARP помогает компьютеру определить, какой MAC-адрес соответствует тому или иному IP-адресу. Для этого реализация ARP на компьютере ведет таблицу сопоставления IP-адресов с MAC-адресами для всех хостов, которые связывались с данным компьютером, — таблицу ARP (ARP table). Время жизни каждой записи в ней обычно составляет несколько десятков минут. По истечении этого срока MAC-адрес удаленного абонента забывается, исходя из предположения, что абоненты больше не обмениваются данными (в этом случае значение TTL сбрасывается), и для последующих коммуникаций сначала нужно выполнить ARP-поиск. ARP-поиск представляет собой обычную широковещательную рассылку сообщения примерно следующего содержания: «Мне нужен MAC-адрес хоста с IP-адресом 192.168.2.24. Если это ваш адрес, пожалуйста, сообщите об этом». Этот поисковый запрос включает MAC-адрес отправителя, чтобы хост 192.168.2.24 знал, кому отвечать, и его IP-адрес, чтобы хост 192.168.2.24 добавил в свою ARP-таблицу сопоставление IP- и MAC-адресов отправителя.

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

Применив этот трюк к обоим участникам коммуникации, злоумышленник сможет принимать весь трафик, которым они обмениваются. Обеспечив пересылку этих фреймов на правильный MAC-адрес, он тем самым установит скрытый шлюз атаки «человек посередине» (Man-in-the-Middle, MITM), способный перехватывать весь трафик между двумя хостами.


8.2.3. Подмена данных (помимо ARP)

Как правило, подмена данных подразумевает передачу байтов по сети с использованием поддельного адреса отправителя. Злоумышленники могут подделывать не только ARP-пакеты, но и любой другой сетевой трафик. В качестве примера можно вспомнить SMTP — удобный текстовый протокол, который сегодня повсеместно используется для отправки электронной почты. В нем применяется заголовок Mail From: для указания адреса отправителя письма, но по умолчанию указанный адрес не проверяется. То есть при желании вы можете поместить в этот заголовок что угодно, и все ответы будут отправляться на этот адрес. При этом получатель даже не увидит содержимого Mail From: — вместо него почтовый клиент отобразит содержимое отдельного заголовка From:. Но и это поле SMTP не проверяет, что позволяет подменить его содержимое. Например, вы можете отправить своим однокурсникам письмо с сообщением о том, что они провалили экзамен, и в качестве отправителя указать преподавателя. Если вы также укажете свой электронный адрес в заголовке Mail From:, то все ответы паникующих студентов окажутся в вашем почтовом ящике. Вот это веселье! Однако когда злоумышленники подделывают адрес для рассылки фишинговых писем, якобы приходящих из надежного источника, это уже далеко не так невинно. Например, письмо от «вашего доктора» может содержать ссылку на срочную информацию о результатах медосмотра, щелкнув по которой вы попадете на сайт, сообщающий, что ваше здоровье в полном порядке (без упоминания о том, что на ваш компьютер загружен вирус). А письмо от «вашего банка» может нести угрозу вашим финансам.

Хотя подмена ARP осуществляется на канальном уровне, а подмена SMTP — на прикладном, в принципе, методы подмены могут применяться на любом уровне стека протоколов. Иногда это достаточно просто сделать. Например, любой, кто умеет создавать пользовательские пакеты, может легко подделать фрейм Ethernet, IP-дейтаграмму или UDP-пакет. Достаточно лишь изменить адрес отправителя, и эти протоколы никак не смогут выявить обман. Многие другие протоколы гораздо труднее поддаются обману. Например, в случае TCP-соединений конечные точки сохраняют такие данные о состоянии, как порядковые номера и номера подтверждения, что сильно усложняет подмену данных. Если зло­умышленнику не удастся получить порядковые номера путем прослушивания или угадать их, то получатель отбросит поддельные TCP-сегменты как выходящие за рамки установленного окна. Как мы увидим далее, помимо этого имеется ряд других существенных сложностей.

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


Спуфинг DNS

Поскольку служба DNS использует протокол UDP для пересылки своих запросов и ответов, подмена данных здесь не представляет большого труда. Например, как и в случае подмены ARP, можно подождать, пока клиент не отправит поисковый запрос в отношении домена trusted-services.com, а затем, опередив настоящую службу DNS, предоставить клиенту поддельный ответ. В нем будет указано, что для этого домена следует использовать принадлежащий вам IP-адрес. Это легко сделать, если вы можете прослушать поступающий от клиента трафик (и таким образом увидеть содержимое запроса на DNS-поиск, на который нужно ответить). Но что, если вы не можете увидеть этот запрос? В конце концов, если вы уже и так прослушиваете линию, то перехват этого трафика путем спуфинга DNS не имеет особого смысла. Кроме того, что, если вам нужно перехватить трафик не одного, а сразу нескольких пользователей?

Если злоумышленник использует тот же локальный сервер имен, что и жертва, он просто отправляет собственный запрос, скажем, для домена trusted-services.com. После этого сервер начинает искать этот IP-адрес и пытается связаться со следующим сервером имен в процессе поиска. На этот запрос локального сервера имен злоумышленник немедленно выдает поддельный ответ, якобы от следующего сервера. В результате локальный сервер имен сохраняет в своем кэше сфальсифицированное сопоставление и предоставляет его, когда жертва (или кто-то еще), наконец, запрашивает данные по домену trusted-services.com. Обратите внимание, что этот метод может сработать и в том случае, если взломщик не использует тот же локальный сервер имен, что и цель атаки. Для этого нужно как-то склонить жертву к отправке поискового запроса с доменным именем, предоставленным злоумышленником. Например, он может отправить письмо со ссылкой, при активации которой браузер выполнит поиск по нужному имени. После отравления данных сопоставления для домена trusted-services.com все последующие запросы по нему будут возвращать сфальсифицированные данные.

Проницательный читатель может возразить, что это далеко не так просто. Ведь у каждого DNS-запроса есть 16-битный идентификатор, и ответ принимается, только если он содержит такой же идентификатор. Но если хакер не видит запрос, то ему придется подбирать этот идентификатор наугад. Вероятность успеха подбора для отдельного ответа составляет 1 : 65 536. В среднем хакеру придется отправить десятки тысяч DNS-ответов за очень короткий промежуток времени, чтобы сфальсифицировать лишь одно сопоставление на локальном сервере имен, не имея при этом никакой обратной связи. Это нельзя назвать простой задачей.


Атака «дней рождения»

Существует и более простой метод, который называют атакой «дней рождения» (birthday attack), или парадоксом «дней рождения» (birthday paradox); хотя, строго говоря, это вовсе не парадокс. Идея этого метода заимствована из задачи, часто используемой профессорами математики при изложении теории вероятности. Вопрос: сколько студентов должно быть в классе, чтобы вероятность того, что двое из них родились в один день, превысила 50 %? На первый взгляд кажется, что ответом будет число, значительно превышающее 100. Однако согласно теории вероятности это число на самом деле равно 23. Для 23 людей вероятность того, что ни у кого из них не совпадает день рождения, равна:

То есть вероятность того, что два студента отмечают день рождения в один день, превышает 50 %.

Вообще, если имеется сопоставление n входных значений (людей, идентификаторов и т.д.) и k возможных выходных значений (дней рождения, идентификаторов и т.д.), то мы имеем n(n – 1)/2 входных пар. При n(n – 1)/2 > k вероятность того, что будет получено хотя бы одно совпадение, довольно значительна. Таким образом, оно вероятно уже примерно при n > √2k. Ключевой момент состоит в том, что мы не ищем совпадение с днем рождения одного конкретного человека, а сравниваем даты рождения всех студентов и считаем успехом любое найденное соответствие.

Учитывая вышесказанное, хакеры сначала отправляют несколько сотен DNS-запросов в отношении того домена, для которого им нужно фальсифицировать сопоставление. Локальный сервер имен пытается поочередно разрешить каждый из этих запросов путем отправки запроса серверу имен следующего уровня. Вероятно, это не слишком разумно — какой смысл многократно запрашивать данные по одному и тому же домену? Но никто и не утверждает, что серверы имен отличаются большой сообразительностью, и именно так, к примеру, работает популярный сервер имен BIND. Как бы там ни было, сразу после отправки запросов злоумышленники также отсылают сотни поддельных ответов на поисковые запросы, якобы от сервера имен следующего уровня. Эти ответы содержат разные варианты идентификатора запроса. При этом локальный сервер имен косвенно производит сравнение по принципу «многие ко многим», поскольку будет принят любой ответ, идентификатор которого совпадает с идентификатором запроса от локального сервера имен. Обратите внимание, что, как и в случае с днями рождения студентов, сервер имен сравнивает все запросы от локального сервера имен со всеми поддельными ответами.

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


Атака Каминского

Ситуация может принять еще более серьезный оборот, если злоумышленники не будут ограничиваться отдельным веб-сайтом и решат отравить данные сопоставления для целой зоны. Такое нарушение получило известность как DNS-атака Дэна Каминского; в свое время она повергла в шок многих специалистов по информационной безопасности и сетевых администраторов по всему миру. Чтобы понять, чем они были так напуганы, необходимо детально разобраться в том, как происходит DNS-поиск.

В качестве примера рассмотрим процесс обработки DNS-запроса на поиск IP-адреса домена www.cs.vu.nl. После получения этого запроса локальный сервер имен, в свою очередь, отправляет запрос либо на корневой сервер имен, либо на сервер имен домена верхнего уровня (ДВУ) по отношению к домену .nl. Второй сценарий происходит чаще по той причине, что IP-адрес сервера имен ДВУ обычно уже имеется в кэше локального сервера имен. На илл. 8.3 показан такой запрос локального сервера имен (запрашивающий A-запись домена) при выполнении рекурсивного поиска с идентификатором 1337.

Илл. 8.3. DNS-запрос в отношении домена www.cs.vu.nl

Серверу имен ДВУ не известно точное сопоставление, однако он знает имена DNS-серверов Университета Врийе и возвращает их в ответе, поскольку не производит рекурсивный поиск. На илл. 8.4 показан ответ, несколько полей которого заслуживают особого внимания. Во-первых, мы сразу видим, что флаги напрямую сообщают о нежелании сервера выполнять рекурсивный поиск, и потому дальнейший поиск будет итеративным. Во-вторых, в ответе содержится идентификатор 1337, который был использован в поисковом запросе. В-третьих, ответ содержит символьные наименования серверов имен университета ns1.vu.nl и ns2.vu.nl в виде записей NS. Эти данные являются авторитетными и, в принципе, достаточными для того, чтобы локальный сервер имен мог завершить обработку запроса. Ему нужно лишь свериться с А-записью одного из этих серверов имен, связаться с ним и запросить IP-адрес домена www.cs.vu.nl. Но чтобы это сделать, он должен еще раз связаться с тем же сервером имен ДВУ, на этот раз чтобы запросить IP-адрес сервера имен университета. Поскольку это вводит дополнительную задержку в пути туда и обратно, данный подход не слишком эффективен. Чтобы исключить необходимость в этой дополнительной операции поиска, сервер имен ДВУ услужливо предоставляет в своем ответе IP-адреса двух серверов имен университета в виде дополнительных записей с коротким временем жизни. Эти связующие DNS-записи (DNS glue records) как раз и являются ключевым элементом атаки Каминского.

Илл. 8.4. DNS-ответ, отправляемый сервером имен ДВУ

Злоумышленники действуют так. Сначала они отправляют запросы на поиск данных о несуществующем поддомене в домене университета, таком как ohdeardankaminsky.vu.nl. Поскольку этого поддомена нет, ни один сервер имен не может предоставить данные сопоставления из своего кэша. Вместо этого локальный сервер должен связаться с сервером имен ДВУ. Сразу после отправки запросов взломщики отсылают множество поддельных ответов, якобы от сервера имен ДВУ, как и в случае обычного спуфинга DNS. Однако на этот раз в ответе говорится, что сервер имен ДВУ не располагает нужными данными (то есть он не предоставляет A-запись), не выполняет рекурсивный поиск и рекомендует локальному серверу имен завершить поиск путем обращения к одному из серверов имен университета. Он даже может предоставить реальные имена этих серверов. Единственное, что при этом фальсифицируется, это связующие записи: вместо них злоумышленники дают подконтрольные им IP-адреса. В результате при запросе данных о любом поддомене в домене .vu.nl производится обращение к серверу имен злоумышленников, которые могут предоставить в ответ какой угодно IP-адрес. Таким образом, они способны провести атаку типа «человек посередине» против любого сайта в домене университета!

Очень многие (хотя и не все) реализации серверов имен были уязвимы к этой атаке. Очевидно, у интернета возникла проблема. В связи с этим в штаб-квартире компании Microsoft в Редмонде было собрано экстренное совещание. Как позже вспоминал Каминский, оно было окутано столь строгой атмосферой секретности, что «многие из прилетевших в Microsoft людей даже не знали, о какой программной ошибке пойдет речь».

Каким же образом все эти умные люди справились с проблемой? По правде говоря, решить ее полностью им не удалось, хотя они и сумели существенно усложнить хакерам задачу. Напомним, что корневая проблема, из-за которой спуфинг DNS возможен, заключается в том, что длина идентификатора запроса составляет лишь 16 бит. Это позволяет получить его либо путем прямого перебора, либо с помощью атаки «дней рождения». Увеличение длины идентификатора запроса существенно снижает вероятность успешного проведения такой атаки. Однако просто изменить формат сообщения протокола DNS затруднительно; кроме того, это нарушило бы работу многих существующих систем.

Было принято решение дополнить длину произвольного идентификатора путем введения элемента случайности и в UDP-порт отправителя (не прибегая к реальному увеличению идентификатора запроса). К примеру, при отправке DNS-запроса на сервер имен ДВУ модифицированный сервер имен будет случайным образом выбирать номер порта из тысяч доступных номеров и использовать этот порт в качестве UDP-порта отправителя. Теперь злоумышленнику нужно подобрать не только идентификатор запроса, но и номер порта, успев сделать это до поступления реального ответа. Кодировка 0x20, о которой мы говорили в главе 7, дополняет идентификатор транзакции еще несколькими битами. При этом учитывается, что DNS-запросы нечувствительны к регистру.

К счастью, протокол DNSSEC предоставляет более надежную защиту от спуфинга DNS. Он содержит ряд расширений протокола DNS, призванных обеспечить одновременно и целостность, и аутентификацию источника DNS-данных для клиентов службы DNS. Однако процесс внедрения DNSSEC идет чрезвычайно медленно. Хотя первые работы над ним проводились еще в начале 1990-х годов, а первая спецификация RFC для него была опубликована комитетом IETF в 1997 году, только сейчас DNSSEC начинает находить более-менее широкое применение. Чуть позже мы поговорим об этом подробнее.


Подмена TCP

В TCP произвести подмену данных гораздо сложнее, чем в протоколах, рассмотренных выше. Чтобы создать впечатление, что TCP-сегмент пришел от какого-то компьютера в интернете, злоумышленникам нужно подобрать не только номер порта, но и правильные порядковые номера. Кроме того, при подмене TCP-сегментов чрезвычайно сложно поддерживать нормальное TCP-соединение. Есть две разновидности такой атаки:


1. Подмена соединения (connection spoofing). Злоумышленник устанавливает новое соединение, выдавая себя за пользователя, использующего другой компьютер.

2. Захват соединения (connection hijacking). Злоумышленник внедряет данные в рамках уже существующего соединения между двумя пользователями, выдавая себя за одного из них.

Яркий пример подмены TCP-соединения (TCP connection spoofing) — атака на Суперкомпьютерный центр Сан-Диего, проведенная Кевином Митником (Kevin Mitnick) 25 декабря 1994 года. Это одна из самых известных хакерских атак в истории, ставшая темой нескольких книг и фильмов, включая высокобюджетный триллер «Взлом» («Takedown»), снятый по книге системного администратора Суперкомпьютерного центра. (Неудивительно, что он изображен в фильме как очень крутой парень.) Мы обсудим эту историю, поскольку она хорошо демонстрирует, насколько сложно произвести подмену TCP.

К тому моменту, когда Кевин Митник обратил свой взор на Суперкомпьютерный центр Сан-Диего, он уже достаточно давно занимался «хулиганством» в интернете. Надо сказать, что идея проводить атаки в рождественские дни вполне разумна, ведь в праздники пользователей обычно меньше, как и контроля со стороны администраторов. Проведя предварительную разведку, Митник обнаружил, что один из компьютеров центра (X-терминал) доверял другому компьютеру этого центра (серверу).

Эта конфигурация показана на илл. 8.5 (а). Серверу оказывалось безоговорочное доверие, и любой его пользователь мог войти в X-терминал как администратор с помощью удаленной оболочки (rsh) без пароля. План Митника состоял в том, чтобы установить TCP-соединение с X-терминалом, выдавая себя за сервер, а затем с его помощью полностью отключить парольную защиту — в те дни это можно было сделать, записав «+ +» в файле .rhosts.

Однако сделать это было не так просто. Если бы Митник отправил X-терминалу поддельный запрос на установление TCP-соединения (сегмент SYN) с IP-адресом сервера (шаг 1 на илл. 8.5 (б)), то X-терминал отправил бы ответ SYN/ACK реальному серверу, и Митник бы этого не увидел (шаг 2 на илл. 8.5 (б)). В результате он бы не узнал изначальный порядковый номер X-терминала (ISN). Это практически случайный номер, который был нужен Митнику для проведения третьего этапа «рукопожатия» TCP (на котором, как мы видели ранее, передается первый сегмент с данными). Что еще хуже, получив сегмент SYN/ACK, сервер сразу же ответил бы на это сегментом RST, чтобы прекратить установление соединения (шаг 3 на илл. 8.5 (в)). Поступление SYN/ACK говорит о проблеме, ведь сервер не отправлял перед этим SYN.

Илл. 8.5. Проблемы, с которыми столкнулся Кевин Митник при атаке на Суперкомпьютерный центр Сан-Диего

Тот факт, что Митник не видел сегмент SYN/ACK и поэтому не мог получить ISN, не стало бы проблемой, если бы этот номер был предсказуемым (например, начинался с 0 для каждого нового соединения). Но поскольку ISN выбирался достаточно случайно для каждого соединения, нужно было выяснить, как он генерировался, чтобы предсказать, какой номер использует X-терминал в невидимом сегменте SYN/ACK, который он отправит серверу.

Чтобы решить все эти проблемы, Митник провел свою атаку в несколько этапов. Он начал с активного взаимодействия с X-терминалом с использованием неподдельных сообщений SYN (шаг 1 на илл. 8.6 (а)). Хотя эти попытки не привели к установлению TCP-соединения с X-терминалом, они позволили получить некоторую последовательность ISN. К счастью для Кевина, номера выбирались не таким уж случайным образом. Понаблюдав за ними некоторое время, он смог выявить закономерность. Теперь он был уверен, что, получив один ISN, он сможет предсказать следующий. Затем он позаботился о том, чтобы доверенный сервер не мог сбросить его попытки подключения. Для этого он запустил DoS-атаку, которая сделала сервер недоступным (шаг 2 на илл. 8.6 (б)). После этого уже можно было приступить к проведению реальной атаки.

После отправки поддельного пакета SYN (шаг 3 на илл. 8.6 (б)) он определил, какой ISN будет использован X-терминалом в отсылаемом на сервер ответе SYN/ACK (шаг 4 на илл. 8.6 (б)). Он указал этот номер на третьем и последнем шаге, где отправил команду echo «+ +» >> .rhosts в качестве данных на порт, используемый демоном удаленной оболочки (шаг 5 на илл. 8.6 (в)). После этого он мог войти в систему с любого компьютера без пароля.

Поскольку атака Митника стала возможной главным образом из-за предсказуемости номеров ISN протокола TCP, впоследствии разработчики сетевых стеков приложили немало усилий к тому, чтобы повысить степень случайности при выборе протоколом TCP этих важных для безопасности номеров. Поэтому теперь реализовать такую атаку уже невозможно. Сегодня злоумышленники должны подбирать ISN иначе, например так, как это делается в случае захвата соединения. Обсудим эту разновидность атак более подробно.

Илл. 8.6. Атака Митника


Захват TCP-соединения

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

Для большей конкретности предположим, что злоумышленник хочет внедрить некоторые данные в TCP-соединение клиента, который вошел в веб-приложение на сервере, с тем чтобы либо клиент, либо сервер получил внедренные зло­умышленником байты. Пусть для последних байтов, отправляемых клиентом и сервером, используются порядковые номера 1000 и 12500 соответственно. Допустим, все полученные до этого данные были подтверждены, и ни клиент ни сервер сейчас ничего не отправляют. В этот момент хакер внедряет, скажем, 100 байт в идущий к серверу TCP-поток путем отправки поддельного пакета, который содержит IP-адрес и порт источника клиента, а также IP-адрес и порт источника сервера. Этих четырех значений достаточно, чтобы сетевой стек демультиплексировал данные в нужный сокет. Помимо этого, злоумышленник предоставляет надлежащий порядковый номер (1001) и номер подтверждения (12501), и, таким образом, TCP передаст на веб-сервер 100 байт пользовательских данных.

Однако здесь возникает небольшая проблема. После передачи внедренных байтов приложению сервер отправит клиенту сообщение, подтверждающее их получение: «Спасибо за байты, готов получить байт номер 1101». Это сообщение оказывается неожиданным для клиента, и он думает, что сервер допустил ошибку. Ведь он не отправлял никаких данных и только собирается отправить байт 1001. Он быстро сообщает об этом серверу, отправив пустой сегмент с порядковым номером 1001 и номером подтверждения 12501. «Вот это да! — говорит сервер. — Спасибо, но это выглядит как старое подтверждение. А я уже получил следующие 100 байт. Лучше сообщить об этом удаленной стороне». Он снова отправляет подтверждение с номерами 1101 и 12501, на что клиент отвечает еще одним подтверждением, и т.д. Такая ситуация называется штормом подтверждений (ACK storm). Этот цикл прекратится лишь в том случае, если одно из подтверждений будет потеряно (в силу того, что протокол TCP не производит повторную передачу подтверждений, не содержащих какие-либо данные).

Каким же образом злоумышленник может утихомирить шторм подтверждений? Для этого существует несколько способов, которые мы сейчас обсудим. Самый простой подход сводится к тому, чтобы напрямую разорвать соединение, отправив RST-сегмент участникам коммуникации. В качестве альтернативы можно произвести отравление ARP, чтобы одно из подтверждений ушло на несуществующий адрес и потерялось. Еще одна стратегия состоит в том, чтобы внести настолько большое рассогласование между сервером и клиентом, чтобы сервер начал игнорировать все данные от клиента, и наоборот. Это достаточно сложно сделать путем отправки большого количества данных, но хакер может легко реализовать это на этапе установления соединения. Идея в следующем. Злоумышленник ждет, пока клиент не установит соединение с сервером. После отправки сервером ответного пакета SYN/ACK взломщик отсылает ему пакет RST для завершения соединения, а сразу за ним — пакет SYN с теми же IP-адресом и TCP-портом источника, которые изначально использовал клиент, но с другим порядковым номером клиентской стороны. После отправки сервером следующего пакета SYN/ACK как сервер, так и клиент будут находиться в состоянии установленного соединения, но не смогут взаимодействовать друг с другом. Ведь разница между их порядковыми номерами настолько большая, что они всегда будут находиться за пределами допустимого окна. Вместо этого злоумышленник, выступающий в роли «человека посередине», будет ретранслировать трафик между сторонами и при желании внедрять нужные ему данные.


Внемаршрутный взлом TCP

Некоторые разновидности атак настолько сложны, что трудно понять даже сам принцип их действия, не говоря уже о том, чтобы как-то от них защититься. В данном разделе мы рассмотрим одну из них. Обычно злоумышленники не находятся в том же сегменте сети, что и участники коммуникации, и не могут прослушивать трафик между ними. Атаки, проводимые в таких условиях, называются внемаршрутным взломом TCP (off-path TCP exploit) и очень трудны в реализации. Даже если игнорировать возможный шторм подтверждений, чтобы внедрить данные в существующее соединение, злоумышленник должен собрать довольно много информации:


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

2. Затем нужно выяснить, какие номера портов использовать.

3. Наконец, необходимо узнать порядковые номера.

Это довольно сложная задача для того, кто находится на другом конце интернета, но все-таки ее можно выполнить. Спустя десятилетия после атаки Митника на Суперкомпьютерный центр Сан-Диего исследователи в области информационной безопасности выявили новую уязвимость, позволившую им реализовать внемаршрутный взлом TCP на популярных системах Linux. Они описали свою атаку в статье «Внемаршрутный взлом TCP: глобальное ограничение скорости опасно» (весьма удачное название, как мы увидим далее). Мы рассмотрим этот случай, поскольку он хорошо демонстрирует, что утечка секретной информации может произойти косвенным образом.

По иронии судьбы проведение этой атаки стало возможным благодаря новой функции, которая должна была, наоборот, повысить, а не снизить степень защиты системы. Как уже упоминалось, внемаршрутное внедрение данных было очень сложной задачей. Злоумышленник должен был угадать номера портов и порядковые номера, а это трудно сделать методом прямого подбора. Тем не менее это возможно, учитывая, что точный порядковый номер не требовался — достаточно было обеспечить отправку данных в пределах допустимого окна. То есть с некоторой (очень малой) долей вероятности злоумышленники могли сбросить соединение или внедрить данные в существующие соединения. В августе 2010 года для решения этой проблемы было выпущено новое расширение протокола TCP (RFC 5961).

Спецификация RFC 5961 изменила то, как TCP принимал сегменты SYN, RST и обычные сегменты данных. Описанная уязвимость имелась только в Linux, поскольку лишь в этой системе RFC 5961 была реализована должным образом. Чтобы понять, как изменился протокол TCP с новым расширением, нужно разобраться, как он работал до этого. Сначала выясним, как TCP принимал сегменты SYN. До выхода RFC 5961 при получении SYN для уже существующего соединения TCP отбрасывал этот пакет, если он находился за пределами допустимого окна, и сбрасывал соединение, если он находился в его пределах. Это объяснялось следующим образом. При получении SYN TCP предполагал, что другой абонент произвел перезапуск, а значит, существующее соединение утратило актуальность. Такое поведение было не слишком разумным, ведь чтобы сбросить соединение, злоумышленнику достаточно было получить лишь один сегмент SYN с порядковым номером, попадающим в окно получателя. Вместо этого RFC 5961 предложила не сбрасывать соединение сразу, а сначала отправлять подтверждение запроса (challenge ACK) очевидному источнику сегмента SYN. Если пакет пришел от реального удаленного узла, значит, этот узел действительно потерял предыдущее соединение и теперь устанавливает новое. В этом случае при получении подтверждения запроса он отправит пакет RST с корректным порядковым номером. Этого не смогут сделать злоумышленники, поскольку они не получат подтверждение запроса.

То же самое относится и к сегментам RST. В исходной версии TCP хосты удаляли RST-пакеты, если они не попадали в допустимое окно, в противном случае они сбрасывали соединение. Чтобы усложнить сброс чужого соединения, в RFC 5961 было предложено немедленно прерывать его, только если порядковый номер в RST точно совпадает с номером, с которого начинается окно получателя (то есть со следующим ожидаемым порядковым номером). Когда этот номер не совпадает с ожидаемым, но находится в пределах допустимого окна, хост не разрывает соединение и отсылает подтверждение запроса. Если мы имеем дело с реальным отправителем, то он передаст RST-пакет с корректным порядковым номером.

Наконец, для сегментов данных протокол TCP старого образца проводил две проверки. Сначала он проверял порядковый номер, и если тот находился в пределах допустимого окна, он также проверял номер подтверждения, который считался действительным при попадании в определенный (огромный) интервал. Мы обозначим порядковый номер первого неподтвержденного байта как FUB, а номер следующего байта, подлежащего отправке, как NEXT. В этом случае действительны все пакеты с номерами подтверждения в диапазоне [FUB – 2GB, NEXT], или половина всего пространства номеров подтверждения. Злоумышленники просто не могут не воспользоваться такой ситуацией! Более того, если номер подтверждения также находился в пределах окна, прежний TCP обрабатывал данные и производил стандартное продвижение окна. Вместо этого спецификация RFC 5961 предписывает принимать те пакеты, у которых номер подтверждения находится внутри окна (приблизительно), и отправлять подтверждение запроса в случае пакетов, попадающих в окно [FUB – 2GB, FUB – MAXWIN], где MAXWIN — самое большое из когда-либо объявленных узлом окон.

Разработчики RFC 5961 быстро поняли, что это расширение может порождать очень много подтверждений запроса, и предложили ограничить количество подтверждений. В реализации для Linux это означало отправку не более 100 подтверждений запроса в секунду в рамках всех соединений. То есть некая глобальная переменная, общая для всех соединений, должна была отслеживать количество переданных подтверждений. Когда оно достигало 100, отправка прекращалась до окончания 1-секундного интервала (что бы при этом ни происходило).

Как бы хорошо это ни звучало, здесь кроется одна проблема. Единственная глобальная переменная здесь отражает общее состояние, что может стать побочным каналом для хорошо продуманной атаки. Рассмотрим первое препятствие, стоящее перед злоумышленниками, — вопрос о наличии соединения между двумя пользователями. Как вы помните, подтверждение запроса высылается в трех случаях:


1. В сегменте SYN указаны правильные IP-адреса отправителя и получателя и номера портов; при этом неважно, каким будет порядковый номер.

2. Порядковый номер сегмента RST находится в пределах допустимого окна.

3. В сегменте данных номер подтверждения также находится в пределах окна для запросов.

Допустим, злоумышленники хотят выяснить, имеется ли соединение между пользователем с адресом 130.37.20.7 и веб-сервером (с портом получателя 80) с адресом 37.60.194.64. Поскольку взломщикам не нужен точный порядковый номер, им достаточно лишь подобрать номер порта отправителя. Для этого они подключаются к веб-серверу и отправляют 100 пакетов RST подряд, в ответ на что сервер отправляет 100 подтверждений запроса (либо меньше, если часть таких подтверждений уже была отправлена до этого, что, впрочем, маловероятно). После 100 пакетов RST злоумышленники отправляют поддельный сегмент SYN, выдавая себя за клиента с адресом 130.37.20.7 с помощью подобранного номера порта. Если номер подобран неверно, то ничего не происходит, и взломщикам все равно приходит 100 подтверждений. Но если он подобран правильно, мы получаем первый сценарий, при котором сервер отсылает подтверждение запроса реальному клиенту. Поскольку сервер может отправлять только 100 подтверждений запроса в секунду, из них злоумышленники получат только 99. То есть, посчитав полученные подтверждения, они могут не только выявить наличие соединения между двумя хостами, но и определить используемый клиентом номер порта источника (скрытый). Конечно, для этого потребуется довольно много попыток, но это вполне осуществимо. Кроме того, существуют методы, позволяющие повысить эффективность этого процесса.

Получив номер порта, злоумышленники могут перейти к следующему этапу атаки: подбору порядкового номера и номера подтверждения. Это делается аналогичным образом. В случае порядкового номера хакеры снова отсылают 100 подлинных пакетов RST (побуждая сервер к отправке подтверждений запросов) и дополнительный поддельный RST с правильными IP-адресами и уже известными номерами портов, а также подобранным порядковым номером. Если подобранный номер попадает в окно, мы получаем второй сценарий. То есть злоумышленники могут определить, правильно ли они подобрали номер, подсчитав количество полученных подтверждений запроса.

Наконец, в случае номера подтверждения они повторяют тот же трюк, отправляя в дополнение к 100 RST пакет данных, у которого все поля содержат корректные данные, за исключением подобранного номера подтверждения. После этого у злоумышленников имеется вся информация, необходимая для сброса соединения или внедрения данных.

Внемаршрутный взлом TCP хорошо демонстрирует три момента. Во-первых, мы понимаем, насколько сложными могут быть сетевые атаки. Во-вторых, это прекрасный пример сетевой атаки по побочным каналам (side-channel attack). С ее помощью хакеры получают важную информацию по обходному каналу. В данном случае они узнают все нужные им параметры подключения путем подсчета, казалось бы, никак не связанных с этим вещей. В-третьих, внемаршрутный взлом TCP показывает, что главная причина, из-за которой атаки по побочным каналам стали возможными, — хранение общего состояния в глобальной переменной. Уязвимости побочных каналов очень часто встречаются и в программном, и в аппаратном обеспечении, и всегда коренным источником проблем является совместное использование какого-нибудь важного ресурса. Конечно, мы и так это знали, ведь такое разделение ресурсов идет вразрез с базовой идеей Зальцера и Шредера о необходимости минимизировать количество общих механизмов, о которой мы говорили в начале главы. В сфере безопасности представление о том, что с другими нужно делиться, не соответствует действительности!

Прежде чем перейти к следующей теме (нарушение работы и отказ в обслуживании), следует отметить, что внедрение данных не относится к числу методов, представляющих исключительно теоретический интерес; он также активно используется на практике. После разоблачений, сделанных Эдвардом Сноуденом (Edward Snowden) в 2013 году, стало известно, что американское Агентство национальной безопасности (National Security Agency, NSA) проводило массовую слежку за гражданами. Одним из направлений этой деятельности было проведение сложной сетевой атаки Quantum. Когда определенные пользователи подключались к популярным сервисам (Twitter, Gmail или Facebook), их перенаправляли на специальные серверы путем внедрения пакетов. Затем эти серверы взламывали компьютеры жертв для получения полного доступа к хранящейся на них информации. Конечно, NSA полностью отрицает это. Оно готово отрицать сам факт своего существования. Иногда «NSA» в шутку расшифровывают как «No Such Agency» («нет такого агентства»).


8.2.4. Нарушение работы

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


1. Аварийный отказ. Отправленный злоумышленником контент вызывает аварийный отказ или зависание компьютера жертвы. Примером такой атаки является «пинг смерти», упомянутый ранее.

2. Алгоритмическая сложность. Злоумышленник отправляет такие данные, обработка которых требует больших вычислительных затрат (на уровне алгоритмов). Предположим, сервер позволяет клиентам отсылать расширенные поисковые запросы. В этом случае атака за счет алгоритмической сложности может сводиться к отправке ряда сложных регулярных выражений, что приведет к ситуации с наихудшим временем поиска.

3. Переполнение данными. Злоумышленник закидывает жертву таким гигантским количеством запросов или ответов, что система не справляется с ними. Часто, хотя и не всегда, это приводит к аварийному отказу компьютера жертвы.

Атаки переполнения данными стали серьезной головной болью многих организаций, ведь на сегодняшний день провести крупномасштабную DoS-атаку очень просто и дешево. За небольшую денежную сумму можно арендовать сеть ботов с тысячами компьютеров и атаковать любой адрес. Если данные отправляются с большого количества компьютеров из разных уголков мира, то это распределенная атака типа «отказ в обслуживании», или DDoS-атака (Distributed Denial-of-Service). Устроить DDoS-атаку может даже далекий от техники человек с помощью существующих в интернете «стрессоров» или «бутеров» — специализированных сервисов, предлагающих для этой цели удобный интерфейс.


Переполнение SYN-пакетами

В старые добрые времена DDoS-атаки были достаточно простыми. Например, можно было использовать множество взломанных компьютеров, чтобы обеспечить переполнение SYN-пакетами. Все эти компьютеры отправляли на сервер TCP-сегменты SYN, в которых часто были подделаны данные об отправителе. Пока сервер отправлял ответы SYN/ACK, никакой другой компьютер не мог завершить «рукопожатие» TCP. Таким образом, сервер оставался в зависшем состоянии, а это довольно затратно. Каждый хост может поддерживать лишь ограниченное количество полуоткрытых TCP-соединений и уже не принимает новые соединения по достижении этого предела.

Существует много способов защиты от переполнения SYN-пакетами. Например, можно просто отбрасывать полуоткрытые соединения после достижения предела, отдавая предпочтение новым, или уменьшить время жизни принятых SYN-пакетов. Очень элегантное и простое решение, которое сегодня поддерживает большинство существующих систем, сводится к использованию файлов SYN cookie, уже упоминавшихся в главе 6. Специальный алгоритм устанавливает изначальный порядковый номер таким образом, чтобы серверу не нужно было запоминать никакие параметры подключения до получения третьего пакета в «тройном рукопожатия». Как вы помните, размер порядкового номера составляет 32 бита. При использовании файлов SYN cookie сервер выбирает изначальный порядковый номер так:


1. Первые 5 бит отводятся под результат деления t по модулю на 32, где t — значение медленно возрастающего таймера (например, его значение увеличивается с интервалом в 64 с).

2. В следующих 3 битах кодируется значение MSS (максимальный размер сегмента), что дает восемь возможных значений.

3. Оставшиеся 24 бита отводятся под криптографический хеш, вычисляемый на основе временной метки t, IP-адресов отправителя и получателя и номеров портов.

Преимуществом такого порядкового номера является то, что сервер может просто вставить его в пакет SYN/ACK и забыть об этом. Если процесс «рукопожатия» не завершится, это не приведет к каким-либо тяжелым последствиям. Если же он будет завершен, то наличие собственного порядкового номера в дополнение к номеру в подтверждении позволит серверу полностью воспроизвести состояние, необходимое ему для установления соединения. Сначала сервер проверяет, совпадает ли криптографический хеш с последним значением t, а затем быстро восстанавливает запись в SYN-очередь, используя 3-битное значение MSS. Хотя файлы SYN cookie позволяют использовать только восемь вариантов размера сегмента и несколько ускоряют рост порядковых номеров, это практически не дает какого-либо негативного эффекта. Особенно приятно то, что данная схема совместима с обычным протоколом TCP и не требует, чтобы клиент поддерживал такое же расширение.

Конечно, наличие файлов SYN cookie не исключает вероятность того, что хакеры проведут DDoS-атаку, завершив процесс «рукопожатия». Но это обойдется им гораздо дороже (поскольку их компьютеры тоже имеют ограничение на количество открытых TCP-соединений), и что еще важнее, они не смогут провести атаку на TCP с использованием поддельных IP-адресов.


Отражение и усиление DDoS-атак

Между тем DDoS-атаки на основе TCP не являются единственным возможным вариантом. В последние годы все больше крупномасштабных DDoS-атак проводится с UDP в качестве транспортного протокола. Подмена UDP-пакетов обычно не представляет больших проблем. Более того, использование UDP позволяет заставить реальные серверы в интернете провести против жертвы атаку с отражением (reflection attack). В этом случае хакер отправляет запрос с поддельным адресом отправителя реальному UDP-сервису (например, серверу имен). После этого сервер отвечает на поддельный адрес. Если отослать такие запросы большому количеству серверов, то лавина ответных UDP-пакетов, скорее всего, выведет компьютер жертвы из строя. Атаки с отражением имеют два главных преимущества:


1. Добавив дополнительный уровень косвенности, злоумышленник усложняет для жертвы задачу блокировки отправителей (ведь это реальные серверы).

2. Часто сервисы усиливают атаку за счет отправки больших ответов на небольшие запросы.

Именно к данному виду атак с усилением относятся некоторые известные DDoS-атаки с рекордным объемом трафика, измерявшимся терабитами в секунду. Для успешного осуществления такой атаки злоумышленник должен найти общедоступные сервисы с большим коэффициентом усиления, где один небольшой пакет запроса может повлечь большой ответный пакет (а лучше несколько). При этом байтовый коэффициент усиления будет отражать относительное усиление в байтах, а пакетный — относительное усиление, выраженное в количестве пакетов. На илл. 8.7 представлены коэффициенты усиления нескольких популярных протоколов. Как бы внушительно ни выглядели эти цифры, важно помнить, что это средние значения, и у некоторых серверов эти показатели могут быть еще выше. Что интересно, у протокола DNSSEC, со­зданного для устранения проблем безо­пасности DNS, коэффициент усиления намного выше, чем у обычного протокола DNS, и в случае отдельных серверов может превышать 100. Не отстают в этом плане и некорректно настроенные memcached-серверы (быстрые базы данных в оперативной памяти) — в ходе крупномасштабной атаки с усилением, проведенной с их помощью в 2018 году, был достигнут объем трафика в 1,7 Тбит/с и коэффициент усиления, намного превышающий 50 000.

Протокол

Байтовый коэффициент усиления

Пакетный коэффициент усиления

NTP

556,9

3,8

DNS

54,6

2,1

BitTorrent

3,8

1,6

Илл. 8.7. Коэффициенты усиления популярных протоколов


Защита от DDoS-атак

Хотя защититься от столь огромных потоков трафика нелегко, все же существует несколько способов. Один из самых простых состоит в том, чтобы заблокировать трафик в непосредственной близости от его источника. Как правило, для этого используется выходная фильтрация (egress filtering), при которой сетевое устройство, брандмауэр, блокирует все исходящие пакеты, у которых IP-адрес отправителя не входит в число адресов его сети. Конечно, при этом брандмауэр должен знать, какие пакеты могут прийти с определенным IP-адресом источника; как правило, это возможно только в пограничном сегменте сети. Например, брандмауэр может знать все диапазоны IP-адресов университетской сети и блокировать трафик от любого постороннего IP-адреса. Противоположностью выходной фильтрации является входная фильтрация (ingress filtering), при которой сетевое устройство отбрасывает весь входящий трафик с внутренними IP-адресами.

Еще один способ защиты сводится к тому, чтобы попытаться «поглотить» DDoS-атаку с помощью резервной пропускной способности, что требует больших затрат, непозволительных для отдельной организации (за исключением самых крупных компаний). К счастью, это необязательно делать в одиночку. Если организации объединят свои ресурсы, то даже очень небольшие компании смогут позволить себе такую защиту от DDoS-атак. Как и в случае страхования, предполагается, что хакеры не атакуют всех сразу.

Так какую «страховку» мы при этом получаем? Существуют компании, предлагающие сайтам облачную защиту от DDoS-атак: при необходимости емкость увеличивается за счет облака. При этом фактически обеспечивается облачное экранирование или даже сокрытие IP-адреса реального сервера. Все запросы передаются расположенным в облаке прокси-серверам, которые по возможности отсеивают вредоносный трафик (в случае продвинутых атак это очень непросто) и направляют безопасные запросы на реальный сервер. В случае роста числа запросов или объема трафика, идущего на конкретный сервер, облако выделяет дополнительные ресурсы для обработки пакетов. То есть оно «поглощает» возрастающий поток данных. Обычно облако также выступает и в качестве скруббера («щетки») для очистки данных. Например, оно может удалять дублирующие друг друга TCP-сегменты или недопустимые комбинации TCP-флагов и в целом играть роль брандмауэра веб-приложений (Web Application Firewall, WAF).

Существует несколько разных по стоимости вариантов ретрансляции трафика через облачные прокси-серверы. Если финансы позволяют, можно воспользоваться методом создания черной дыры с помощью BGP (BGP blackholing). В этом случае предполагается, что владелец сайта целиком контролирует блок /24 из 16 777 216 адресов. Идея в том, чтобы владелец сайта просто удалил объявления BGP для этого блока в своих маршрутизаторах. Вместо этого поставщик облачной защиты начинает объявлять эти IP-адреса из собственной сети, чтобы весь идущий на сервер трафик сначала проходил через облако. Но далеко не каждый имеет в своем распоряжении целый блок сети и может оплатить перенаправление BGP. Есть более экономный вариант — перенаправление DNS (DNS rerouting). Администраторы сайта должны изменить DNS-сопоставления на своих серверах имен так, чтобы они указывали не на реальный сервер, а на серверы в облаке. В обоих случаях пакеты посетителей сайта сначала попадают на прокси-сервер поставщика облачной защиты, а затем перенаправляются на реальный сервер.

Хотя перенаправление DNS проще в реализации, такая защита будет надежной, только если вам удастся сохранять в тайне реальный IP-адрес сервера. Если зло­умышленники узнают этот адрес, они смогут атаковать сервер напрямую, действуя в обход облака. К сожалению, существует целый ряд каналов, по которым может произойти утечка сведений об IP-адресе. Подобно протоколу FTP, некоторые веб-приложения передают IP-адрес удаленному абоненту путем внутриполосной передачи, что является практически неразрешимой проблемой. Еще одним каналом утечки являются архивные данные службы DNS, которые позволяют злоумышленникам увидеть, какие IP-адреса сервер использовал в прошлом. Некоторые компании занимаются тем, что собирают и продают такие архивы.



41 От англ. «Xmas» — «Christmas», Рождество. — Примеч. пер.

Загрузка...