Перейти к содержимому

Анализ вывода Nmap на реальном стенде: как читать результаты и не пропустить вектор атаки

Анализ вывода Nmap на реальном стенде: как читать результаты и не пропустить вектор атаки
Время чтения: 13 мин.

На лабораторном стенде вывод nmap -sV -sC занял 30 строк. Три из них вели к RCE через дефолтный Tomcat Manager — но новичок два часа брутфорсил SSH на порту 22, начисто проигнорировав порт 8080, где http-title показывал стандартную страницу. Знакомо?

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

Место Nmap в цепочке разведки: что идёт до и после

Nmap закрывает два этапа по MITRE ATT&CK: Active Scanning (T1595, Reconnaissance) и Network Service Discovery (T1046, Discovery). Подтехника Vulnerability Scanning (T1595.002) подключается, когда к базовому скану добавляются NSE-скрипты категории vuln. В терминах kill chain — это после пассивной разведки (OSINT, DNS enumeration, Shodan/Censys) и перед эксплуатацией (Exploit Public-Facing Application, T1190, Initial Access).

Nmap отвечает на три вопроса: какие хосты живые, какие порты открыты и что за сервисы на них крутятся. Всё остальное — эксплуатация, закрепление, перемещение по сети — строится на его результатах.

Контекст применения меняет параметры запуска. На внешнем пентесте Nmap — первый инструмент после получения скоупа. Приоритет — скорость и минимум шума: SYN-скан (-sS) с умеренной скоростью (-T3), без скриптов на первом проходе. На внутреннем пентесте — запуск после получения точки опоры (foothold) для маппинга сегмента. Приоритет — полнота: -sV -sC -p-, потому что IDS/IPS за периметром обычно менее агрессивен к трафику из доверенной зоны.

Что идёт после Nmap: результаты сканирования определяют направление атаки. Обнаружен Apache Tomcat 8.5 на порту 8080 — следующий шаг: проверка дефолтных кредов, поиск CVE по минорной версии, доступ к Manager. Обнаружен SMB на 445 — проверка подписи, null session, поиск общих папок через smb-enum-shares. Nmap не эксплуатирует уязвимости сам, но генерирует данные, от которых зависит каждый следующий шаг.

Для скоростного покрытия больших подсетей на начальной фазе внешнего пентеста часто используют masscan — он сканирует порты значительно быстрее, но не определяет версии сервисов и не поддерживает NSE. Типичный workflow: masscan находит открытые порты по всему скоупу за минуты, затем Nmap точечно опрашивает найденные порты с -sV -sC. Инструменты дополняют, а не заменяют друг друга.

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

Прежде чем разбирать вывод, убедитесь что окружение готово:

  • ОС: Kali Linux 2024.x+ (Nmap предустановлен) или любой Linux/macOS/Windows с Nmap из пакетного менеджера
  • Версия Nmap: 7.94+ (проверить: nmap --version). NSE-скрипты обновляются вместе с Nmap. Проект активно поддерживается (nmap.org)
  • Права: root/sudo для SYN-сканирования (-sS). Без root доступен только TCP Connect (-sT) — медленнее и заметнее в логах
  • Сеть: доступ к целевому хосту. Для практики — scanme.nmap.org (официальный тестовый сервер Nmap), стенды HackTheBox, TryHackMe
  • RAM: 512 МБ минимум для одиночного хоста, 2+ ГБ при работе с подсетями /24 и полным набором NSE-скриптов

Установка: sudo apt update && sudo apt install nmap на Ubuntu/Debian. На macOS: brew install nmap. Для Windows — инсталлятор с nmap.org/download, после установки запускать из cmd/PowerShell с правами администратора.

Разбираем вывод Nmap строка за строкой

Запускаем базовое сканирование учебного стенда с определением версий и дефолтными скриптами: nmap -sV -sC -p- target.htb. Флаг -sV включает Version Detection (System Information Discovery, T1082), -sC запускает скрипты категории default, -p- сканирует все 65535 TCP-портов вместо стандартных top-1000.

PORT     STATE  SERVICE VERSION
22/tcp   open   ssh     OpenSSH 7.9p1 Debian 10+deb10u2
80/tcp   open   http    Apache httpd 2.4.38 ((Debian))
|_http-title: Default Page: It works
443/tcp  closed https
3306/tcp open   mysql   MySQL 5.5.62-0+deb8u1
8080/tcp open   http    Apache Tomcat 8.5.43
|_http-title: Apache Tomcat/8.5.43

Теперь читаем это так, как читает пентестер при работе со стендом.

Состояния портов: open, closed, filtered

Nmap классифицирует порты в три основных состояния, и каждое несёт информацию.

open — порт принимает соединения, за ним работает сервис. Каждый open порт — элемент поверхности атаки. Четыре open порта в примере — четыре потенциальных вектора.

closed — порт доступен, хост отвечает RST, но сервиса за портом нет. В нашем примере 443 closed означает: HTTPS не настроен, хотя порт не заблокирован файрволом. Для пентестера закрытый порт сам по себе неинтересен, но подтверждает — файрвол пропускает трафик сюда, а SSL/TLS не настроен. Косвенный признак неполного hardening.

filtered — Nmap не получил ответа или получил ICMP-ошибку «destination unreachable». Порт за файрволом, пакеты дропаются. На внешнем пентесте массовый filtered (например, 998 filtered ports) — норма: между сканером и целью стоит stateful firewall или cloud security group (AWS SG, Azure NSG).

Отдельное состояние open|filtered встречается при UDP-сканировании (-sU). UDP не подтверждает получение пакетов, и отсутствие ответа не позволяет различить открытый порт и фильтрацию. Видите open|filtered — запускайте точечную проверку: nmap -sUV -p <port> target с определением версии.

[Ограничение: современные stateful firewall (Check Point, Palo Alto, Fortinet) могут подменять ответы — показывать ложный closed для реально фильтруемых портов. Результат Nmap — лучшая гипотеза, не абсолютная истина.]

Версии сервисов и зацепки для вектора атаки

Возвращаемся к выводу и смотрим, что каждая строка с версией рассказывает о цели.

OpenSSH 7.9p1 Debian 10+deb10u2 — четыре факта в одной строке. Сервис SSH, версия 7.9p1, ОС Debian 10 (Buster), патч-уровень deb10u2 (второе обновление безопасности). OpenSSH 7.9 — не самая старая версия, брутфорс SSH редко даёт результат на стендах, но строка подсказывает ОС. А это критично для подбора эксплойтов ядра на этапе privilege escalation.

Apache httpd 2.4.38 ((Debian)) в связке с http-title: Default Page: It works — двойной сигнал. Apache 2.4.38 — конкретная минорная версия, которую стоит пробить по CVE-базам. А дефолтная страница — сильный индикатор: администратор не настроил виртуальный хост. Это часто коррелирует с отсутствием hardening в целом — слабые конфигурации, дефолтные директории (проверяем через nmap --script http-enum -p 80 target), отсутствие заголовков безопасности (A05:2021 — Security Misconfiguration по OWASP Top 10).

MySQL 5.5.62-0+deb8u1 — один из самых информативных фрагментов вывода. MySQL 5.5 достиг End of Life в декабре 2018 года. Суффикс deb8u1 указывает на Debian 8 (Jessie), хотя SSH говорит о Debian 10. Возможные объяснения: MySQL крутится в Docker-контейнере на базе Debian 8 или пакет установлен из устаревшего репозитория. В обоих случаях — высокая вероятность непатченных уязвимостей (A06:2021 — Vulnerable and Outdated Components по OWASP Top 10). Следующий шаг: nmap --script mysql-empty-password -p 3306 target для проверки пустых паролей.

Apache Tomcat 8.5.43 на порту 8080 — главная находка на этом стенде. Стандартный http-title подтверждает: титульная страница не изменена. С высокой вероятностью Tomcat Manager доступен по /manager/html с дефолтными кредами (tomcat:tomcat, admin:admin, tomcat:s3cret). Если Manager открыт — это прямой путь к RCE: загрузка WAR-файла с reverse shell, и через минуту у вас шелл на сервере. Именно это пропустил новичок из начала статьи.

NSE-скрипты для обнаружения уязвимостей: от -sC до —script vuln

Nmap Scripting Engine превращает сканер портов в платформу для оценки уязвимостей. По данным Nmap.org, в стандартной поставке — более 600 Lua-скриптов. Именно NSE отвечает за то, что отличает анализ вывода Nmap от простого перечисления портов.

Категории NSE-скриптов и выбор под задачу

Для пентестера критичны четыре категории.

default — безопасные скрипты первичной разведки. Запускаются через -sC или --script=default. На выходе: баннеры (http-title, ssh-hostkey), базовая информация о сервисах (mysql-info, smb-os-discovery), проверка анонимного доступа (ftp-anon). Безопасны для продакшена — не отправляют exploit-пакеты.

vuln — проверка известных уязвимостей без эксплуатации. Запуск через --script vuln. Скрипты ищут Heartbleed, EternalBlue, Shellshock и десятки других. При обнаружении — явная метка VULNERABLE с ссылкой на CVE.

auth — проверка аутентификации: дефолтные креды, пустые пароли. Включает mysql-empty-password, ftp-anon, http-default-accounts. Применяется точечно, после определения сервисов.

safe — скрипты, гарантированно не влияющие на работу сервиса. Частично пересекаются с default и vuln. Если сомневаетесь в допустимости — --script safe даёт максимум информации без риска.

Категории exploit, dos, brute, fuzzer — агрессивные действия. dos может уронить сервис, brute генерирует сотни попыток входа, заметных для любого SIEM. На продакшен-системах без письменного разрешения — запрещены. В лаборатории — пожалуйста, но с пониманием последствий.

Отдельно про точечный запуск скриптов. Когда на хосте обнаружен SMB (порт 445), запуск nmap --script smb-enum-shares,smb-vuln-ms17-010 -p 445 target даст больше, чем категорийный --script vuln, потому что вы целенаправленно проверяете конкретные гипотезы: открытые шары и EternalBlue. Общий принцип — начать с категории, сузить до конкретных скриптов.

—script vuln и vulners.nse: матчинг CVE по версиям сервисов

Команда nmap -sV --script vuln target запускает все встроенные скрипты категории vuln. Они проверяют уязвимости активно — отправляют тестовые пакеты и анализируют ответы. Скрипт ssl-heartbleed, например, отправляет crafted Heartbeat-пакет и определяет, возвращает ли сервер данные из памяти процесса.

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

Метка State: VULNERABLE однозначна — сервер подвержен CVE-2014-0160 (CVSS 7.5, HIGH; CWE-125 — Out-of-bounds Read). Уязвимость позволяет удалённому атакующему без аутентификации вытягивать фрагменты памяти процесса OpenSSL: приватные ключи, сессионные cookie, пароли. По данным CISA KEV, CVE-2014-0160 активно эксплуатируется, EPSS-оценка — 1.0 (максимальная вероятность). Верифицированные PoC доступны на Exploit-DB (EDB-32764, EDB-32791, EDB-32998).

Принципиально иной подход у скрипта vulners.nse. Это внешний скрипт, не входящий в стандартную поставку Nmap, и его нужно ставить отдельно: скопировать vulners.nse в /usr/share/nmap/scripts/ (из GitHub-репозитория nmap-vulners) и обновить базу командой sudo nmap --script-updatedb. После установки запуск: nmap -sV --script vulners target.

Ключевое отличие: vulners.nse не проверяет уязвимости активно. Он берёт определённые версии сервисов (результат -sV) и матчит их через API vulners.com с базой CVE. Без -sV скрипт бесполезен — ему нечего матчить. Параметр --script-args mincvss=7.0 фильтрует вывод до High и Critical. На время-критичных assessment’ах начинайте с mincvss=9.0, затем расширяйте до 7.0.

Распространённая ошибка — считать, что --script vuln включает vulners.nse. Нет. Категория vuln содержит только встроенные скрипты. Если нужен матчинг версий по CVE-базам — vulners.nse ставится отдельно.

[Ограничение: vulners.nse требует интернет-подключения для запросов к API. В изолированных сетях альтернатива — vulscan.nse, работающий с локальными офлайн-базами CVE. Но локальные базы устаревают без ручного обновления.]

От вывода к вектору: практическая таблица решений

Интерпретация вывода — полдела. Нужна система принятия решений. Ниже — таблица, привязывающая типичные находки в выводе Nmap к конкретным действиям.

Что в выводе Что это значит Следующий шаг
http-title: Apache Tomcat/X.X Дефолтная страница, возможен Manager Проверить /manager/html с кредами tomcat:tomcat, admin:admin
ftp-anon: Anonymous FTP login allowed Анонимный доступ к FTP Подключиться, искать конфиги, бэкапы, скрипты развёртывания
MySQL версии 5.5 или ниже End-of-Life, непатченные CVE --script mysql-vuln*, mysql-empty-password
ssl-cert: Subject: CN=internal.corp Сертификат раскрывает внутреннее имя Добавить домен в скоуп для дальнейшей разведки
smb-os-discovery: Windows Server 2012 R2 ОС без поддержки с 2023 --script smb-vuln* (EternalBlue, MS08-067)
Порт 8443 / 9090 / 4848 open Admin-панели (Jenkins, Webmin, GlassFish) Открыть в браузере, определить приложение, дефолтные креды
http-server-header: Apache/2.4.49 Конкретная минорная версия с известными CVE Проверить CVE для версии (path traversal в 2.4.49/2.4.50)
Порт 6379 open, сервис redis Redis часто без аутентификации redis-cli -h target, проверить доступ без пароля
http-title: 404 Not Found на нестандартном порту Веб-сервер работает, контент скрыт Запустить http-enum, http-methods, directory brute-force

На внешнем пентесте фокус — веб-сервисы (80, 443, 8080, 8443). Через них чаще всего происходит Initial Access (T1190). Уязвимости вроде CVE-2017-5638 в Apache Struts (CVSS 9.8, CRITICAL; CWE-755 — Improper Handling of Exceptional Conditions) эксплуатируются удалённо через HTTP-заголовок Content-Type, без аутентификации. По данным CISA KEV, эта уязвимость используется в атаках с ransomware, EPSS — 1.0. Nmap покажет версию Struts через -sV, а подтверждение потребует ручного тестирования или специализированного скрипта.

На внутреннем пентесте акцент смещается: SMB (445), RDP (3389), WinRM (5985/5986), LDAP (389/636) — сервисы для lateral movement. Тут Nmap помогает в Remote System Discovery (T1018) и System Network Configuration Discovery (T1016).

Ограничения Nmap в современных средах

Nmap — инструмент номер один для сетевой разведки, но у него есть чёткие границы. Знать их так же важно, как знать флаги.

Cloud и WAF. AWS Security Groups, Azure NSG, GCP Firewall Rules дропают пакеты без ответа. Все порты выглядят как filtered. WAF (Cloudflare, AWS WAF) проксирует трафик — Nmap видит IP-адрес CDN, а не реального сервера. На внешнем пентесте через CDN результаты сканирования отражают конфигурацию прокси, не целевого сервера.

Rate limiting и IDS/IPS. Агрессивное сканирование (-T4, -T5) триггерит правила детектирования. Snort, Suricata, коммерческие IPS логируют и блокируют массовые SYN-пакеты. CrowdStrike Falcon и SentinelOne фиксируют активное сканирование как подозрительную активность. Замедление решает часть проблемы: --scan-delay 1s между зондами или -T2 (polite).

Version Detection — не гарантия. Баннеры можно подменить: mod_security для Apache, SSH Banner Spoofing. Кастомные сервисы на нестандартных портах могут показывать tcpwrapped или unknown service. tcpwrapped означает, что TCP-соединение завершилось handshake, но сервис немедленно закрыл соединение без ответа — возможен TCP wrapper или honeypot. Я на одном стенде потратил полчаса, пытаясь понять, что за сервис на 9999 — оказался honeypot.

UDP. Полное UDP-сканирование (-sU -p-) одного хоста занимает десятки минут из-за rate-limiting ICMP-ответов. Прагматичный подход: сканируйте только нужные UDP-порты — nmap -sU -p 53,161,500,1194 target (DNS, SNMP, IKE, OpenVPN).

Веб-приложения. Nmap определяет веб-сервер и заголовки, но не видит SQL-инъекции, IDOR или broken access control внутри приложения. Для веб-уровня нужны Burp Suite, OWASP ZAP, Nuclei (для Nuclei, к слову, есть готовые YAML-шаблоны под конкретные CVE — включая Heartbleed и Struts). Nmap — отправная точка разведки, не замена полноценного сканера уязвимостей.

Пошаговый workflow сканирования стенда

Для закрепления — конкретная последовательность действий на учебном стенде или при работе с целью пентеста.

  1. Быстрый скан — определить живые хосты и top-1000 портов: nmap -sS -T3 target
  2. Полный скан портов — найти сервисы на нестандартных портах: nmap -sS -p- -T3 target
  3. Определение версий и скрипты — для найденных портов: nmap -sV -sC -p 22,80,3306,8080 target
  4. Vuln-проверка — для веб-сервисов и сетевых сервисов: nmap -sV --script vuln -p 80,443,8080 target
  5. Точечные NSE — под конкретную гипотезу: nmap --script smb-vuln*,smb-enum-shares -p 445 target
  6. UDP-выборка — нужные сервисы: nmap -sU -p 53,161,500 target
  7. Сохранение результатов — для отчёта и повторного анализа: добавьте -oN scan.txt -oX scan.xml к любой команде

Каждый шаг строится на результатах предыдущего. Не запускайте nmap -A -p- --script vuln одной командой — это громко для IDS, медленно (часы на одном хосте) и генерирует вывод, в котором главное теряется за второстепенным. Последовательный подход экономит время и снижает риск обнаружения на реальном пентесте.

Тема анализа вывода Nmap кажется тривиальной — до первого engagement’а, где результат зависит от умения читать. По моему опыту, 80% начинающих проходят мимо находок не потому, что Nmap их скрыл. Версия сервиса — не просто строка текста, а запрос к CVE-базе. Дефолтный http-title — не техническая мелочь, а индикатор того, что администратор не трогал конфигурацию после установки. Строка filtered — не «порт закрыт», а «между вами и целью стоит устройство, которое стоит изучить».

Этот навык формируется через разбор десятков стендов, не через заучивание флагов. Каждый новый порт, каждая нестандартная версия тренирует паттерн «вижу X — проверяю Y — нахожу Z». Большинство руководств учат запускать команды, но не учат интерпретировать ответы. А вся ценность сканирования — именно в интерпретации: в зазоре между тем, что Nmap показал, и тем, что пентестер из этого извлёк. На IB Basics разбирают как раз этот навык — от первого скана до выводов, без академической воды.

Эту тему и смежные навыки разбирают на практике в курсе «Специалист по тестированию на проникновение» Codeby Academy.