Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР 109, ЯНВАРЬ 2008 г.

Сырость не радость

Крис Касперски

Хакер, номер #109, стр. 050

Реализация сырых сокетов в WinNT

Сырые сокеты (raw sockets) широко используются как в хакерских, так и в легальных коммерческих программах: эксплойтах, спуферах, сниферах, сканерах, брандмауэрах, NAT'ах, etc. Никсы поддерживают сырые сокеты изначально, 9x – лишь формально. С выходом W2K Microsoft подарила нам полноценную поддержку сырых сокетов, но начиная с XP SP2 сурово урезала их функциональность, в результате чего многие системные программы перестали работать. Чтобы вернуть былую функциональность, программистам пришлось опуститься на уровень ядра или заюзать библиотеку WinCap. А что делать простым пользователям? Как оживить старые программы, не имея исходных текстов на руках? Без паники! Сейчас я все расскажу.

Сокеты представляют собой индустриальный стандарт унифицированного интерфейса, ориентированный на межпроцессорное взаимодействие и поддерживаемый практически всеми операционными системами. Причем сокету все равно, где находится соседний процесс — на локальной машине или на другом конце света (тьмы). В общем случае сокет представляет собой комбинацию IP-адреса и порта (например: 192.168.6.9:25), а также набор функций для установки соединения и обмена данными.

Обычные сокеты — явные приверженцы парадигмы ООП и позволяют взаимодействовать с заголовками пакетов только путем вызова соответствующих API-функций. Мы можем задавать целевой адрес и порт назначения (а при желании и локальный порт), устанавливать некоторые флаги типа TTL (Time To Live - время жизни) или TOS (Type of Service - тип сервиса). Остальные же поля (например, поле контрольной суммы или флаг фрагментации) операционная система заполняет самостоятельно. Программист лишен права вмешиваться в этот тонкий процесс. Впрочем, большинству прикладных протоколов (POP3/SMTP/HTTP) обозначенных возможностей вполне достаточно, и программистам жаловаться не приходится. А хакерам?

Сырые сокеты выгодно отличаются тем, что позволяют собирать TCP/IP-пакеты, вручную контролируя каждый бит заголовка и отправляя в сеть нестандартные пакеты, к приему которых операционная система ни морально, ни физически не готова. Хакер может намертво повесить целевой компьютер, забросить зловредный shell-код, обойти брандмауэр, незаметно просканировать порты, отправить пакет от чужого имени и много чего еще!

Во времена рассвета Винды 9x, поддерживающей сырые сокеты лишь на уровне ICMP, хакеры вовсю ставили Linux/BSD только для того, чтобы получить полноценный доступ к сырым сокетам. Эти системы превращали хакеров в богов, контролирующих обширные сетевые территории и скрывающихся за поддельными IP-адресами. И хотя основные ошибки в TCP/IP-стеке за последнее десятилетие были исправлены, внедрение новомодного (а значит, ни фига не протестированного) IPv6 вкупе с полностью переписанным сетевым стеком в Висте спровоцировало всплеск интереса к атакам старого типа.

Полноценная поддержка сырых сокетов в W2K вызвала настоящий фурор! Программисты перенесли многие хакерские программы (типа nmap) в Windows, и необходимость ставить никсы просто отпала. По Сети прокатилась волна атак. Сырые сокеты использовали не только хакеры, но и черви (например, червь Stumbler), в результате чего в XP функциональность сырых сокетов была существенно урезана. В XP SP2 наступил сплошной ахтунг, а XP SP2 с заплаткой MS05-019 — это уже не ахтунг, а просто мерзость какая-то с кучей блокировок на уровне ядра, которые с прикладного уровня просто так не обойдешь.

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

Отсутствие поддержки сырых сокетов никак не увеличивает защищенность Windows, хотя и не позволяет использовать ее в качестве плацдарма для атак на другие системы (точнее, затрудняет атаку в несколько раз). Но ведь на дворе не 1995 год! Воздвигнуть Linux/BSD на виртуальной машине сегодня может даже начинающий хакер, да и способы обхода ограничений сырых сокетов тоже имеются. В ассортименте.

Настоящая статья главным образом ориентирована на пользователей, работающих с чужими программами и не имеющих возможности (времени, желания) дорабатывать их исходный код. Как заставить старые программы работать на новых системах? Вот в чем вопрос! Мы рассмотрим все имеющиеся на данный момент оси (вплоть до Висты и Server 2008 включительно), демонстрируя различные пути обхода наложенных ограничений.

В хлюпающей грязи зловонных болот M$

Сырые сокеты делятся на две категории: первые знают номер протокола, с которым они работают (например, ICMP); вторые же принимают пакеты всех протоколов независимо от номера, прописанного в их заголовке. Достаточно часто встречается утверждение, что при попытке открыть сырой сокет вызовом API-функций socket/WSAsocket со вторым параметром SOCK_RAW (type) и с нулевым третьим параметром (protocol) такой сокет тебе откроется - не вопрос. Однако при попытке сделать sendto или recvfrom ядро скажет тебе, что ты болван. Ну конечно же оно сделает это не так прямолинейно: мол, твой системный вызов прерван, а правильный вариант выглядит так: socket(AF_INET, SOCK_RAW, IPPROTO_IP).

Базару нет, вариант действительно правильный, однако, поскольку макрос IPPROTO_IP равен нулю, socket(AF_INET, SOCK_RAW, 0) будет работать ничуть не хуже. Кстати, AF_INET можно смело заменить PF_INET — суть дела от этого не изменится. А вот с остальными типами протоколов надо разобраться. Параметр IPPROTO_IP тождественен IPPROTO_RAW — в обоих случаях мы принимаем все IP-пакеты целиком вместе с IP-заголовками независимо от того, была ли установлена опция/IP_HDRINCL или нет.

Параметр IPPROTO_ICMP распространяется только на ICMP-сообщения, однако, если к сокету была применена операция SIO_RCVALL, протокол нивелируется и ловит все пакеты без разбора, обеспечивая тот же самый эффект, что и IPPROTO_IP/IPPROTO_RAW (по крайней мере, в текущих версиях Windows дело обстоит именно так). Параметр IPPROTO_UDP в этом случае не ловит никаких пакетов вообще, но конкретно срывает крышу персональным брандмауэрам, многие из которых отображают большое количество блокируемого UDP-трафика. Но на самом деле не блокируют его, а спокойно доставляют пакеты до целевого приложения. То есть все работает нормально, только брандмауэр ругается. Неплохая шутка для администраторов :).

Параметр IPPROTO_TCP вызывает ошибку при обращении к функции bind, так что с TCP выходит полный облом. Но если кто здесь и болван, так это ядро, но не никак я.

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

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

Если для сырого сокета задан foreign-адрес (удаленный IP-адрес), он будет ловить только IP-пакеты, приходящие с заданного узла, то есть пакеты, чей source-адрес равен установленному (задать foreign-адрес можно с помощью API-функции connect). Особого смысла в этом нет, ну разве что если мы хотим ограничить сбор трафика каким-то конкретным узлом. Если же foreign-адрес не установлен, в сырой сокет копируются все пакеты независимо от адреса-источника.

Как вариант - грабеж проходящего мимо трафика можно осуществить с помощью установки IOCTL-параметра SIO_RCVALL путем вызова функции WSAIoctl, главными недостатками которой является невозможность работать с протоколами, отличными от IPPROTO_IP, и необходимость привязки сокета на конкретный интерфейс. То есть если у нас обозначена сетевая карта локальной сети, DSL- и GPRS-модем, то API-функцию bind придется вызывать трижды, каждый раз делая это в отдельном потоке (на блокируемых сокетах). Попытка привязки к любому адресу (INADDR_ANY) ведет к провалу. К тому же флаг SIO_RCVALL поддерживается только начиная с W2K и в NT не работает. В общем, решай сам, иметь или не иметь. Между тем, существуют и другие IOCTL-команды, полезные для грабежа: SIO_RCVALL_MCAST получает весь multicast IP-трафик (при этом тип протокола должен быть установлен в IPPROTO_UDP), а SIO_RCVALL_IGMPMCAST, соответственно, грабит весь IGMP multicast IP-трафик (при этом тип протокола должен быть установлен в PPROTO_IGMP).

Простейший IP-снифер я выложил на наш DVD, прилагаемый к журналу.

Но это все, что касается сырых сокетов, принимающих пакеты. В полной мере их функциональность впервые была реализована в W2K и с тех пор не претерпела никаких существенных изменений. Судьба сырых сокетов, передающих пакеты, намного более печальна. NT не позволяет создавать больше 10 TCP-соединений за 10 минут, хотя при желании это значение можно увеличить, покопавшись в реестре.

В W2K сырые сокеты поддерживаются без каких бы то ни было ограничений, однако, отправляя IP-пакет с чужим IP, мы рискуем нарваться на кучу неприятностей. Неправильный пакет может зарезать как наш собственный персональный брандмауэр, так и NAT, встроенный в DSL-модем. Даже если пакет благополучно покинет хакерский компьютер, его наверняка прибьет первый же маршрутизатор провайдера. Так что мало научиться создавать сырые сокеты с поддельными IP-адресами, хакеру еще необходимо найти демократично настроенного провайдера (вот потому у одних поддельные IP работают, а у других нет). В локальной сети (во всяком случае, в пределах одного сегмента) подобных проблем не возникает и все работает на ура. Впрочем, подделка IP не главная функция сырых сокетов, и обычно хакеры используют их для создания битых TCP/IP-пакетов с диким набором флагов, который целевая операционная система не переваривает и передает управление на shell-код.

В XP SP0 функциональность сырых сокетов в плане отправки данных существенно ограничена, и они жестоко фильтруются персональным брандмауэром ака Windows Firewall, который, впрочем, легко остановить командой net stop sharedaccess, после чего все проблемы исчезают. XP SP1 (с установленной заплаткой безопасности MS05-019) блокирует сырые сокеты, если брандмауэр не запущен! Политика запретов продолжила набирать обороты и в XP SP2, из которой исчезли сырые TCP-сокеты, и хакеры оказались вынуждены вручную собирать TCP-пакеты из IP или использовать протоколы ICMP и/или UDP. В Висте от всего этого богатства остался всего лишь один ICMP, что вплотную приблизило ее к 9x (правда, ходят слухи, что поддержку сырых IP и UDP Висте очень скоро вернут).

Короче, в XP SP2 мы имеем следующий перечень ограничений (подробнее смотри тут - http://technet.microsoft.com/en-us/library/bb457156.aspx):

  1. TCP-пакеты не могут быть посланы через сырые сокеты.
  2. UDP-пакеты с левым адресом источника дропаются системой.

Server 2003 и Server 2008 полностью поддерживают сырые сокеты, но только после остановки встроенного брандмауэра, что осуществляется командой net stop alg, причем касательно Server 2008 информация пока неполная, противоречивая и может измениться в любую минуту. В общем, держи лапы на пульсе, в смысле на клавиатуре.

Таким образом, для хакинга идеально подходит W2K или (с некоторой натяжкой) Server 2003/2008. А что делать тем, у кого установлена XP/Виста и кто слезать с нее ни за что не собирается даже ради хакерства и крутизны?

Сырые сокеты на XP SP2/Висте

Используя XP SP2/Висту, будь готов к тому, что многие атакующие программы откажутся работать. Ну с подделкой IP-адреса никаких вопросов не возникает. Достаточно завести себе интерфейс с IP-адресом, который мы хотим подделывать, и система благополучно пропустит его наружу. А вот с остальными ограничениями бороться сложнее. Разработчики коммерческих утилит (сканеров безопасности, например) матерясь опускаются с прикладного уровня на уровень ядра, создавая специальный драйвер-отмычку.

Штатный драйвер TCPIP.SYS создает несколько устройств: TCP, UDP и RAWIP. Причем RAWIP потребовался для обслуживания своего же собственного NAT'а, впервые появившегося в W2K. NAT есть NAT, и ему позарез необходимо слать пакеты от имени внешних узлов, обеспечивая прозрачную трансляцию адресов. Грубо говоря, NAT - это легальный IP-спуфер, встроенный в систему, и грех не упасть ему на хвост.

Хакерский драйвер должен открыть доступ к устрройству DeviceRawIp, назначить ему атрибут IPHDR_INCL, после чего можно слать все что угодно и от кого угодно. А чтобы псевдоустройство было видно с прикладного уровня, достаточно вызывать API-функцию DefineDosDevice, и это будет работать на любой системе, причем поиском правильного интерфейса для отправки пакета займется непосредственно сам драйвер TCPIP.SYS и нам не придется с этим заморачиваться. Способ универсальный, но без драйвера тут не обойтись. Коммерческие программисты даже не крякнут, но вот авторы разных эксплойтов и других бесплатных атакующих утилит просто забили на XP SP2 и перешли на никсы или вернулись обратно в W2K, что вызвало огромное недовольство простых смертных. Им-то сносить свою любимую XP/Висту ох как не хочется! Лучше уж якорь в задницу!

Но что мешает установить VMware и натянуть поверх XP любую другую систему, например W2K, Linux или BSD? Однако без тонкостей и здесь не обходится. Чтобы этот «бутерброд» заработал, необходимо обеспечить физический доступ виртуальной машины к сетевой карте (если используется Ethernet-интернет), USB-порту, в который воткнут DSL-модем, или COM-порту с диалап-модемом. Все это осуществляется легальными средствами самой VMware и не вызывает никаких проблем.

Заходим в свойства виртуальной машины (Edit virtual machine settings), находим там сетевую карту и говорим «Bridget: connect directly to physical network», после чего гостевая операционная система подключается прямиком к виртуальному адаптеру. Чтобы пакеты уходили с базовой машины в сеть, еще надо настроить маршрутизацию пакетов штатной командой route. Это может отпугнуть начинающих, и на первых порах лучше использовать DSL-модемы на USB.

По умолчанию VMware видит все USB-устройства, так что никаких проблем тут не возникает, а вот COM-модемы уже требуется сконфигурировать вручную. Возвращаемся к Edit virtual machine settings, жмем Add, находим в списке устройств последовательный порт (serial port) и говорим «Use physical serial port on the host», после чего модем увидится гостевой осью как родной, и нам останется только войти в интернет. Аналогичным образом обстоят дела и с сотовыми телефонами: подключаем их либо через COM/USB-шнурок, либо через ИК/Bluetooth-порт с адаптером, воткнутым в COM/USB. Тут, правда, необходимо отметить, что мне неизвестны сотовые операторы, поддерживающие сырые сокеты. В том смысле, что пакеты все равно пересобираются на ближайшем же узле, и все наши хитрые манипуляции с заголовками идут лесом.

Как вариант - можно загрузиться в LiveCD (типа KNOPPIX) и юзать сырые сокеты уже через него. В общем, возможных решений много. И какие бы препятствия нам ни городил MicroSoft, мы — хакеры — все равно их обойдем!

Заключение

Microsoft (и куча сетевых обозревателей, включая вроде бы неглупого мужика Стива Гибсона — www.grc.com/dos/intro.htm) расценивает сырые сокеты исключительно как орудие зла и в стремлении защитить мир от вандалов планомерно щемит функциональность, забывая о том, что сырые сокеты — это еще и превосходное средство обучения. Только конструируя TCP/IP-пакеты своим руками, можно постичь истинное дао, на котором держится весь интернет, и нам остается только радоваться, что сырые сокеты по-прежнему с нами!

Нажми на газ!

Сырые TCP/UDP-сокеты работают намного медленнее обычных (что особенно хорошо заметно при открытии большого количества соединений или интенсивном трафике), а потому применять их следует только тогда, когда стандартными средствами поставленная задача не решается.

Вокруг MS05-019

Заплатка MS05-019 представляет собой обновление безопасности, затыкающее критическую дыру в TCP/IP-стеке путем замещения драйверов afd.sys, tcpip.sys и tdpi.sys, а также некоторых динамических библиотек (подробнее об этом можно прочитать на www.microsoft.com/technet/security/bulletin/ms05-019.mspx).

Отказ от использования заплатки MS05-019 теоретически возможен, но практически крайне нежелателен, поскольку, поймав определенным образом сконструированный IP-пакет, атакованный компьютер начнет исполнять зловредный shell-код на уровне ядра или (что более вероятно) уйдет в голубой экран. Впрочем, существует возможность заблокировать незапрошенный IP-трафик на брандмауэре (Windows Firewall умеет делать это), однако тогда перестанут работать и многие легальные программы. С другой стороны, установка MS05-019 проходит весьма болезненно, порождая огромное количество проблем (неполный список которых лежит на http://support.microsoft.com/kb/897656), и потому хакерам настоятельно рекомендуется снести ее напрочь, а трафиком рулить посредством брандмауэра. Например, Outpost'та, для которого можно написать специальный плагин, распознающий зловредные IP-пакеты и дропающий их. Наградой за это станет «реабилитация» сырых сокетов.

От юзера до админа

По умолчанию сырые сокеты доступны только из-под учетной записи администратора, что не есть хорошо, однако любые ограничения можно обойти. Чтобы сырые сокеты заработали и на пользовательском уровне, достаточно открыть следующую ветвь системного реестра: HKLMSystemCurrentControlSetServicesAfdParameters, найти там параметр DisableRawSecurity типа DWORD (если такого параметра нет, создать его), присвоить ему значение 1, после чего перезагрузиться. Все - теперь сырые сокеты доступны всем!

DVD

На диске ищи полный вариант статьи, а также исходник моего снифера, использующего сырые сокеты.

VIDEO

На нашем DVD тебя ждет увлекательный видеоурок, посвященный этой статье.

Содержание
ttfb: 11.331081390381 ms