Волков Алексей, Семенов Вячеслав
Подобный диалог можно увидеть на чат-серверах очень часто. Как правило, после появления таких строк в общем «базаре» остальные участники «разговора» сразу обо всем забывают и начинают дружно допытываться: «Вы, ребята, хакеры, наверно?..». А те, в свою очередь, скромно отнекиваются, но продолжают травить байки для публики о том, как «нюкнуть» проштрафившегося «чатланина». И все восхищенно «слушают» и «говорят»: «Вот это да! И вы это делали?!.. Как так? Где найти программу?».
В конце концов, на многочисленные просьбы «слушателей» продемонстрировать что-нибудь эдакое («Взломайте Neo99 – он мне надоел за сегодня!…») новоявленные «хакеры» после двухминутной паузы с сожалением отвечают: «Не получается… Может, у них там фаирволл стоит и ли еще что…». И дружно покидают чат, не вынеся «позора».
«Сканирование», «нюк», «завал»… Многие относятся к этим вещам как к забаве. Ну, не понравился тебе юзер – нюкни его! И дело с концом. На самом деле это весьма серьезные вещи, придуманные не ради забавы, а для осуществления многоэтапной атаки на компьютерные системы с самыми различными целями – от получения несанкционированного доступа до «обвала» сервера или сегмента сети и временного нарушения его работоспособности. Давайте попытаемся разобраться в этих, ставших уже классическими, атаках, и методах противодействия им.
Сканирование как метод вскрытия каналов передачи данных существует уже достаточно долгое время. Идея его заключается в том, чтобы исследовать как можно больше потенциальных каналов связи и выявить те из них, которые находятся в состоянии ожидания соединения.
Сам по себе термин «сканирование» появился в процессе слияния компьютеров с телефонными системами. В результате такой интеграции была сформирована глобальная сеть телефонных коммуникаций, доступ в которую можно получить, всего лишь набрав номер на телефонном аппарате. С одного телефона доступны миллионы абонентов телефонной сети, однако полезными могут оказаться лишь сотни, а то и десятки абонентов, к телефонам которых подключен модем.
Логически верным подходом для поиска телефонных номеров таких абонентов является «атака в лоб» – перебор всех возможных номеров АТС и поиск тона несущей частоты, генерируемого модемом на другом конце линии. Так возникло направление, называемое wardialing. Появилась масса программ типа ToneLoc, предназначенных для исследования большого объема телефонных номеров на наличие абонентов, к телефонам которых подключен модем.
Основная идея проста. Если, набрав номер, модем установил соединение (т.е. на другом конце линии также находится модем), набранный номер запоминается. В противном случае модем “вешает трубку”, набирает следующий номер и вновь пробует установить соединение.
Wardialing является весьма эффективным методом для поиска входов в различные сети по коммутируемой телефонной линии. С другой стороны, огромное число компьютеров объединены в сеть с помощью специального оборудования (сетевых адаптеров, кабельных модемов) и выделенных линий и не используют коммутируемые линии АТС. В этом случае программы типа ToneLoc оказываются бесполезными, поскольку определить нужно не телефонный номер, а номер порта сервера, ожидающего запрос на соединение.
Термин «порт» является абстрактным понятием, используемым для упрощенного описания механизма установления соединения между хостами, и представляет собой потенциальный канал передачи данных. Использование механизма портов существенно облегчает процесс установления соединения и обмена информацией между сервером и хостом. Возникает проблема – как же просканировать порты удаленного компьютера?
Механизм портов универсален. Его универсальность заключается в том, что этот механизм используется на любом хосте сети Интернет независимо от того, какая операционная система на нем установлена. Это дает любому желающему возможность исследования сетевого окружения сервера методом опроса его портов (т.е. «сканирование» портов). На все возможные номера портов (1-65535) сервера посылается «лавина» пакетов, и по тому, от каких портов будут (или не будут) получены ответы, определяются открытые порты и службы, работающие на исследуемом сервере.
Как и в WarDialing’е, сразу же нашлась масса энтузиастов, начавших активно осваивать новое поле деятельности. Эти ребята отлично понимали, что чем качественнее будет решена задача определения открытых портов, тем больше появится возможностей для дальнейшего продвижения по хакерскому пути.
Следует заметить, что большинство из новоявленных «хакеров» пошли по пути «наименьшего сопротивления» и либо использовали стандартный метод Connect(), рассмотренный ниже, либо пользовались разработками тех немногих, которые знали гораздо больше про сетевые операционные системы, а не ограничивались Windows 95/98/NT.
Было разработано огромное количество различных методов для поиска протоколов и портов, которые «прослушивает» удаленная машина. Естесственно, наиболее «продвинутые» методы созданы для «продвинутых» операционных систем типа UNIX. Все методы имеют определенные преимущества и недостатки. Давайте рассмотрим наиболее часто используемые из них.
Любой уважающий себя хакер перед тем, как сканировать хост, задаст себе резонный вопрос: а работает ли этот хост вообще? Поэтому для начала необходимо выяснить, какие хосты в сканируемом сегменте сети являются функционирующими, и определить их адреса.
Самый простой способ получить такую информацию – использовать команду ping с указанием IP-адреса или URL сканируемого хоста (см. рис. 1). В качестве запроса хост отправляет серверу ICMP-сообщение и ожидает получения ответа, также представляющего собой ICMP-сообщение (т.н. ICMP-эхо). Варьируя время ожидания ответа на ping-запрос, можно сканировать большие сети.
Этот метод был первым из всех методов сканирования TCP-портов (портов протокола TCP), использующихся в настоящее время, и поэтому является самым старым. Тем не менее, он и сейчас весьма эффективно справляется со своей задачей. Принцип, положенный в основу данного метода, аналогичен тому, что применялся в wardialinge.
Функция connect() позволяет хосту соединиться с любым портом сервера. Действуя простым перебором, последовательно создается соединение со всеми портами сканируемого хоста. Если порт, указанный в качестве параметра функции, прослушивается сервером (т.е. порт открыт для соединения), то результатом выполнения функции будет установление соединения с сервером по указанному порту. В противном случае, если соединение не установлено, то порт с указанным номером является закрытым.
Помимо TCP-портов есть еще и UDP-порты, точно такие же и ровно столько же. Основным их отличием является использование протокола UDP вместо протокола TCP. Не смотря на то, что организация протокола UDP проще, чем TCP, сканировать UDP-порты гораздо труднее. Это связано прежде всего с концепцией протокола UDP как протокола с негарантированной доставкой данных. Поэтому UDP-порт не посылает подтверждение приема запроса на установление соединения, и нет никакой гарантии, что отправленные UDP-порту данные успешно дойдут до него.
Хакеры решили, что было бы весьма неплохо просканировать и их, и придумали ряд уловок, использующих функции, аналогичные connect(). Так, например, попытка вызова функции write() (запись в порт) на закрытый UDP-порт обычно приводит к возникновению ошибки.
Функция recvfrom() (принять данные через порт) в этом плане более информативна. Вызов ее на открытый UDP-порт сервера обычно возвращает ошибку EAGAIN (Try Again – «попытайтесь еще раз», код 13), и ECONREFUSED (Connection Refused – «соединение закрыто», код 111), если порт закрыт. Таким образом, по этим признакам также возможно определить состояние портов сканируемого сервера.
Основным недостатком методов connect(), recvfrom() и write() является возможность обнаружения и фильтрации такого рода сканирования, причем сделать это достаточно легко. Log-файл сканируемого сервера укажет службам, отвечающим за внешние подключения, на наличие многочисленных попыток подключения с одного адреса и ошибок установления соединения (поскольку хост исследующего после соединения с сервером сразу обрывает его), а те, в свою очередь, немедленно заблокируют доступ к серверу для хоста с данным адресом.
Поэтому умные люди, работающие к тому же на UNIX, не стали останавливаться на достигнутом, а двигали идею дальше. Для операционных систем, позволяющих управлять сетевыми протоколами на низком уровне (к сожалению, операционные системы фирмы Microsoft к таковым не относятся), было разработано огромное количество методов, порой настолько изощренных, что диву даешься, насколько сильна человеческая мысль.
Одним из них является метод, известный еще как «сканирование с установлением наполовину открытого соединения» (half-open scanning), поскольку установление полного TCP-соединения, как при connect(), не производится. Вместо этого хост отправляет на определенный порт сервера SYN-пакет (синхрониация), как бы намереваясь создать соединение, и ожидает ответ. Наличие в ответе флагов SYN|ACK (синхронизация с подтверждением) означает, что порт открыт и прослушивается сервером. Получение в ответ TCP-пакета с флагом RST (сброс) означает, что порт закрыт и не прослушивается. В случае приема SYN|ACK-пакета хост немедленно отправляет RST-пакет для сброса устанавливаемого сервером соединения.
Не многие серверы способны отследить попытку SYN-сканирования их портов. Так, ОС Windows 95/98/NT, по всей видимости, имеют иммунитет к такому сканированию, однако большинство ОС являются восприимчивыми. Кроме того, некоторые файрволлы и пакетные фильтры «ожидают» поддельные SYN-пакеты на закрытые порты защищаемого ими сервера, и специальное программное обеспечение типа synlogger или courtney распознает попытку SYN-сканирования. Если сервер «рвет» соединение после опроса нескольких портов, используется FIN-сканирование.
FIN-пакеты (пакет с установленным флагом «конец сеанса») способны обойти эти средства защиты. Идея заключается в том, что большинство серверов имеют обыкновение отвечать на прибывший FIN-пакет на закрытый порт RST-пакетом. FIN-пакеты на открытые порты игнорируются сервером. Таким образом, совместно используя SYN и FIN-сканирование можно с успехом обойти средства защиты сервера и просканировать его порты.
Данный метод представляет собой комбинацию SYN и FIN-сканирования с небольшим усовершенствованием. TCP-пакет (SYN или FIN-пакет, имеющий небольшой размер) разбивается на стороне хоста на пару IP-фрагментов меньшего размера, и эта пара IP-фрагментов отправляется серверу. На стороне сервера IP-фрагменты «собираются» в один TCP-пакет и производится его обработка (те же действия, как и при SYN или FIN-сканировании).
Фрагментация позволяет уменьшить вероятность обнаружения сканирования фильтрами пакетов и другим подобным оборудованием. Однако при этом следует быть очень осторожным, поскольку некоторые программы имеют обыкновение «зависать» при попытке обработки такого маленького IP-фрагмента.
Протокол ident (RFC 1413) позволяет определить имя (username или login, указанное при входе в систему) владельца любого запущенного на сервере процесса, связанного с ним, даже если сам этот процесс не инициализировал TCP-соединение. Так, например, имеется возможность подключиться к http-порту и затем использовать identd чтобы определить, работает ли на сервере пользователь root (главный администратор). Это может быть сделано только при установлении «полного» TCP-соединения к порту исследуемого сервера.
Интересной «возможностью» протокола FTP (RFC 959) является поддержка т.н. «уполномоченных» (proxy) соединений. Другими словами, атакующий, находясь на сервере source.com, может подключиться к интерпретатору (Protocol Interpreter) протокола FTP-сервера target.com для установления контроля над сетевым соединением. Затем атакующий дает запрос PI сервера инициализировать активный DTP-сервер (Data Transfer Process) и отправить через него любой файл на любой узел Internet !
Данная особенность (известная, кстати, с 1985 года) может использоваться для похищения почты и новостей, «взлома» серверов, заполнения их дисков, обхода файрволлов, и на практике подобную деятельность очень сложно отследить. В нашем случае можно осуществить сканирование TCP-портов исследуемого сервера с помощью proxy-FTP. Так, пройдя через файрволл, хост соединяется с FTP-сервером, и затем сканируются порты, доступ к которым был заблокирован файрволлом (например, 139-й порт – для чего, читайте дальше). Кроме того, если FTP-сервер позволяет читать и записывать данные в каталог (например /incoming), имеется возможность отправлять любые данные на обнаруженный открытый порт сервера.
Как уже говорилось ранее, скнировать UDP-порты гораздо труднее, чем TCP-порты прежде всего потому, что протоколом UDP не предусматривается явное подтверждение приема данных. К счастью, большинство серверов в ответ на пакет, прибывший на закрытый UDP-порт, отправляют ICMP-сообщение «Порт недоступен» (Port Unreachable - PU). Таким образом, если в ответ на UDP-пакет пришло ICMP-сообщение PU, то сканируемый порт является закрытым, в противном случае (при отсутствии PU) порт открыт. Поскольку нет гарантии, что запросы от хоста дойдут до сервера, пользователь должен позаботиться о повторной передаче UDP-пакета, который, по всей видимости, оказался потерянным.
В теории все получается очень гладко. Как же обстоят дела на практике и зачем вообще все это надо? Вот зачем. В руках хакера программные средства сканирования сети являются едва ли не основным инструментом для осуществления взлома (наподобие отладчика машинных кодов HIEW). Данные средства позволяют взломщику до тонкостей разобраться в структуре сети, собрать информацию о пользователях и о сетевом трафике исследуемого сегмента.
Системный администратор может воспользоваться последними разработками подобных программ для сканирования своего сегмента сети с целью выяснения возможности их применения против него самого, после чего модернизировать средства защиты сети.
Приведем тривиальный пример использования сканера портов. Допустим, вы, работая в ОС Windows, решили позабавиться на досуге и отомстить своему соседу за вчерашнюю шутку в чате. Что ж, давайте попробуем. Сразу оговоримся, что мы приводим этот пример лишь в качестве иллюстрации, а не как руководство к действию. В качестве средства мести вы решили использовать уже небезызвестный «нюк».
Итак, найдя на каком-нибудь хакерском сайте программы-сканеры портов и выбрав «самый лучший с огромными возможностями» (как указано в описании) вы, сгорая от нетерпения, распаковали архив и установили наконец долгожданную игрушку (см. рис. 1).
Рисунок 1: сканер портов 7th Sphere. Простой и надежный. Для Windows.Сканируем сами себя – адрес 127.0.0.1
Зная IP-адрес обидчика, вы, потирая руки, сканируете его компьютер, и получаете список всех открытых портов.
Теперь настало время разобраться с термином «нюк». Под «нюком» понимается определенный пакет, отправленный на 139-й порт любой Windows-машины, работающей в сети. Всвязи с ошибкой в реализации стека протоколов TCP/IP в ОС Windows, пришедший на 139-й порт пакет вызывает очень любопытные эффекты в работе Windows, часто приводящие к внутренней ошибке и закрытию соединения (говорят «выкинуло»).
Поскольку у вашего соседа «форточки» раскрыты настежь, то нас интересует состояние того самого 139-го порта. Со счастливым выражением лица вы смотрите в список и обнаруживаете, что 139-й порт открыт. Порыскав по тому же хакерскому сайту, вы без труда отыщете кучу программ-«нюков» (рис. 2). Скачиваем, устанавливаем, пишем IP-адрес соседа, нажимаем кнопку NUKE EM и… снова сканируем его. Как вы думаете, почему вдруг ни один порт компьютера вашего соседа не отвечает?.. Потому что его «выкинуло» (вот при встрече разоряться будет!).
Рисунок 2: вот такой примитивный, но "смертоносный" интерфейс у "нюка"!
Возможно ли защититься от такого рода атак? Конечно же да. И незаменимым средством защиты являются различные программные средства, устанавливаемые на компьютере клиента. Глупо надеяться на интернет-провайдера, проповедующего в большинстве случаев принцип «помоги себе сам». Одна из таких программ (кстати, абсолютно бесплатная) называется NukeNaber (рис. 3). Программа представляет собой простой фильтр-монитор «опасных» портов, список которых пользователь может настроить по своему вкусу.
Рисунок 3: NukeNaber успешно справился со своей задачей - отследил сканирование и отфильтровал "нюк"
К сожалению, программы типа NukeNaber не являются панацеей, поскольку в настоящее время разработаны и другие атаки на Windows-машины (типа Teardrop или Land). Однако мы все же советуем установить подобную программу, хотя бы для того, чтобы завтра ваш сосед не «нюкнул» вас.
Мы рассмотрели лишь основные методы, применяемые для сканирования портов сервера, определения их состояния и работающих на сервере служб. Комплексное использование рассмотренных методов позволяет не только получить достоверную информацию об открытых портах, но и обойти возможные средства защиты исследуемого сегмента сети.
Следует заметить, что все рассмотренные в данной статье используются в сканерах, разработанных для «продвинутых» сетевых систем типа Linux. Исключением, пожалуй, являются connect(), write() и recvfrom(), которые могут использоваться практически в любых ОС (включая Windows).
Одним из таких программ-сканеров для Linux является сетевой сканер NMAP - The Network Mapper (рис. 5).
Рисунок 4: Графический интерфейс NMAP. Мощь и сила Linux.
Эта программа использует все рассмотренные нами методы и поэтому является самым мощным средством сканирования сети. Помимо гарантированного получения результата сканирования и абсолютной «невидимости» самого процесса на стороне сканируемого хоста, NMAP обладает еще одним, не менее важным и нужным свойством . Он позволяет точно определить операционную систему удаленного хоста.
Как именно это делается, мы рассмотрим в нашей следующей статье. Ну а пока - если хотите опробовать на практике рассмотренные методы, закрывайте ваши «форточки» и надевайте «красную шляпу» Linux.