Rambler's Top100

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

Fyodor <fyodor@insecure.org>

Алексей Волков <alex@cherepovets-city.ru>

Введение

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

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

Логически верным подходом для поиска телефонных номеров таких абонентов является "атака в лоб" - перебор всех возможных номеров АТС и поиск тона несущей частоты, генерируемого модемом на другом конце линии. Так возникло направление, называемое wardialing. Появилась масса программ типа ToneLoc, предназначенных для исследования большого объема телефонных номеров на наличие абонентов, к телефонам которых подключен модем..

Основная идея проста. Если, набрав номер, модем установил соединение (т.е. на другом конце линии также находится модем), набранный номер запоминается. В противном случае модем "вешает трубку", набирает следующий номер и вновь пробует установить соединение.

Wardialing является весьма эффективным методом для поиска входов в различные сети по коммутируемой телефонной линии. С другой стороны, огромное число компьютеров объединены в сеть с помощью специального оборудования (сетевых адаптеров, кабельных модемов) и выделенных линий и не используют коммутируемые линии АТС. В этом случае программы типа ToneLoc оказываются бесполезными, поскольку определить нужно не телефонный номер, а номер порта сервера, ожидающего запрос на соединение.

Термин "порт" является абстрактным понятием, используемым для упрощенного описания механизма установления соединения между хостами, и представляет собой потенциальный канал передачи данных. Использование механизма портов существенно облегчает процесс установления соединения и обмена информацией между сервером и хостом. Кроме того, имеется возможность исследования сетевого окружения сервера методом опроса его портов (т.н. "сканирование" портов). На все возможные номера портов (1-65535) сервера посылается "лавина" пакетов, и по тому, от каких портов будут (или не будут) получены ответы, определяются открытые порты и службы, работающие на исследуемом сервере.

Техника сканирования портов

Было разработано огромное количество различных методов для поиска протоколов и портов, которые "прослушивает" удаленная машина. Все методы имеют определенные преимущества и недостатки. Ниже рассмотрены наиболее часто используемые из них.

Сканирование сервера с использованием ICMP-эха

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

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

Сканирование TCP-портов функцией connect()

Данный метод является основным для сканирования портов по протоколу TCP. Функция connect() позволяет хосту соединиться с любым портом сервера. Если порт, указанный в качестве параметра функции, прослушивается сервером (т.е. порт открыт для соединения), то результатом выполнения функции будет установление соединения с сервером по указанному порту. В противном случае, если соединение не установлено, то порт с указанным номером является закрытым.

Этот метод обладает одним серьезным преимуществом: его может применить любой пользователь, не обладающий никакими привилегиями на хосте. Другое преимущество - скорость исследования. Последовательный перебор портов путем вызова функции connect() для очередного номера порта, определение его состояния и закрытие соединения - достаточно долгий процесс. Однако его можно ускорить, применив метод "параллельного просмотра" с использованием неблокированного соединения (non-blocked socket). Такой метод позволяет определить состояние практически всех портов сервера одновременно.

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

Сканирование TCP-портов флагом SYN

Данный метод известен еще как "сканирование с установлением наполовину открытого соединения" (half-open scanning), поскольку установление полного TCP-соединения не производится. Вместо этого хост отправляет на определенный порт сервера SYN-пакет, как бы намереваясь создать соединение, и ожидает ответ. Наличие в ответе флагов SYN|ACK означает, что порт открыт и прослушивается сервером. Получение в ответ TCP-пакета с флагом RST означает, что порт закрыт и не прослушивается.

В случае приема SYN|ACK-пакета хост немедленно отправляет RST-пакет для сброса устанавливаемого сервером соединения. преимущество данного метода прежде всего заключается в том, что лишь немногие серверы способны зарегистрировать такого рода сканирование. К сожалению, пользователь, должен обладать статусом Root на хосте, с которого производится сканирование. Если статус будет ниже Root, то пользователь попросту не сможет программно сформировать одиночный SYN-пакет.

Сканирование TCP-портов флагом FIN

Как уже говорилось, лишь немногие серверы способны отследить попытку SYN-сканирования их портов. Так, некоторые файрволлы и пакетные фильтры "ожидают" поддельные SYN-пакеты на закрытые порты защищаемого ими сервера, и специальное программное обеспечение типа synlogger или courtney распознает попытку SYN-сканирования. Если сервер "рвет" соединение после опроса нескольких портов, используется FIN-сканирование.

FIN-пакеты способны обойти эти средства защиты. Идея заключается в том, что, согласно RFC 793, на прибывший FIN-пакет на закрытый порт сервер   должен ответить RST-пакетом. FIN-пакеты на открытые порты игнорируются сервером. Однако не все ОС придерживаются этой рекомендации. Так, ОС Windows 95/98/NT, по всей видимости, имеют иммунитет к такому сканированию, однако большинство ОС являются восприимчивыми. Таким образом, совместно используя SYN и FIN-сканирование можно с успехом обойти средства защиты сервера и просканировать его порты.

Сканирование TCP-портов флагами SYN|FIN с использованием IP-фрагментации

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

Фрагментация позволяет уменьшить вероятность обнаружения сканирования фильтрами пакетов и другим подобным оборудованием. Однако при этом следует быть очень осторожным, поскольку некоторые программы имеют обыкновение "зависать" при попытке обработки такого маленького IP-фрагмента.

Сканирование TCP-портов методом reverse-ident (обратной идентификации)

Протокол ident (RFC 1413) позволяет определить имя (username или login, указанное при входе в систему) владельца любого запущенного на сервере процесса, связанного с ним, даже если сам этот процесс не инициализировал TCP-соединение. Так, например, имеется возможность подключиться к http-порту и затем использовать identd чтобы определить, работает ли на сервере пользователь root. Это может быть сделано только при установлении "полного" TCP-соединения к порту исследуемого сервера.

Сканирование TCP-портов с использованием атаки "Прорыв через FTP"

Интересной "возможностью" протокола FTP (RFC 959) является поддержка т.н. "уполномоченных" (proxy) соединений. Другими словами, атакующий, находясь на сервере source.com, может подключиться к интерпретатору (Protocol Interpreter) протокола FTP-сервера taregt.com для установления контроля над сетевым соединением. Затем атакующий дает запрос PI сервера инициализировать активный DTP-сервер (Data Transfer Process) и отправить через него любой файл на любой узел Internet !

Данная особенность (известная, кстати, с 1985 года) может использоваться для похищения почты и новостей, "взлома" серверов, заполнения их дисков, обхода файрволлов, и на практике подобную деятельность очень сложно отследить. В нашем случае можно осуществить сканирование TCP-портов исследуемого сервера с помощью proxy-FTP. Так, пройдя через файрволл, хост соединяется с FTP-сервером, и затем сканируются порты, доступ к которым был заблокирован файрволлом (например, 139-й порт). Кроме того, если FTP-сервер позволяет читать и записывать данные в каталог (например /incoming), имеется возможность отправлять любые данные на обнаруженный открытый порт сервера.

Перед непосредственным сканированием порта необходимо установить соединение с FTP-сервером и использовать команду PORT с указанием номера интересуемого порта. Таким образом серверу будет сообщено, что пассивный User-DTP на стороне хоста ожидает приема через некоторый указанный порт. Затем необходимо дать команду LIST для текущего каталога, и FTP-сервер отправит данные о каталоге по каналу Server-DTP, соединенному с User-DTP по указанному порту.

Если указанный в команде PORT порт сервера открыт, результат выполнения LIST будет успешным (код ответа в этом случае будет 150 и 226). В противном случае будет иметь место подобный ответ:

425 Can't build data connection: Connection Refused

После этого вновь используется команда PORT с указанием другого порта и операция повторяется.

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

Сканирование UDP-портов проверкой ICMP-сообщения "Порт недоступен"

Этот метод также предназначен для определения состояния портов сервера. Основным отличием является использование протокола UDP вместо протокола TCP. Не смотря на то, что организация протокола UDP проще, чем TCP, сканировать UDP-порты гораздо труднее. Это связано прежде всего с концепцией протокола UDP как протокола с негарантированной доставкой данных. Поэтому UDP-порт не посылает подтверждение приема запроса на установление соединения, и нет никакой гарантии, что отправленные UDP-порту данные успешно дойдут до него.

К счастью, большинство серверов в ответ на пакет, прибывший на закрытый UDP-порт, отправляют ICMP-сообщение "Порт недоступен" (Port Unreachable - PU). Таким образом, если в ответ на UDP-пакет пришло ICMP-сообщение PU, то сканируемый порт является закрытым, в противном случае (при отсутствии PU) порт открыт. Поскольку нет гарантии, что запросы от хоста дойдут до сервера, пользователь должен позаботиться о повторной передаче UDP-пакета, который, по всей видимости, оказался потерянным.

Этот метод работает очень медленно из-за использования на некоторых машинах т.н. "компенсации" (RFC 1812 раздел 4.3.2.8), ограничивающей частоту генерирования ICMP-сообщений об ошибке. Например, ядро Linux ограничивает частоту генерирования ICMP-сообщения "адресат недостижим" (Destination Unreachable) до 80 сообщений за 4 секунды, с простоем 0,25 секунды, если это ограничение было превышено. Кроме того, для использования данного метода (а именно - для обнаружения ICMP-сообщений об ошибке) пользователь должен обладать статусом Root на хосте, с которого производится сканирование.

Может показаться, что сканирование UDP-портов не дает той полноты информации, какую можно получить при сканировании TCP-портов. Однако, принимая во внимание существующие (хотя и не многочисленные) "дыры" в службах, использующих протокол UDP (например, "дыру" в rpcbind-демоне ОС Solaris, который может находится на любом UDP-порту с номером выше 32770), сканирование UDP-портов кажется не таким уж бессмысленным.

Сканирование UDP-портов с использованием функций recvfrom() и write()

Этот метод используется в случае, когда пользователь, проводящий сканирование, не обладает статусом Root на хосте. Поскольку не-root пользователь не может "читать" ICMP-сообщение PU, в ОС, поддерживающих механизм сокетов (например в Linux), имеется возможность получения информации о состоянии UDP-порта косвенным способом. Так, например, попытка вызова функции write() на закрытый порт обычно приводит к возникновению ошибки.

Функция recvfrom() в этом плане более информативна. Вызов ее на неблокированный UDP-сокет сервера обычно возвращает ошибку EAGAIN (Try Again - "попытайтесь еще раз", код 13) в случае, когда ICMP-сообщение не было принято, и ECONREFUSED (Connection Refused - "соединение закрыто", код 111), если ICMP-сообщение было принято. Таким образом, по этим признакам также возможно определить состояние портов сканируемого сервера.

Возможности RuNmap

До возникновения идеи о создании программы Nmap были исследованы возможности многих сканеров, таких, как strobe (автор - Julian Assange), netcat (Hobbit), stcp (Uriel Maimon), pscan (Pulvius) ident-scan (Dave Goldsmith) и Satan (Wietse Venema). Все они - превосходные сканеры. Вначале были попытки доработать код одних сканеров для поддержки лучших возможностей других. Затем было решено написать абсолютно новый сканер, который использовал бы лучшие возможности его предшественников, и, конечно, имел новые, такие, как "фрагментированное" сканирование и др. Так получился сетевой сканер Nmap - the Network Mapper. Программа RuNmap представляет собой русифицированную и доработанную версию Nmap. Ниже приведены наиболее отличительные ее возможности.

Динамическое вычисление времени задержки. Некоторым сканерам для работы необходимо указать время задержки между передачей двух пакетов. Как вам узнать его? Естественно, можно использовать данные ping-запроса, но это займет достаточно много времени, и кроме того время задержки постоянно меняется и зависит от "загруженности" хоста, состояния сети и т.д. RuNmap самостоятельно определяет время задержки, и подстраивает его в процессе сканирования. Для root-пользователей используется наилучший способ определения времени задержки - функция ping. Для остальных этот параметр определяется функцией connect () на закрытый порт. Кроме того, у пользователя имеется возможность самостоятельно задать время задержки, но обычно делать это нет необходимости.

Повторная передача пакетов. Некоторые сканеры сразу отправляют все запросы, а затем "собирают" ответы на них. Весьма некорректный подход, поскольку при этом не принимается во внимание тот факт, что иногда пакеты могут просто не дойти до адресата по самым различным причинам. В такой ситуации сканер примет решение об отсутствии ответа и ошибочно укажет, что сканируемый порт закрыт. Больше всего ошибок возникает при использовании "негативного" сканирования типа UDP или FIN, решение в которых принимается на основе отсутствия ответа. RuNmap автоматически выбирает число повторных передач пакетов на порты, от которых не был получен ответ.

Параллельное сканирование портов. Некоторые сканеры последовательно сканируют все 65535 портов за один раз. Этот метод нормально работает лишь при сканировании TCP-портов в высокоскоростных локальных сетях. Глобальные сети типа Internet высокой скоростью не отличаются. RuNmap использует неблокированный ввод/вывод (non-blocked i/o) и параллельное сканирование во всех режимах TCP и UDP. Вы можете задать число параллельных процессов сканирования самостоятельно. На очень быстрых сетях эффективность сканирования уменьшается при указании этого значения больше 18. На медленных сетях - наоборот, чем больше значение, тем выше эффективность.

Гибкое указание сканируемых портов. Часто бывает необходимо отсканировать какие-либо конкретные порты, а не все 65535 портов сразу. Большинство сканеров позволяет задавать диапазон портов типа 1-N, что также не всегда приемлемо. RuNmap позволяет задать любое количество произвольных диапазонов и портов, например '21-25,80,113,6000-'. При использовании "быстрого" режима RuNmap будет сканировать только порты, перечисленные в файле /etc/services.

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

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

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

Более подробную информацию о возможностях RuNmap вы можете получить из "Руководства пользователя". Новые версии RuNmap и подробное его описание находится на сайте

http://www.cherepovets-city.ru/insecure

Заключение

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

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

Системный администратор может воспользоваться RuNmap для сканирования своего сегмента сети с целью выяснения возможности их применения против него самого, после чего модернизировать средства защиты сети.

Следует заметить, что все рассмотренные в данной статье используются в сканерах, разработанных для "продвинутых" сетевых систем типа Linux. Исключением, пожалуй, являются connect(), write() и recvfrom(), которые могут использоваться практически в любых ОС (включая Windows). Так что если хотите опробовать на практике рассмотренные методы, закрывайте ваши "форточки" и надевайте "красную шляпу".

   

© 1997-2000 Fyodor. Insecure Organisation.

http://www.insecure.org

© 1999-2000 Алексей Волков. AVS Hackers Technology, Inc.

http://www.cherepovets-city.ru/insecure