
Первый бокс на HackTheBox, терминал открыт, IP цели — 10.10.10.40. Запускаешь nmap 10.10.10.40, ждёшь минуту и получаешь пять строк: 22/tcp open ssh, 80/tcp open http, 445/tcp filtered microsoft-ds. Три порта, три разных статуса, три вопроса без ответа. Почему 445 filtered, а не closed — и что за этим стоит? Какой сервис крутится на 80-м — Apache, nginx, что-то самописное? Если хотя бы один из этих вопросов вызывает замешательство — читай дальше. Разберём стек TCP/IP на том уровне, который реально нужен для CTF, объясним каждый тип сканирования nmap и научимся читать вывод без гадания.
Модель OSI с семью уровнями — классика учебников, но для работы с nmap хватает четырёхуровневой модели TCP/IP на практике. Разберём ровно то, что понадобится при сканировании.
Канальный уровень (Link Layer) — физическое соединение: Ethernet, Wi-Fi, MAC-адреса. Для CTF-задач почти не критичен, за одним исключением: ARP-сканирование в локальном сегменте через nmap -PR работает именно тут. Если атакующая машина и цель в одной подсети — ARP-запросы дадут самый быстрый и надёжный результат обнаружения хостов.
Сетевой уровень (Internet Layer) — маршрутизация пакетов. Здесь живёт протокол IP. Когда nmap отправляет пакет на 10.10.10.40, именно IP-уровень тащит его через цепочку маршрутизаторов до нужного хоста. Сюда же относятся ICMP-сообщения — те самые «ошибки недостижимости», которые nmap интерпретирует при определении состояния порта.
Транспортный уровень (Transport Layer) — ключевой для понимания сканирования портов. Тут работают два протокола: TCP и UDP. TCP гарантирует доставку — подтверждение получения, повторная отправка потерянных пакетов, сохранение порядка. UDP работает по принципу «отправил и забыл»: никаких гарантий, зато минимум накладных расходов. Для CTF разница критична. Большинство сервисов работают по TCP — HTTP, SSH, SMB, FTP, MySQL. Но DNS (порт 53), SNMP (порт 161), DHCP (порты 67/68) и TFTP (порт 69) используют UDP. Пропустить UDP-сканирование — значит потерять вектор атаки, который автор задания заложил намеренно.
Прикладной уровень (Application Layer) — протоколы конкретных сервисов. Когда nmap показывает 80/tcp open http, расшифровка такая: на транспортном уровне TCP, порт 80 открыт, а на прикладном — HTTP-сервер. Именно с этим уровнем ты работаешь, когда открываешь сайт в браузере или подключаешься по SSH.
Представь IP-адрес как адрес здания, а порты — как пронумерованные двери. Всего дверей 65535 для TCP и отдельно 65535 для UDP — итого 131070 потенциальных точек входа на одном хосте. За дверью 22 обычно стоит SSH, за 80 — HTTP, за 443 — HTTPS. Но это конвенция: администратор может повесить SSH на порт 2222, а веб-сервер запустить на 8080 или 31337. Задача nmap — выяснить, какие двери открыты и что за ними стоит.
Порты 0–1023 — «well-known», за ними закреплены стандартные сервисы. 1024–49151 — зарегистрированные (сторонние приложения). 49152–65535 — динамические, обычно используются клиентскими приложениями для исходящих соединений. В CTF флаги регулярно прячут на нестандартных портах выше 10000, так что сканирование только дефолтной тысячи — типичная ошибка новичков.
В классификации MITRE ATT&CK сканирование портов — техника Network Service Discovery (T1046, тактика Discovery): атакующий определяет доступные сервисы на целевых хостах. На этапе разведки перед атакой — Active Scanning (T1595, тактика Reconnaissance) с подтехниками Scanning IP Blocks (T1595.001) и Vulnerability Scanning (T1595.002). Понимание этой классификации помогает не только в атаке, но и в защите: зная, как выглядит сканирование с точки зрения MITRE, проще писать правила детектирования.
Чтобы понять, чем SYN-скан отличается от connect-скана и почему FIN-скан может проскочить мимо фаервола, нужно разобраться с TCP-рукопожатием — three-way handshake. Три шага, которые устанавливают TCP-соединение, и каждый тип скана в nmap эксплуатирует их по-своему.
Шаг 1 — SYN. Клиент шлёт пакет с флагом SYN: «хочу подключиться к твоему порту». Стук в дверь.
Шаг 2 — SYN-ACK. Если порт открыт и сервис слушает, сервер отвечает пакетом с двумя флагами — SYN и ACK: «слышу тебя, готов к разговору». Дверь приоткрылась.
Шаг 3 — ACK. Клиент подтверждает: «отлично, начинаем». Соединение установлено, можно гонять данные.
Что происходит, если порт закрыт? Сервер вместо SYN-ACK шлёт пакет с флагом RST (reset) — принудительный сброс. «Тут никого нет, проходи мимо.» А если порт фильтруется фаерволом? Пакет просто исчезает — дверь замурована, стук не слышен ни с одной стороны.
Теперь ключевой момент. SYN-скан в nmap выполняет только шаги 1 и 2: отправляет SYN, получает SYN-ACK (порт открыт) или RST (закрыт) — и сразу обрывает, отправляя свой RST. Полное соединение не устанавливается, поэтому многие логи его не фиксируют. Connect-скан проходит все три шага, завершая handshake — и именно поэтому оставляет следы. FIN/NULL/Xmas-сканы действуют ещё хитрее: отправляют пакеты с нестандартными комбинациями флагов, рассчитывая на то, что TCP-стек цели ответит по-разному в зависимости от состояния порта.
Для справки — TCP-флаги, которые встретятся при сканировании:
| Флаг | Что делает | Где встретите в контексте nmap |
|---|---|---|
| SYN | Инициирует соединение | SYN-скан, connect-скан |
| ACK | Подтверждает приём данных | ACK-скан, третий шаг handshake |
| RST | Принудительно сбрасывает соединение | Ответ закрытого порта |
| FIN | Сигнализирует завершение передачи | FIN-скан |
| PSH | Требует немедленной передачи данных | Xmas-скан (в комбинации) |
| URG | Помечает данные как срочные | Xmas-скан (в комбинации) |
Если открыть Wireshark параллельно со сканированием, можно увидеть эти флаги в каждом пакете — крайне полезное упражнение для закрепления. Рекомендую попробовать хотя бы раз.
Nmap распознаёт шесть состояний портов. Четыре встречаются регулярно, два — в специфичных сценариях. Понимание каждого состояния напрямую влияет на то, куда ты направишь усилия при решении CTF-задания.
open — сервис активно слушает и принимает подключения. Цель номер один. Открытый порт — точка входа: можно подключиться, определить версию сервиса и искать уязвимости.
closed — порт доступен (хост отвечает RST), но работающего сервиса за ним нет. В CTF обычно не интересен напрямую, но подтверждает: хост живой, фаервола между вами нет. Если все порты closed — хост работает, просто на нём ничего не запущено (или запущено на портах, которые ты не просканировал).
filtered — nmap не может определить состояние порта. Пакеты блокируются фаерволом, маршрутизатором или другим сетевым фильтром. Ответа нет, или приходит ICMP-ошибка недостижимости (тип 3, коды 1, 2, 3, 9, 10 или 13). И вот тут внимание: filtered не означает «тут пусто». За фильтром может прятаться рабочий сервис, и в CTF это прямой сигнал — попробуй другой тип сканирования или иной подход.
unfiltered — порт доступен и отвечает, но определить — открыт он или закрыт — не удаётся. Встречается при ACK-сканировании (-sA). Для CTF-новичков практически не актуален.
open|filtered — nmap не получил ответа и не может решить: порт открыт или фильтруется? Типичная ситуация при UDP-сканировании и сканах FIN/NULL/Xmas. Видишь этот статус — запускай определение версий (-sV), оно поможет уточнить.
closed|filtered — встречается только при idle-сканировании (-sI). В повседневной CTF-практике не попадается.
Пример вывода с разными состояниями:
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
139/tcp filtered netbios-ssn
445/tcp filtered microsoft-ds
3306/tcp closed mysql
8080/tcp open http-proxy
Три открытых порта (22, 80, 8080) — к ним можно подключаться и копать сервисы. Два фильтруемых (139, 445) — фаервол блокирует SMB-трафик извне, но сам факт фильтрации говорит: сервис, скорее всего, работает за фильтром. Один закрытый (3306) — MySQL не запущен, фаервола перед портом нет. Такой анализ результатов сканирования сети должен стать автоматическим навыком.
Документация nmap описывает более десяти типов сканирования. Для CTF в абсолютном большинстве случаев хватает трёх: SYN, connect и UDP. Остальные — для обхода фаерволов и нестандартных ситуаций.
Дефолтный тип при запуске nmap с правами root (или sudo). Шлёт SYN-пакет, получает SYN-ACK от открытого порта — и тут же обрывает RST-ом, не завершая рукопожатие. Отсюда название «полуоткрытое» сканирование.
Почему он хорош: высокая скорость (тысячи портов в секунду на быстрой сети), относительная скрытность — полное TCP-соединение не устанавливается, многие системы логирования такие попытки пропускают. Согласно документации nmap, SYN-скан «работает с любым совместимым TCP-стеком и не зависит от особенностей конкретной платформы», в отличие от FIN/NULL/Xmas-сканов. Ограничение одно: нужны root-привилегии для отправки сырых пакетов.
Использует стандартный системный вызов connect() — тот же механизм, через который браузер открывает сайт. Полностью устанавливает TCP-соединение (все три шага handshake). Включается автоматически, когда нет прав root.
Минусы: медленнее SYN-скана, оставляет записи в логах целевой системы, требует больше пакетов для получения той же информации. Документация прямо говорит: «Администратор, увидевший группу записей о попытках установки соединения от одной системы, должен понять, что его машина подверглась connect-сканированию». В CTF-лабораториях (HackTheBox, TryHackMe) обычно доступен root на атакующей машине, так что connect-скан используется нечасто.
Многие новички в ИБ полностью игнорируют UDP — и это систематическая ошибка. DNS (порт 53), SNMP (порт 161), DHCP (порты 67/68), TFTP (порт 69) — все они работают по UDP. В CTF-заданиях бывает, что единственный путь к флагу лежит через UDP-сервис. Без его обнаружения задание нерешаемо. Точка.
Механика: nmap отправляет пустой UDP-пакет или пакет с protocol-specific payload для известных сервисов. Если приходит ICMP-ошибка «port unreachable» (тип 3, код 3) — порт закрыт. UDP-ответ — порт открыт. Тишина — open|filtered, неопределённость. Документация подсказывает: «определение версий (-sV) может помочь отличить реально открытые порты от фильтруемых».
Главная боль UDP-сканирования — скорость. Многие ОС ограничивают частоту ICMP-ответов (Linux и Solaris тут особенно строги). Полный UDP-скан всех 65535 портов может занять часы. Для CTF разумный компромисс: --top-ports 100 или --top-ports 1000. Можно и комбинировать UDP с TCP-сканом за один проход: nmap -sS -sU <target>.
Три типа, которые эксплуатируют особенность спецификации TCP (RFC 793): на пакет без SYN/RST/ACK закрытый порт должен ответить RST, а открытый — проигнорировать.
NULL-скан (-sN) отправляет пакет без единого установленного флага — голый, в чём мать родила. FIN-скан (-sF) — пакет только с FIN. Xmas-скан (-sX) — пакет с FIN, PSH и URG одновременно (три флага «горят», как гирлянда — отсюда название Christmas).
Проблема: не все системы следуют RFC. Windows, многие маршрутизаторы и сетевые устройства шлют RST на любой нестандартный пакет вне зависимости от состояния порта. Результат: ложные «closed» для реально открытых портов. На Windows-хосте NULL-скан даёт мусорные результаты — это нужно просто запомнить.
В CTF эти сканы полезны, когда SYN-скан показывает все порты как filtered: FIN/NULL/Xmas могут проскочить через простой пакетный фильтр, который проверяет только наличие SYN-флага.
| Тип скана | Флаг | Root | Скорость | Когда использовать в CTF |
|---|---|---|---|---|
| SYN | -sS | Да | Высокая | Первый выбор, всегда |
| Connect | -sT | Нет | Средняя | Нет root-доступа |
| UDP | -sU | Да | Низкая | DNS, SNMP, TFTP |
| FIN | -sF | Да | Средняя | SYN-скан выдаёт filtered |
| NULL | -sN | Да | Средняя | SYN-скан выдаёт filtered |
| Xmas | -sX | Да | Средняя | SYN-скан выдаёт filtered |
Запустим версионное сканирование и разберём каждую строку. Вот типичная картина при работе с CTF-боксом:
Nmap scan report for 10.10.10.40
Host is up (0.052s latency).
Not shown: 991 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3
80/tcp open http Apache httpd 2.4.41
445/tcp open microsoft-ds Windows Server 2019 Std
8080/tcp open http-proxy Squid http proxy 4.10
9090/tcp open zeus-admin?
Service Info: OSs: Linux, Windows
Host is up (0.052s latency) — хост ответил, задержка 52 миллисекунды. Нормально для VPN-подключения к лаборатории. Если latency больше 300 мс — стоит увеличить таймауты через --host-timeout или --max-retries.
Not shown: 991 closed tcp ports (reset) — из 1000 просканированных портов (дефолт nmap) 991 закрыт. Слово «reset» — сервер ответил RST на каждый SYN. Фаервола перед этими портами нет. Было бы «no-response» — значит, пакеты ушли в пустоту и между вами фильтр.
22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3 — порт 22, протокол TCP, статус open. Сервис — SSH, конкретно OpenSSH версии 8.9p1 на Ubuntu. Версия критична: по ней проверяются публичные уязвимости через searchsploit OpenSSH 8.9 или поиск по CVE-базам.
9090/tcp open zeus-admin? — знак вопроса после имени сервиса. Nmap не уверен в идентификации: служба ответила, но баннер не совпал ни с одной сигнатурой из базы. Подключись вручную: nc 10.10.10.40 9090 покажет баннер, а браузер — возможную веб-панель. В CTF именно на таких «неопознанных» портах часто прячется нестандартный сервис, который и является точкой входа.
Service Info: OSs: Linux, Windows — nmap видит признаки обеих ОС в баннерах. Может быть контейнерная среда (Linux-хост с Windows-сервисами через Wine или docker) или просто неточность в fingerprinting. Не стоит принимать эту строку как истину — для точного определения ОС используй nmap -O.
На что обращать внимание при чтении результатов:
Рабочая последовательность, обкатанная на практике. Не единственно правильная, но надёжная для большинства CTF-платформ.
nmap -sC -sV <target> — дефолтные NSE-скрипты плюс определение версий по топ-1000 портов. Занимает 30–90 секунд. Даёт первую картину: какие сервисы доступны и на каких версиях работают. Флаг -sC (эквивалент --script=default) запускает безопасные скрипты: проверку баннеров, методов аутентификации SSH, HTTP-заголовков и базовой информации о сервисах. Результат сразу сохраняй — добавь -oA initial_scan к команде.
Параллельно в отдельном терминале: nmap -p- -sS --min-rate 1000 <target>. Флаг -p- покрывает все 65535 портов. --min-rate 1000 ускоряет процесс, гарантируя минимум 1000 пакетов в секунду. Занимает 3–10 минут. Боксы регулярно прячут сервисы на портах вроде 31337, 50000 или 65000. Без полного скана ты их не найдёшь.
sudo nmap -sU --top-ports 50 <target>. UDP-скан медленный, поэтому начинаем с 50 самых распространённых портов. Если TCP-вектор привёл в тупик — расширяй до 200 или 1000. SNMP с community string «public» или TFTP с доступной конфигурацией роутера бывают единственным путём к решению.
Когда полный скан обнаружил порт, которого не было в первом проходе (допустим, 31337): nmap -sC -sV -p 31337 <target>. Версии, скрипты, баннеры — всё сфокусировано на одном порте. Быстро и максимум деталей.
HTTP-сервер → --script http-enum для обнаружения скрытых директорий и файлов. SMB → --script smb-enum-shares,smb-enum-users для перечисления шар и учёток. MySQL → --script mysql-info. Правильно подобранный набор скриптов экономит время перед переходом к ручным инструментам: gobuster для веб-директорий, enum4linux для SMB.
Формула всего процесса: широко → глубоко → точечно. Обзорный скан для первой картины, полный охват для скрытых портов, прицельный удар по найденным целям.
Четыре паттерна, которые стабильно всплывают у новичков на CTF-площадках. Я видел каждый из них десятки раз.
По умолчанию nmap проверяет около 1000 портов из 65535 — менее 2% от общего количества. Если задание устроено так, что сервис висит на порту 49999, дефолтный скан его не покажет. Решение: всегда параллельно запускать nmap -p- для полного покрытия.
«TCP показал три открытых порта — иду ломать.» И пропускается SNMP на UDP/161, через который можно вытащить системную информацию, или TFTP на UDP/69 с файлами конфигурации. UDP-скан медленный и неприятный, но без него картина заведомо неполная.
Filtered означает блокировку пакетов фаерволом, а не отсутствие сервиса. За фильтром часто работает целевой сервис. Попробуй альтернативный тип скана (FIN, NULL, Xmas), смени source-порт через --source-port 53 (некоторые фаерволы пропускают трафик, идущий «с DNS-порта») или задействуй --script firewall-bypass. В CTF filtered-порт — это подсказка от автора задания, а не тупик.
Запустил скан, прочитал вывод, закрыл терминал. Через полчаса нужна версия сервиса — приходится сканировать заново. Привыкай к nmap -oA scan_results <target>: создаются три файла — текстовый (.nmap) для чтения, XML (.xml) для импорта в Metasploit или другие инструменты, grepable (.gnmap) для обработки через grep и скрипты. Потраченные 5 секунд на -oA экономят 5 минут потом.
Активное сканирование портов фиксируется системами обнаружения вторжений. Сервисы вроде AbuseIPDB классифицируют такую активность как категорию #14 — Port Scan, и IP сканера может попасть в блоклист с высоким confidence score. В CTF-лабораториях это не проблема: инфраструктура изолирована. Но при работе с реальными системами — письменное разрешение на тестирование обязательно.
Полгода назад разбирал с CTF-командой очередной бокс и снова увидел тот же паттерн: ребята запускают nmap <ip> без единого флага, видят порты 22 и 80, полчаса безуспешно пытаются пробить SSH и веб-сервер. Потом выясняется: кастомный сервис на порту 50000 отдаёт флаг по обычному GET-запросу. Проблема не в знании эксплоитов и не в навыках реверса — проблема в качестве разведки. Сканирование портов nmap для CTF это не про нажатие Enter и беглый просмотр списка. Это про понимание: что означает каждая строка вывода, почему SYN-скан показывает не то же самое, что connect, и зачем вообще трогать UDP, когда «и по TCP всё видно». Прежде чем углубляться в конкретные эксплоиты и цепочки атак — выстрой фундамент на транспортном уровне. Не модель OSI из учебника, а практическое понимание того, как TCP-стек реагирует на пакет с флагом FIN на закрытый порт и почему NULL-скан на Windows-хосте даёт мусор. Без этого фундамента nmap превращается в чёрный ящик с непредсказуемым поведением. Если хочешь выстроить базу системно вместо прыжков между случайными YouTube-роликами — на IB Basics на codeby.school путь от сетей до первых задач проходят без академического занудства.
🚀 Хочешь закрепить на практике? Реши задачи по теме на HackerLab — категория «pentest-machines».
0 комментариев
Пожалуйста, войдите, чтобы оставить комментарий.
Загрузка комментариев...