К счастью, протокол 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 не производит повторную передачу подтверждений, не содержащих какие-либо данные).