Сканирование портов и сервисов
Сканирование портов находит, какие сервисы слушают; фингерпринтинг называет их версии. И то и другое — разведка, только против авторизованных целей, и каждый зонд оставляет строку в логе защитника, что и делает сканирование двусторонней историей.
На авторизованном лабораторном хосте ты наводишь сканер на один IP, и через восемь секунд у тебя есть карта, которой не было: порт 22 открыт и отвечает как OpenSSH 7.4, порт 5432 открыт и говорит на протоколе PostgreSQL, на порту 6379 слушает Redis вообще без баннера авторизации. Никто не выдавал тебе эту опись — ты вывел всё это из того, как хост ответил на несколько тысяч аккуратно сформированных пакетов. Эта восьмисекундная карта — разведка, и те же восемь секунд записали около трёх тысяч попыток подключения в лог на другой стороне. Сканирование никогда не бывает односторонним чтением: каждый вопрос, который ты задаёшь сети, сеть может услышать.
К концу урока ты поймёшь, как сканирование портов работает на уровне TCP, как фингерпринтинг сервисов превращает открытый порт в названную версию и что именно видит защитник, пока ты это делаешь, — всё против систем, которые ты авторизован тестировать.
Сначала авторизация — сканирование это разведка, а не бесплатное чтение
Прежде любого механизма ниже остаётся в силе правило, открывающее весь этот трек: сканирование портов легитимно только против системы, которой ты владеешь или которую явно авторизован тестировать. В терминах MITRE ATT&CK сканирование — это Active Scanning в тактике Reconnaissance (TA0043), и слово «active» здесь ключевое. В отличие от чтения публичных DNS-записей цели, сканер отправляет пакеты на цель и ждёт ответов, а значит, касается инфраструктуры, которой ты не управляешь, и оставляет на ней следы. Наводить сканер на хост без авторизации — это неправомерный доступ почти в любой юрисдикции, как бы мягким ни было сканирование. Всё здесь оформлено для CTF-машины, намеренно уязвимой VM, которую ты развернул, или работы в рамках согласованного объёма — никогда для реальной цели «просто посмотреть, что открыто».
Мы учим это защитно: если ты точно понимаешь, что вскрывает сканирование и что оно после себя оставляет, ты можешь и сократить то, что раскрывают твои собственные системы, и распознать сканирование в своих логах, когда его запустят против тебя.
Как работает сканирование портов: рукопожатие TCP как вопрос
Сканирование портов — это просто трёхэтапное рукопожатие TCP, использованное как допрос. Чтобы открыть обычное соединение, клиент шлёт SYN, сервер отвечает SYN-ACK, если порт слушает, и клиент завершает ACK. Сканер эксплуатирует середину этого обмена: он шлёт SYN, и один лишь ответ сообщает ему состояние порта ещё до того, как соединение полностью установлено.
- Вернулся
SYN-ACK→ порт открыт: что-то слушает. - Вернулся
RST(сброс) → порт закрыт: хост достижим, но там ничего не слушает. - Ничего не вернулось (после повторов/таймаута) → фильтруется: файрвол молча отбрасывает зонд, и ты не отличаешь открытый от закрытого.
Классика по умолчанию — SYN-сканирование (часто называемое «полуоткрытым» или «скрытным»): оно шлёт SYN, читает ответ и затем шлёт RST, чтобы разорвать наполовину построенное соединение до завершения рукопожатия. Исторически это имело значение, потому что соединение, которое так и не открылось полностью, часто не попадало в собственные логи приложения. В противоположность ему connect-сканирование завершает полное трёхэтапное рукопожатие через штатный системный вызов соединения ОС — надёжнее и служит запасным вариантом, когда у сканера нет прав на формирование сырых пакетов, но громче, потому что завершённое соединение — ровно то, что записывает журналирование приложения.
От открытого порта к названному сервису: фингерпринтинг и баннеры
Номер открытого порта — слабая догадка. Порт 22 обычно означает SSH, а 5432 обычно — PostgreSQL, но сервисы постоянно работают на нестандартных портах, и одно лишь «открыт» ничего не говорит о том, какое ПО и какой версии слушает. Превращение номера порта в уверенную идентификацию — это фингерпринтинг сервиса, и у него два вида.
Дешёвый — захват баннера (banner grabbing): многие сервисы объявляют себя в момент подключения. Открой сырое TCP-соединение к порту SSH, и он поприветствует тебя строкой версии вроде SSH-2.0-OpenSSH_7.4; SMTP-сервер ответит строкой 220 с названием почтового ПО; неправильно настроенный веб-сервер вернёт заголовок Server:. Ты читаешь баннер, который сервис сам отдаёт, и знаешь, что это, — без всякой хитрости, ведь сервис сам тебе сообщил.
Более глубокий — активный фингерпринтинг (детекция сервиса/версии -sV в nmap). Когда баннер отсутствует, лжёт или неоднозначен, сканер шлёт последовательность сформированных зондов и сопоставляет паттерн ответов — тайминги, точные последовательности байтов, поведение при ошибках, особенности протокола — с базой известных сигнатур сервисов. Он также может вывести ОС по тонким различиям в том, как сам стек TCP/IP отвечает (значения TTL, размеры окна, порядок опций), потому что нет двух одинаково ведущих себя стеков. Это точнее, чем доверять баннеру, но и гораздо громче: вместо одного соединения он выстреливает десятками необычных зондов на порт — ровно тот аномальный трафик, который IDS настроен замечать.
| Техника | Что делает сканер | Что узнаёт | Шум / заметность |
|---|---|---|---|
SYN-скан (-sS) | SYN, читает ответ, RST до завершения рукопожатия | Открыт / закрыт / фильтруется по каждому порту | Тише на уровне приложения; виден файрволу/IDS |
Connect-скан (-sT) | Завершает полное 3-этапное рукопожатие через ОС | Те же состояния, без прав на сырые пакеты | Громче всего: каждое соединение бьёт по логам приложения |
| Захват баннера | Подключается, читает приветствие сервиса | Имя + версия сервиса, если отдаются | Низкая: похоже на одно обычное соединение |
Детекция версии (-sV) | Шлёт сформированные зонды, сопоставляет сигнатуры ответов | Уверенная версия, даже если баннер лжёт/отсутствует | Высокая: много необычных зондов на порт |
▸Почему это работает
Почему скорость сканирования напрямую обменивается на скрытность и точность? У сканера несколько ручек — сколько портов в секунду, сколько параллельных зондов, как долго ждать ответа. Выкрути их вверх — полное сканирование завершится за секунды, но всплеск одинаковых пакетов в узком окне — самое лёгкое, на что защитнику настроить алерт (например, «30 SYN на 30 портов с одного источника за секунду»). Замедли его — рандомизируй порядок, разнеси зонды на минуты — и ты сольёшься с обычным трафиком, но теперь сканирование идёт часами, а нестабильная сеть теряет ответы, стоя тебе точности. Нет настройки, которая была бы быстрой, точной и невидимой; ты всегда тратишь одно, чтобы купить другое. Вся работа защитника — сделать так, чтобы быстрый-и-точный угол спускал тревогу.
Что видит защитник — и почему сканирование двусторонне
Это та половина, о которой забывают новички: пока ты читаешь цель, цель читает тебя. Каждый зонд — это пакет с твоим IP-источником, а защитный стек построен замечать ровно те паттерны, что создаёт сканирование.
- Логи файрвола / соединений фиксируют поток: много SYN на много портов с одного источника в короткое окно. Серия полуоткрытых соединений, завершённых
RST(сигнатура SYN-скана), или разлёт по всему диапазону портов — хрестоматийный отпечаток сканирования. - IDS/IPS (Snort, Suricata или облачный эквивалент) имеет правила, настроенные именно на это, — порог различных портов, затронутых с источника за интервал, — и может выдать алерт, ограничить скорость или вовсе заблокировать IP-источник.
- Детекция версии ещё заметнее: необычные, не соответствующие протоколу зонды, которые шлют
-sVи детекция ОС, не похожи ни на один нормальный клиент, поэтому они зажигают сигнатурное обнаружение куда сильнее простого прохода по портам.
Защитные уроки выпадают прямо отсюда. Сократи то, что вообще раскрыто (закрой порты, привяжи сервисы к внутренним интерфейсам, поставь впереди файрвол, чтобы большинство зондов фильтровались, а не получали ответ). Срежь или обезличь баннеры, чтобы успешное соединение не отдавало ничего, — но помни, что это лишь прячет ярлык, а не сам сервис, поэтому замедляет атакующего, а не останавливает его. И мониторь сигнатуру сканирования, чтобы обнаруживать разведку рано, ведь в цепочке поражения (kill chain) разведка — это первая стадия, и поймать атакующего на ней — самое дешёвое место разорвать цепочку.
На авторизованной работе тебе нужно определить точные версии ПО на хосте, но SOC клиента активно мониторит, и ты хочешь как можно дольше оттянуть обнаружение. Какой подход лучше отвечает цели?
При SYN-сканировании что говорит сканеру ответ хоста и почему SYN-скан исторически называли «полуоткрытым»?
Почему активная детекция версии в nmap (`-sV`) гораздо заметнее для IDS, чем простой захват баннера?
Упорядочь шаги, которые делает сканер, чтобы от IP-адреса прийти к названному сервису с версией:
- 1 Отправить зонд SYN на целевой порт
- 2 Прочитать ответ, чтобы классифицировать порт (открыт / закрыт / фильтруется)
- 3 На открытом порту прочитать баннер, если сервис его отдаёт
- 4 Если баннер отсутствует или неоднозначен, отправить сформированные зонды детекции версии
- 5 Сопоставить паттерн ответа с базой сигнатур, чтобы назвать версию
- 01Объясни, как SYN-сканирование портов работает на уровне TCP, что означают три состояния порта и почему SYN-скан тише connect-скана.
- 02Сравни захват баннера и активную детекцию версии и опиши, что видит защитник при сканировании и как он сокращает раскрытие.
Сканирование портов — это трёхэтапное рукопожатие TCP, превращённое в допрос: сканер шлёт SYN, и один лишь ответ классифицирует порт — SYN-ACK это открыт, RST это закрыт, а тишина это фильтруется (файрвол отбрасывает зонд). SYN-скан по умолчанию («полуоткрытый») сбрасывает соединение до завершения рукопожатия, исторически тише на уровне приложения, чем connect-скан, который завершает полное рукопожатие и попадает в логи приложения. Найти открытый порт — лишь половина дела; превратить его в названный сервис с версией — это фингерпринтинг: дёшево через захват баннера, где сервис сам отдаёт свою идентичность, и точнее, но куда громче через активную детекцию версии, которая выстреливает сформированными зондами и сопоставляет сигнатуры ответов (а по особенностям стека может вывести и ОС). Объединяющая зрелая мысль в том, что сканирование двусторонне: каждый зонд несёт твой IP-источник в логи файрвола и IDS защитника, где пороговые правила по различным портам на источник настроены срабатывать ровно на этот паттерн, — а аномальные зонды детекции версии громче ещё. Поэтому компромисс постоянен — быстро и точно это громко, тихо это медленно или частично, — и защитные ходы выпадают прямо из него: сжать поверхность атаки, чтобы зонды фильтровались, срезать баннеры, чтобы соединение не раскрывало ничего, и алертить на сигнатуру сканирования, чтобы разорвать цепочку поражения на её первой, самой дешёвой стадии. И всегда — только против систем, которые ты авторизован тестировать.
Практика
Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.
Что-то непонятно?
Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.
Примени это
Примени этот урок в реальном проекте.