МАКСИМ СТЕПИН (maxim.stepin@usa.net)
Широкое распространение сетей, построенных на основе протокола TCP/IP (как локальных, так и Internet), привело к разработке методов преодоления защиты и появлению множества программ, предназначенных для совершения неправомерных действий в таких сетях.
У неспециалиста в области компьютерной безопасности, читающего в прессе о все новых и новых случаях взлома защитных систем, ошибках в программном обеспечении и т. п., складывается впечатление об абсолютном беспределе, царящем в киберпространстве, и уязвимости подключенного к сети компьютера.
Сейчас, когда 16-битные платформы практически отошли в прошлое, самыми распространенными операционными системами являются различные версии Windows, и в настоящее время подавляющее большинство компьютеров работает под управлением одной из следующих систем: Windows 95, Windows 95 OSR2, Windows 98, Windows NT 3.51 или Windows NT 4.0. Поэтому рассмотрение некоторых аспектов безопасности этих систем будет интересно большинству пользователей. А поскольку Windows NT позиционируется как серверная платформа, то статья может представлять интерес и для начинающих системных администраторов.
Неправомерные действия по отношению к компьютерам и сетям можно разделить на несколько групп: взлом с целью получения привилегированного доступа, взлом с целью похищения конфиденциальной информации и т. д. Особняком стоят действия, не преследующие личной выгоды и состоящие просто во вредительстве, выведении систем из строя. Как пример можно привести написание вирусов.
Атаки, использующие ошибки в стандартах и их реализациях, называются Denial of Service ("отказ в обслуживании"), или DoS-атаки. В этой статье мы дадим краткий обзор DoS-атак для Windows-систем.
Нередко различные DoS-атаки называют общим термином nuke. Одна из самых известных атак как раз и называется WinNuke (о ней чуть ниже). Восстановим историческую справедливость в этом вопросе.
Существует метод атаки, называемый просто nuke. Собственно, классический nuke не является DoS-атакой. Идея целиком основана на документированных стандартах, а не на ошибках в конкретной реализации TCP/IP. Суть классического nuke заключается в следующем. Для служебных целей в IP-сетях используется протокол ICMP (Internet Control Message Protocol; его описание см., например, в RFC 1122). В частности, с этим протоколом мы встречаемся, когда используем программы ping и traceroute. Одной из возможностей ICMP является проверка наличия определенного адреса в сети. В случае ошибки соединения проводится диагностика ситуации и выдается сообщение: "сеть недоступна", "адрес недоступен", "ошибка маршрутизации" и др. Стандартные реализации TCP/IP-стека по приходу ICMP-пакета с извещением об ошибке производят определенные действия, в частности, перестройку таблицы маршрутизации. Но как побочный эффект происходит разрыв всех установленных соединений с машиной, имеющей адрес, о котором стало известно, что он недостижим. На основе этого эффекта и строятся диверсии.
Действительно, если знать, что компьютер с адресом X установил соединение с компьютером Y, и послать ICMP-сообщение об ошибке на компьютер X с исходящим адресом компьютера Y, то безусловной реакцией будет разрыв этого соединения. Для осуществления подобной атаки необходимо работать с IP на более низком уровне, нежели стандартные функции. Чтобы подставить в пакет фальшивый адрес отправителя, нужно взаимодействовать непосредственно с IP, "вручную" заполняя все структуры, необходимые протоколам более высокого уровня.
Подмена адресов IP-пакетов называется спуфингом (от англ. spoofing - мистификация, обман). Практический эффект такого рода атак невелик. Для их осуществления необходимо знать, что два компьютера установили между собой соединение. Пользователю, бесцельно бродящему по WWW, сделать это практически невозможно. Более уязвимы к такого рода "диверсии" пользователи, которые долго поддерживают соединение с определенным компьютером: любители разговаривать на IRC (или в Web-чатах) и играть в различные онлайновые игры (от MUD до новейших 3D-стрелялок).
Классический nuke является одним из излюбленных инструментов ведения "военных действий" на IRC. Хотя простого способа противодействия ему не существует, утешает то, что среднестатистическому пользователю ничего не угрожает. А теперь перейдем непосредственно к описанию DoS-атак.
Начнем, конечно же, с классического и широко известного WinNuke, появившегося 7 мая 1997 года. Автор метода поместил его описание и исходный текст программы в несколько news-конференций. Ввиду крайней простоты метода практически каждый мог вооружиться новейшим оружием и пойти крушить направо и налево.
Первой жертвой стал сервер www.microsoft.com. Он прекратил откликаться в пятницу вечером (9 мая) и только к обеду понедельника вновь обрел устойчивость. Остается лишь пожалеть его администраторов, которые весь уик-энд регулярно нажимали волшебную комбинацию трех клавиш, после чего реанимированный сервер падал вновь. А может быть, после первых нескольких попыток сервер и прекратили оживлять, кто знает...
Конечно же, наряду с жертвой номер раз в мае 97-го пали многие серверы, на которых красовалась гордая надпись "Windows NT Powered", а также серверы и без оной, но работающие под Windows NT. К чести Microsoft следует заметить, что заплатки появились довольно быстро.
Итак, что же такое WinNuke? Наряду с обычными данными стандарт предусматривает пересылку по TCP-соединению и срочных (Out Of Band, OOB) служебных данных. На уровне форматов пакетов TCP это выражается в ненулевом значении соответствующего поля (urgent pointer). Большинство компьютеров, работающих под Windows, используют сетевой протокол NetBIOS, нуждающийся в трех IP-портах: 137, 138, 139. Как выяснилось, если соединиться с Windows-машиной через 139-й порт и послать туда несколько байт OOB-данных, то NetBIOS, не зная, что делать с этими данными, попросту подвешивает или перезагружает машину. В Windows 95 это обычно выглядит как синий текстовый экран с сообщением об ошибке в драйвере TCP/IP, и работа с сетью становится невозможной до перезагрузки ОС. NT 4.0 без service pack'ов перезагружается. NT 4.0 лишь со вторым service pack'ом выпадает в синий экран, сообщая о необработанном исключении в коде ядра (эту картинку нередко называют blue screen of death).
Судя по информации в Сети, такой атаке подвержены и Windows NT 3.51, и Windows 3.11 for Workgroups, и WinFrame, в основе которого лежит Windows NT 3.51. Официальные заплатки от Microsoft:
Тут к месту упомянуть довольно забавную историю. Как выяснилось вскоре после выпуска SP3 (service pack 3 для Windows NT 4.0), WinNuke, запущенный с компьютеров Macintosh, легко "пробивал" защиту service pack'а. Причиной послужило существование двух разных стандартов на IP-пакеты, содержащие OOB-данные, - стандарта от Berkley и стандарта, описанного в RFC. Они по-разному вычисляют UrgentPointer, и результат вычислений отличается ровно на единицу. Третий service pack, защищающий от "своих" OOB-пакетов, оказался беззащитен против пакетов другого стандарта. Поэтому почти сразу после SP3 вышел дополнительный OOB-fix. Его можно найти на ftp://ftp.microsoft.com/bussys/winnt/winnt-public/fixes/usa/nt40/hotfixes-postSP3/oob-fix/.
Следует заметить, что если для написания оригинального WinNuke достаточно самых тривиальных функций работы с TCP/IP (программа на PERL занимает семь строк), то, чтобы "пробить" SP3, потребуется работать с TCP на низком уровне либо запускать стандартный WinNuke с платформы, поддерживающей другую реализацию OOB. Само существование OOB-данных, безотносительно WinNuke, вызывает немало проблем именно из-за существования двух стандартов, или, вернее, отсутствия стандарта. Поэтому гарантировать корректную работу программы, использующей OOB, не может никто (правильнее сказать, легко можно гарантировать ее некорректную работу).
Умные люди рекомендуют вообще не использовать OOB-данные в своих программах, и многие так и поступают. Таким образом, OOB сегодня - это наличие потенциальных дырок, позволяющих злоумышленникам изобретать все новые и новые методы атак. Попросту "постреляв" OOB-данными по открытым TCP-портам, можно попытаться найти новую дырку в какой-либо программе. Некоторым, говорят, удается...
Еще одна ошибка обнаружилась буквально через месяц после нашумевшего дебюта WinNuke. Объектом атаки на сей раз стал протокол ICMP, точнее, его реализация. Этот протокол издавна привлекал любителей сетевых диверсий. Поскольку ICMP представляет собой внутренний механизм поддержки работоспособности IP-сетей, то с точки зрения злоумышленника он является очевидным объектом атаки. Как пример можно упомянуть ping с большим размером пакета. Поскольку ICMP-пакеты имеют определенные привилегии в обработке, то ping большого размера может парализовать работу компьютера или даже целой сети, IP-каналы которых будут передавать только ICMP-пакеты.
Такой способ часто используется людьми, имеющими достаточно мощные каналы связи, против тех, кто адекватных каналов не имеет. Сей метод, основанный на грубой силе, очевидно, не требует большого ума (точнее сказать, не требует никакого ума и, видимо, поэтому так любим молодыми сотрудниками провайдерских организаций). Защиты от него в общем случае не существует, самый адекватный метод реакции - установив адрес злоумышленника, написать жалобы куда только можно.
Но мы опять отвлеклись от основной темы. Объектом нашего исследования является известная ошибка, называемая SPing (Jolt, SSPing, IceNuke, IcePing, IceNuke, Ping Of Death...). Множество названий вовсе не означает множества различных модификаций. Просто разные люди называют одну идею по-разному, и встретить программу можно под всеми вышеперечисленными именами. Как выяснилось, Windows-системы неадекватно реагируют на получение сильно фрагментированного ICMP-пакета (кусочками до одного килобайта) большого размера (чуть больше 64 килобайт). Реакция заключается в безоговорочном повисании, включая мышь и клавиатуру. В конце июня 1997 года жертвой SPing пал сервер Microsoft, после чего его закрыли каким-то хитрым брандмауэром (думается, информация о типе и настройках этого брандмауэра относится к важнейшим секретам Microsoft).
В отличие от WinNuke, жертвами SPing могут стать не только Windows-системы, но и Mac OS и некоторые версии Unix (заплатки для них, к счастью, уже имеются). Официальная заплатка от Microsoft для NT 4.0 с установленным SP3 (далее везде по тексту будет подразумеваться, что NT 4.0 имеет установленный SP3) лежит на ftp://ftp.microsoft.com/bussys/winnt/winnt-public/fixes/usa/NT40/hotfixes-postSP3/icmp-fix/.
Заметим, что SPing намного серьезнее, нежели WinNuke, поскольку использует ICMP-пакеты, которые чаще всего не фильтруются брандмауэром, а если и фильтруются, то подобного рода защиту можно попытаться преодолеть, используя приемы спуфинга.
Следующий метод атаки, называемый land, замечателен в первую очередь огромным числом поражаемых систем. Кроме Windows NT, этой напасти подвержены и Mac OS, и множество вариантов Unix (от бесплатных до коммерческих), и такие экзотические системы, как QNX и BeOS, и даже многие аппаратные маршрутизаторы (в том числе от Cisco и 3Com). Практически для всех систем уже имеются исправления, хотя, конечно же, установили их далеко не все владельцы компьютеров.
Что же такое land? При инициации TCP-соединения посылается пакет с установленным флагом SYN. Нормальной реакцией на получение SYN-пакета является подготовка ресурсов для нового соединения, посылка SYN-ACK-пакета (пакета подтверждения) и ожидание реакции с другой стороны. Если в течение определенного времени ответа не последует, SYN-ACK-пакет передается повторно несколько раз, как правило, со все большей задержкой.
Очевидным методом атаки, использующим вышеописанный механизм, является классический SYN-Flood, заключающийся в следующем: на компьютер-жертву посылается множество SYN-пакетов с искаженными адресами отправителя. Компьютер-жертва тратит массу вычислительных ресурсов, пытаясь подтвердить соединения с абсолютно ничего не подозревающими или даже с несуществующими компьютерами. При достаточно большом количестве фальшивых запросов ресурсы компьютера-жертвы могут исчерпаться, и все другие процессы будут остановлены либо аварийно завершены (другой вариант: будут сброшены все имеющиеся соединения).
Но это очень старый метод, основанный на грубой силе. Механизм работы land хитрее. Посылается SYN-пакет с адресом отправителя, совпадающим с адресом получателя, жертвы. Пакет посылается на любой открытый порт. Для Windows-систем это почти всегда может быть порт 139 (наш старый знакомый по WinNuke). Для других систем это может быть любой известный порт (21, 80 и др.). Реакцией Windows-компьютера на land является абсолютное повисание.
Заплатку для Windows NT 4.0 можно скачать с ftp://ftp.microsoft.com/bussys/winnt/winnt-public/fixes/usa/NT40/hotfixes-postSP3/land-fix. Для остальных подверженных атаке систем заплатки могут быть найдены на сайтах компаний-производителей.
Найденный в том же несчастливом 1997 году метод атаки Teardrop основан на ошибках в реализации TCP/IP-стека. Атаке подвержены Windows-системы, а также компьютеры с Linux. Заплатка от Microsoft для Windows NT лежит по адресу ftp://ftp.microsoft.com/bussys/winnt/winnt-public/fixes/usa/NT40/hotfixes-postSP3/simptcp-fix. Строго говоря, эта заплатка, появившаяся довольно быстро, предназначалась для отражения другой атаки (которая заключается в посылке большого количества UDP-пакетов с искаженным адресом отправителя на 19-й порт, что приводит к повышенному UDP-трафику).
Фурора, подобного тому, который вызвал WinNuke, на сей раз не было. Возможно, пользователи уже свыклись с тем, что новые методы DoS-атак появляются регулярно. Тем не менее, Teardrop замечателен тем, что стал первым из семейства подобных (об этом будет рассказано ниже). Он прекрасно иллюстрирует тот факт, что любые программы, даже насчитывающие несколько строк, содержат ошибки. (Если вы уверены, что программа безошибочна, значит, вы просто не заметили ошибки, которая после обнаружения будет казаться очевидной.)
Совершим небольшой экскурс в тайны реализации TCP/IP-стека. Передача данных в TCP/IP-сетях осуществляется не с помощью неких идеальных носителей информации, а по вполне реальным каналам (часто отвратительного качества), и в сам стандарте заложено, что передаваемый пакет может разбиваться на несколько меньших пакетов, а принимающая сторона возвращает ему первоначальный вид. Точнее, более высокоуровневые, чем IP, протоколы TCP и UDP могут передаваться фрагментированно на уровне IP. Каждый фрагмент характеризуется смещением от начала исходного пакета и своей длиной. Драйвер TCP/IP-стека собирает фрагменты на принимающей стороне до тех пор, пока не получит их все (или, во всяком случае, пока не решит, что принял все).
Безусловно, при передаче возможны различные ситуации, которые умная реализация TCP/IP должна распознавать. В частности, может быть, что несколько полученных фрагментов будут пересекаться. Нас интересует ситуация, когда новый фрагмент имеет смещение, лежащее внутри уже полученного фрагмента.
Что же делает TCP/IP-стек в этом случае? Во-первых, вычисляется размер пересечения: смещение старого фрагмента плюс длина старого фрагмента есть смещение нового фрагмента. А затем в буфер копируется только та часть нового фрагмента, которая "выступает за границу" старого фрагмента. Все просто и очевидно. Однако возможна ситуация, когда новый фрагмент не только начинается внутри старого, но и заканчивается в нем же.
По идее, такой фрагмент должен быть просто пропущен, но как раз этого программисты, писавшие Windows NT и Linux, и не предусмотрели. Что же происходит в этом случае? Пусть у нас есть уже полученный фрагмент A, со смещением A_offs и длиной A_len. Пришел новый фрагмент B, со смещением B_offs и длиной B_len. Причем A_offs < B_offs < B_offs + B_len < A_offs + A_len, то есть фрагмент B лежит внутри фрагмента A.
Проследим действия принимающей стороны по шагам. Начало нового фрагмента лежит внутри имеющегося. Пересекающаяся часть имеет смещение A_offs + A_len - B_offs. А тот кусочек, что нужно добавить в буфер, начинается с A_offs + A_len и имеет длину (B_offs + B_len) - (A_offs + A_len).
О-ля-ля! Длина-то меньше нуля или (если вспомнить о машинной зацикленной арифметике) является очень большим числом. И вот такого большого размера блок памяти будет копироваться, уничтожая при этом все встречающееся на пути (обычно под "горячую руку" попадает операционная система). Собственно, вышеописанное и есть Teardrop. Приведенное объяснение абсолютно верно для Linux (поскольку ее исходный код открыт), но, вероятно, аналогичный механизм делает потенциальной жертвой Teardrop-атаки и Windows NT.
Вслед за появлением метода Teardrop возникло несколько его модификаций, которые были способны пробивать Windows NT с установленной против обычного Teardrop заплаткой. Известность получили Bonk (Boink), NewTear, SynDrop. Все эти атаки закрываются еще одной заплаткой: ftp://ftp.microsoft.com/bussys/winnt/winnt-public/fixes/usa/nt40/hotfixes-postSP3/teardrop2-fix.
Наиболее оригинальным среди них является SynDrop. По сути, он представляет собой оригинальный Teardrop с тем отличием, что в посылаемых фрагментах устанавливается флаг SYN (снова этот излюбленный флаг).
После Teardrop-клонов не появлялось широко известных DoS-атак на Windows-платформы. Возможно, злоумышленники просто не предают огласке свои новейшие методы. Кто знает...
Процедура установки всех заплаток для Windows NT 4.0 с SP3 уже давно превратилась в нетривиальное занятие, поскольку заплатки исчисляются несколькими десятками и порядок установки нередко играет определенную роль (грубо говоря, можно установить заплатки в такой последовательности, что система будет неработоспособной). Однако с заплатками от DoS-атак на TCP/IP-стек дело обстоит проще, поскольку они выпускались кумулятивными, то есть последняя заплатка содержит в себе все предыдущие.
Windows 95 также имеет кумулятивные исправления. Их можно найти на:
Windows 98 пока выглядит "неприступной" для DoS-атак. Впрочем, время покажет...
Последнее замечание по технической стороне вопроса: программы для осуществления перечисленных атак, по иронии судьбы, как правило, не реализованы для Windows-платформ.
Причина кроется в том, что Windows-реализация интерфейса сокетов не в полной мере соответствует общепринятому стандарту. Только для WinNuke достаточно простейших процедур реализации сокета. Остальные методы требуют непосредственной работы с заголовками IP-пакетов, для чего необходимо использовать не потоковый или датаграммный сокет, а так называемый "сырой" (SOCK_RAW - если в терминах констант).
WinSock 1.1 попросту не поддерживает такой возможности. Она имеется в WinSock 2.0, но и тут потенциальных нарушителей ждет разочарование: сырые-то они сырые, но возможности менять заголовок так и не появилось. Соответствующая процедура просто не была реализована.
И все же есть способ использовать Windows в качестве платформы для атаки. Нужно написать NDIS-драйвер, который бы, перехватывая все IP-пакеты, открывал доступ к их внутренней структуре. Но, по счастью, люди, обладающие необходимой квалификацией, находят себе более интересные занятия.
Для тех, кто заинтересовался поднятыми в статье вопросами, привожу небольшой список полезных URL:
И в заключение привожу статью УК РФ, соответствующую тематике.