Главная / Блог / Nmap для начинающих в CTF: от базового сканирования портов до скриптов NSE

14 мин.00

Nmap для начинающих в CTF: от базового сканирования портов до скриптов NSE

Nmap для начинающих в CTF: от базового сканирования портов до скриптов NSE

Nmap для начинающих в CTF: от базового сканирования портов до скриптов NSE

На первой HackTheBox-машине я убил полтора часа, перебирая эксплоиты для SSH и Apache на стандартных портах — ни один не зашёл. Стандартный скан показывал три открытых порта, все выглядели «чистыми». Запустил nmap -p- — и вот он, порт 8500 с веб-приложением, для которого есть публичный эксплоит. Shell за три минуты после полутора часов тупика. Вся разница — один флаг -p-.

Ситуация для CTF типичная: Nmap по умолчанию проверяет только 1000 самых популярных TCP-портов, а нестандартные сервисы — ради которых и строятся учебные машины — сидят на остальных 64535. По классификации MITRE ATT&CK, сканирование портов — это Active Scanning (T1595, Reconnaissance) и Network Service Discovery (T1046, Discovery). Первый этап любого пентеста, без которого дальше двигаться некуда.

Состояния портов в Nmap — что они значат для разведки цели

Перед запуском первого скана разберёмся, как Nmap классифицирует порты. Не ради академического интереса — от состояния порта зависит, стоит ли тратить на него время.

Nmap выделяет шесть состояний:

open — сервис принимает соединения. Каждый открытый порт — отдельный вектор атаки. В CTF именно они ведут к флагам.

closed — порт доступен (хост шлёт RST-пакет), но за ним никого нет. В CTF обычно неинтересен, зато подтверждает: машина живая и не режет соединения.

filtered — файрвол или пакетный фильтр не пропускает запрос. Nmap не может понять, открыт порт или нет. В CTF фильтрованный порт часто означает: сервис есть, но до него нужно добраться через другой вектор — SSRF, port forwarding после получения начального доступа.

unfiltered — порт отвечает на запросы, но Nmap не может решить, открыт он или закрыт. Встречается при ACK-сканировании (-sA), которое используют для маппинга правил файрвола.

open|filtered — Nmap не получил ответа и не может определить: порт открыт или фильтруется. Типично для UDP-сканирования и техник FIN, NULL, Xmas.

closed|filtered — только при idle-сканировании (-sI), встречается редко.

Для CTF реально важны два состояния: open (немедленно копать сервис) и filtered (вернуться позже, когда стандартные векторы исчерпаны). Состояние closed можно игнорировать. А вот open|filtered — повод запустить дополнительный скан с другим типом, чтобы уточнить результат. Если половина портов показывает filtered — между вами и целью стоит файрвол, и стандартный SYN-скан полной картины не даст.

Базовое сканирование портов Nmap: первые команды для CTF

Требования к окружению

  • ОС: Kali Linux, Parrot OS или любой дистрибутив Linux с Nmap 7.80+ (проверить: nmap --version)
  • Привилегии: sudo (root) нужен для SYN-сканирования, определения ОС и большинства продвинутых техник
  • Сеть: VPN-подключение к платформе (OpenVPN для HackTheBox, WireGuard для TryHackMe) — без VPN целевая машина недоступна
  • Установка: sudo apt install nmap (Debian/Ubuntu), sudo dnf install nmap (Fedora), sudo pacman -S nmap (Arch)

Быстрая разведка — стартовый скан

[Применимо: CTF-лаборатории, внутренний пентест без ограничений]

Команда sudo nmap -sC -sV -T4 -oA initial <IP> — стартовая точка для каждой CTF-машины. Разберу каждый флаг:

  • -sC запускает скрипты из категории default (аналог --script default) — безопасные скрипты для сбора баннеров SSH, HTTP-заголовков, информации о SMB-шарах
  • -sV определяет версии сервисов на открытых портах. Без него Nmap покажет только номер порта и предполагаемое имя сервиса, но не конкретную версию — а именно версия решает, есть ли публичный эксплоит
  • -T4 — timing template «Aggressive». В CTF-лаборатории нет IDS/IPS, скрытность не нужна — ускоряем
  • -oA initial — сохраняет результаты в трёх форматах: .nmap (текстовый, для чтения), .xml (для парсинга скриптами), .gnmap (greppable, удобен для grep)
sudo nmap -sC -sV -T4 -oA initial 10.10.10.100

PORT     STATE  SERVICE  VERSION
22/tcp   open   ssh      OpenSSH 8.9p1 Ubuntu
80/tcp   open   http     Apache httpd 2.4.52
443/tcp  open   ssl/http nginx 1.18.0
3306/tcp open   mysql    MySQL 5.7.38-log
8080/tcp closed http-proxy

Каждая строка — отдельное направление для копания. SSH с конкретной версией — проверяем CVE. Apache 2.4.52 на порту 80 — открываем в браузере, ковыряем веб-приложение. Nginx на 443 — возможно, отдельный сервис или API. MySQL 5.7 — пробуем дефолтные креды или анонимный доступ. Порт 8080 закрыт — сейчас неинтересен, но может открыться после действий на других сервисах.

Всегда сохраняйте результаты через -oA. Закрыли терминал без сохранения — потеряли всё и сканируете заново.

Сканирование всех 65535 портов

Стартовый скан проверяет 1000 самых популярных портов. Для полной картины параллельно запускайте полное сканирование: sudo nmap -p- -T4 -oA allports <IP>. Флаг -p- — «все порты от 1 до 65535». Медленнее — от 2 до 15 минут в зависимости от сети — но находит сервисы на нестандартных портах, которые авторы CTF-машин прячут намеренно.

Практический приём: стартовый скан в одном терминале, полный — во втором. Пока полный идёт, уже работайте с результатами быстрого. Когда полный завершится — сравните выводы. Порты, которых не было в первом скане, обычно и есть ключ к решению.

Промежуточный вариант — nmap --top-ports 100 -T4 <IP> (100 самых популярных портов). Быстрее стандартного скана, но менее полно. Годится для первичной ориентации, когда времени мало.

Определение версий сервисов и ОС

Флаг -sV заставляет Nmap слать дополнительные пробы к открытым портам для определения конкретной версии сервиса. Глубину контролирует --version-intensity (от 0 до 9, по умолчанию 7). Значение 0 — быстрый поверхностный скан (--version-light), 9 — максимально агрессивный. В CTF стандартного значения хватает за глаза.

Определение ОС включается флагом -O (требует sudo). Nmap анализирует особенности TCP/IP-стека цели и сравнивает с базой отпечатков (техника System Information Discovery, T1082 по MITRE ATT&CK). Для точного результата нужен минимум один открытый и один закрытый порт — без этого Nmap всё равно попробует, но с меньшей достоверностью.

Флаг -A объединяет -sV, -sC, -O и трассировку маршрута — «агрессивный» режим. Команда sudo nmap -A -T4 -p- <IP> -oA comprehensive — максимально полный скан. Используйте после начальной разведки, когда нужна детальная информация по всем портам.

Timing templates: скорость сканирования портов в CTF

Nmap предлагает шесть timing templates — от T0 (Paranoid) до T5 (Insane). Выбор шаблона влияет на скорость и на точность результатов:

Template Название Задержка между пакетами Когда использовать
T0 Paranoid 5 минут Обход IDS на реальном внешнем пентесте
T1 Sneaky 15 секунд Скрытное сканирование внешнего периметра
T2 Polite 0.4 секунды Снижение нагрузки на нестабильную сеть
T3 Normal по умолчанию Стандартный режим, внешний пентест
T4 Aggressive без лишних задержек CTF-лаборатории, внутренний пентест
T5 Insane минимальные таймауты Очень быстрый скан, высокий риск пропуска

В CTF — однозначно -T4. Режим -T5 ещё быстрее, но может пропускать порты из-за агрессивных таймаутов: сервер не успел ответить — Nmap считает порт закрытым или фильтрованным. На реальном пентесте выбор зависит от контекста: внутренний без ограничений — T4, внешний с IDS/IPS — T2 или T3.

Работает если: целевая машина в стабильной локальной сети или VPN, нет ограничений на скорость. Не работает если: между вами и целью перегруженный канал, ненадёжный VPN, или вы сканируете через интернет на T5 (потеря пакетов → ложноотрицательные результаты).

NSE скрипты Nmap для разведки цели в CTF

Nmap Scripting Engine (NSE) — встроенный фреймворк, который превращает Nmap из сканера портов в платформу обнаружения уязвимостей. В стандартной поставке — более 600 скриптов на Lua. Согласно документации nmap.org, NSE проектировался для пяти задач: обнаружение сетей, расширенное определение версий, поиск уязвимостей, обнаружение бэкдоров и эксплуатация (только при наличии авторизации). В CTF NSE решает главный вопрос: не просто «что работает на порту», а «что сломано и как это использовать».

Категории NSE-скриптов и безопасные границы

Скрипты организованы по категориям — функция и уровень агрессивности:

Категория Назначение Риск для цели
safe Не влияют на работу сервисов Безопасно
default Базовый сбор информации (активируются флагом -sC) Безопасно
vuln Проверка на известные уязвимости Обычно безопасно*
discovery Расширенное обнаружение информации Безопасно
auth Проверка аутентификации Умеренный
brute Перебор учётных данных Высокий
exploit Эксплуатация уязвимостей Только с разрешения
dos Проверка на отказ в обслуживании Только в лаборатории

Категории safe, default и discovery подходят для CTF без ограничений. Категория vuln обычно безопасна, но официально не входит в safe — проверяйте описание конкретного скрипта перед запуском на важных системах. brute и auth — с осторожностью (могут заблокировать учётки). exploit и dos — только на собственных стендах и учебных машинах, где последствия не затронут других.

Скрипты могут принадлежать нескольким категориям одновременно. Например, ssl-heartbleed входит в vuln, safe и discovery — проверяет уязвимость без риска сломать сервис, хотя сама проверка может вытянуть фрагменты памяти процесса, включая приватные ключи. Такой вот парадокс — safe, но данные утекают.

Для просмотра доступных скриптов по теме: grep vuln /usr/share/nmap/scripts/script.db или ls /usr/share/nmap/scripts/ | grep "ключевое_слово". Обновление базы: sudo nmap --script-updatedb.

Поиск уязвимостей: --script vuln и сканирование CVE

Флаг --script vuln запускает все скрипты категории vuln — проверки на конкретные уязвимости. Команда nmap -sV --script vuln <IP> сначала определяет версии сервисов (-sV), затем прогоняет по ним vuln-скрипты. Проверяются SSL/TLS-уязвимости (Heartbleed, POODLE), SMB-уязвимости (EternalBlue), HTTP-уязвимости (Shellshock, Apache Struts RCE) и десятки других.

Пример вывода при обнаружении Heartbleed — CVE-2014-0160, CVSS 7.5 HIGH, CWE-125 (buffer over-read в обработке Heartbeat Extension в OpenSSL 1.0.1 до 1.0.1g, позволяет вытянуть до 64 KB памяти процесса за запрос, включая приватные TLS-ключи и пароли):

443/tcp open  https
| ssl-heartbleed:
|   VULNERABLE:
|   The Heartbleed Bug is a serious vulnerability in OpenSSL
|   State: VULNERABLE
|   Risk factor: High
|   References:
|     https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0160

По данным CISA KEV, CVE-2014-0160 активно эксплуатируется с апреля 2014 года, EPSS-score — 1.0 (максимальная вероятность эксплуатации). Когда Heartbleed обнаружили, разработчики Nmap выкатили скрипт ssl-heartbleed за 48 часов — по данным nmap.org, один из примеров скорости реакции NSE-сообщества. Аналогичные скрипты есть для CVE-2017-5638 (Apache Struts RCE, CVSS 9.8 CRITICAL, по данным CISA KEV используется в ransomware-кампаниях) и других активно эксплуатируемых дыр.

Если скрипт ничего не нашёл — вывод по порту будет пустым. Тишина в данном случае — хороший знак.

vulners.nse — CVE-детекция по версиям сервисов

Нюанс, который упускают многие новички: --script vuln не включает популярный сторонний скрипт vulners.nse. Это два разных инструмента для разных задач. Встроенные vuln-скрипты проверяют конкретные уязвимости (Heartbleed, EternalBlue). А vulners.nse дёргает API vulners.com и автоматически сопоставляет обнаруженные версии сервисов с полной базой CVE — то, что раньше приходилось делать руками.

Установка: скопировать vulners.nse из GitHub-репозитория nmap-vulners в /usr/share/nmap/scripts/, затем sudo nmap --script-updatedb. Скрипту нужен доступ к API vulners.com — в изолированных (air-gapped) лабораториях он не заведётся.

Запуск: nmap -sV --script vulners <IP>. Флаг -sV обязателен — без определения версий vulners.nse нечего сопоставлять с базой. Для фильтрации по критичности — аргумент mincvss: команда nmap -sV --script vulners --script-args mincvss=7.0 <IP> покажет только уязвимости с CVSS 7.0 и выше (High и Critical). По данным cyberdesserts.com, рекомендуемые пороги: 9.0 — только критические (быстрая сортировка при дефиците времени), 7.0 — высокие и критические (оптимально для большинства задач), 5.0 — включая средние.

Альтернатива — vulscan.nse, который работает с локальными оффлайн-базами (NVD, Exploit-DB). В отличие от vulners.nse, не требует интернета, но базы нужно обновлять вручную. В CTF с доступом к сети vulners.nse удобнее и актуальнее.

Полезные NSE-скрипты для CTF-разведки

Несколько скриптов, которые часто дают результат на учебных машинах:

  • http-enum — перебор директорий и файлов на веб-сервере (встроенный аналог dirb/gobuster). Запуск: nmap --script http-enum -p 80,443,8080 <IP>
  • smb-vuln* — проверка SMB-уязвимостей, включая EternalBlue (MS17-010). Запуск: nmap --script smb-vuln* -p 445 <IP>
  • ftp-anon — проверка анонимного доступа к FTP. На CTF-машинах анонимный FTP — частый вектор для получения начальных файлов. Запуск: nmap --script ftp-anon -p 21 <IP>
  • mysql-info — сбор информации о MySQL-сервере. Запуск: nmap --script mysql-info -p 3306 <IP>
  • ssl-enum-ciphers — анализ поддерживаемых SSL/TLS-шифров. Помогает выявить слабые конфигурации. Запуск: nmap --script ssl-enum-ciphers -p 443 <IP>

Для запуска нескольких скриптов одновременно перечислите через запятую: nmap --script "http-enum,http-headers" -p 80 <IP>. Для принудительного запуска скрипта на нестандартном порту (допустим, HTTP на 9090): nmap --script http-enum -p 9090 <IP> — Nmap применит скрипт к указанному порту независимо от стандартного назначения.

Практический CTF-workflow: от скана до вектора атаки

Пошаговый алгоритм, который работает на каждой CTF-машине. Порядок проверен на сотнях машин HackTheBox и TryHackMe.

Шаг 1. Быстрый скан топ-портов. sudo nmap -sC -sV -T4 -oA initial <IP>. Занимает 30-90 секунд. Даёт первичную картину: какие сервисы торчат на стандартных портах.

Шаг 2. Полный скан в фоне. Одновременно во втором терминале: sudo nmap -p- -T4 -oA allports <IP>. Занимает 2-15 минут. Ищет сервисы на нестандартных портах.

Шаг 3. Интерпретация результатов. Для каждого открытого порта определите: что за сервис, какая версия, есть ли известные уязвимости. Веб-порты (80, 443, 8080, 8443) — откройте в браузере и параллельно запустите перечисление директорий. SSH — запишите версию, пока не трогайте (обычно не вектор для начального доступа). SMB (445) — проверьте на EternalBlue и анонимный доступ. FTP (21) — проверьте анонимный вход.

Шаг 4. Целевой скан новых портов. Если полный скан нашёл порты, которых не было в начальном — sudo nmap -sC -sV -p <новые_порты> <IP> для определения версий.

Шаг 5. Скрипты уязвимостей. Для подозрительных сервисов (устаревшие версии, нестандартные порты): nmap -sV --script vuln -p <порт> <IP>. Если установлен vulners.nse — добавьте: --script "vuln,vulners" --script-args mincvss=7.0.

Шаг 6. Переход к эксплуатации. Результаты скана — входные данные для следующего этапа. Версию сервиса ищите через searchsploit <сервис> <версия>. CVE из vulners.nse проверяйте по Exploit-DB. Веб-приложение отправляйте в Burp Suite для ручного тестирования. Каждый обнаруженный порт и сервис — отдельная ветка исследования.

Workflow не зависит от сложности машины — одинаково применим для Easy и Hard. Различается только глубина копания на каждом шаге.

Типичные ошибки новичков при сканировании Nmap

Сканирование без sudo. Без root-привилегий Nmap не может слать «сырые» пакеты и вместо SYN-сканирования (-sS) использует полное TCP-соединение (-sT). Медленнее, и определение ОС (-O) недоступно. Продвинутые техники (FIN, NULL, Xmas) тоже мимо.

Только TCP, без UDP. Новички сканируют TCP и полностью пропускают UDP-сервисы. DNS на 53/udp, SNMP на 161/udp, TFTP на 69/udp — все работают по UDP и могут оказаться ключевым вектором. UDP-скан медленный (sudo nmap -sU --top-ports 50 <IP> — от 5 до 30 минут), но на некоторых CTF-машинах без него вектор просто не найти.

Игнорирование флага -Pn. По умолчанию Nmap шлёт ICMP-запрос перед сканированием. Если хост не ответил — сканирование не начнётся: «host seems down». Если машина блокирует ICMP (файрвол, конфигурация ОС), добавьте -Pn для пропуска проверки доступности. В CTF этот флаг часто нужен для машин с настроенным файрволом.

Запуск -A на всех портах сразу. Команда nmap -A -p- — максимально полный скан, но и максимально медленный. Определение ОС, скрипты default и трассировка для каждого из 65535 портов — 30-60 минут. Эффективнее: сначала nmap -p- для обнаружения открытых портов, затем -A только для них.

Не сохранять результаты. Без -oA результат скана живёт только в терминале. Закрыли окно — всё, сканируйте заново. Всегда -oA <имя>.

Когда стандартные техники НЕ работают

Стандартный SYN-скан (-sS) — основа разведки, но в некоторых ситуациях он бесполезен.

Работает если: целевая машина доступна по сети, между вами и целью нет агрессивного файрвола, скан запущен с sudo.

Не работает если:

  • Хост блокирует ICMP и Nmap считает его «мёртвым» — решение: -Pn
  • Rate limiting на файрволе обрезает пакеты при быстром сканировании — решение: снизить скорость до -T2 или -T3
  • Port knocking — сервис открывается только после обращения к определённой последовательности портов. Nmap это не обнаружит. Ищите подсказки в других сервисах: конфиги, записки, комментарии в HTML-коде
  • IPv6-сервисы — если машина слушает на IPv6, а вы сканируете IPv4, порт не найдётся. Nmap поддерживает IPv6 через флаг -6
  • Сервис запускается динамически — некоторые CTF-машины активируют порт после определённого действия (отправка запроса, логин через другой сервис). Поможет повторный скан на следующем этапе решения

За пару лет в CTF я пришёл к выводу: главная проблема новичков — не незнание флагов Nmap, а неумение читать результаты. Все запоминают -sC -sV -p-, но мало кто задумывается, почему конкретный порт показывает filtered вместо closed или что означает tcpwrapped в колонке SERVICE. Механическое копирование команд из cheat sheet работает до первой нестандартной машины. А в CTF нестандартные машины — самые интересные.

Понимание того, что происходит под капотом, отличает человека, который решает машину за час, от того, кто застревает на разведке. Почему SYN-скан не нашёл порт, хотя он открыт? Потому что ICMP заблокирован и Nmap решил, что хост мёртв — нужен был -Pn. Почему vulners.nse не показывает CVE? Забыли -sV, и скрипту нечего сопоставлять с базой. Каждый такой нюанс — потерянный час при неправильном подходе и три секунды при правильном.

На практике потребовалось около полугода и сотня просканированных машин, чтобы перестать бездумно копировать команды и начать читать вывод Nmap как историю о цели: операционная система, назначение сервера, вероятные ошибки конфигурации — всё зашито в результатах скана, если знать куда смотреть. На HackerLab есть лабы с аналогичными машинами, где можно набить руку именно на интерпретации — а не просто на запуске команд.

🚀 Хочешь закрепить на практике? Реши задачи по теме на HackerLab — категория «pentest-machines».

Поделиться

0 комментариев

Пожалуйста, войдите, чтобы оставить комментарий.

Загрузка комментариев...