Полгода назад на внутреннем пентесте мы перехватили TCP-сессию между сервером мониторинга и управляющей консолью - sequence number оказался предсказуемым, RST-инъекция сработала с первого пакета. Двенадцать минут от обнаружения открытого порта до разрыва чужого соединения и подстановки своих данных. Коллега-джуниор наблюдал в Wireshark и не мог понять, что происходит: он знал, что TCP - «надёжный протокол», но не представлял, как устроены флаги и рукопожатие на уровне отдельных битов. Эта статья - разбор TCP/IP стека протоколов для хакера так, как я объясняю его на воркшопах: не через академические модели, а через конкретные атаки и то, что видно в дампе трафика.
Разбор стека протоколов TCP/IP глазами атакующего
Модель OSI с семью уровнями хороша для отчётов заказчику, но реальные сети работают на стеке TCP/IP с четырьмя уровнями: Link (L2), Internet (L3), Transport (L4), Application (L7). Для пентестера каждый уровень - отдельная поверхность атаки со своим инструментарием и ограничениями.На канальном уровне (L2) работают ARP-спуфинг и MAC-flooding - строго внутри одного broadcast-домена. На сетевом (L3) - IP-спуфинг, ICMP-redirect, фрагментация пакетов. На транспортном (L4) - манипуляции TCP-флагами, SYN flood, session hijacking. На прикладном (L7) - SQL-инъекции, перехват HTTP-сессий, banner grabbing. Один и тот же пентестер за час может работать на трёх разных уровнях - и каждый раз ограничения будут разными.
Место TCP-атак в цепочке kill chain определяется задачей:
- Reconnaissance - сканирование портов через TCP-флаги (Scanning IP Blocks, T1595.001, Reconnaissance по MITRE ATT&CK). Определяем открытые сервисы, версии ОС, наличие firewall между нами и целью.
- Initial Access - эксплуатация обнаруженных сервисов: от banner grabbing до подключения к незащищённым портам. Типичные цели - стандартные порты: HTTP (80/443), FTP (21), SSH (22), SMTP (25), MySQL (3306).
- Impact - SYN flood как denial-of-service, RST-инъекция для разрыва легитимных соединений.
Трёхстороннее рукопожатие TCP: механика и точки входа
TCP устанавливает соединение через три пакета с определёнными комбинациями флагов:- SYN - клиент шлёт пакет с флагом SYN и начальным sequence number (ISN): «Хочу подключиться, мой seq = X».
- SYN-ACK - сервер отвечает пакетом с флагами SYN и ACK, подтверждая запрос и указывая свой ISN: «Принял, мой seq = Y, ack = X+1».
- ACK - клиент подтверждает: «ack = Y+1, соединение установлено».
Уязвимость рукопожатия в том, что сервер после получения SYN выделяет ресурсы на полуоткрытое соединение (состояние SYN_RECEIVED) ещё до завершения handshake. Запись в SYN-очереди висит десятки секунд (зависит от
[URL='https://www.kernel.org/doc/html/latest/networking/ip-sysctl.html']tcp_synack_retries[/URL]; в современном Linux ~31с при дефолтном значении 5), ожидая финального ACK. Именно эту механику эксплуатирует SYN flood.Второй вектор - предсказуемость ISN. В устаревших реализациях TCP-стека начальные sequence numbers генерировались линейно или с предсказуемым инкрементом. Атакующий мог предсказать ISN удалённого хоста и инжектировать пакеты в чужую сессию, не видя ответных пакетов - blind TCP injection. Современные ОС вычисляют ISN как криптографический хеш от source/dest IP+port и секретного ключа (RFC 6528), что убивает blind prediction. Но legacy-системы в промышленных сетях и встраиваемых устройствах до сих пор уязвимы - и я такие встречал. [Применимо: внутренний пентест, legacy-инфраструктура, SCADA/ICS.]
SYN-скан: неполное рукопожатие как инструмент разведки
SYN-скан в Nmap (nmap -sS) - первое, что запускаешь на новом проекте. Механика: отправляется SYN, анализируется ответ, немедленно шлётся RST - рукопожатие не завершается. Три варианта ответа определяют состояние порта:- SYN-ACK - порт открыт, сервис слушает.
- RST - порт закрыт, ничего не слушает.
- Тишина (timeout) - порт фильтруется, firewall дропает пакет без ответа.
- ОС: Kali Linux (rolling release) или Debian/Ubuntu с Nmap 7.94+, Wireshark 4.0+, Scapy 2.5+
- RAM: от 4 ГБ для одной VM, 8 ГБ для связки Kali + Metasploitable 2
- Виртуализация: VirtualBox или VMware, сеть Host-Only или Internal Network
- Права: root/sudo (SYN-скан использует raw sockets)
- Интернет: не требуется
Bash:
# SYN-скан с определением версий сервисов
# Контекст: изолированная лаборатория, внутренний пентест
sudo nmap -sS -sV -p 21,22,80,443,445,3389 192.168.56.0/24
tcp.flags.syn == 1 && tcp.flags.ack == 0 - увидите каждый исходящий SYN от сканера. Фильтр tcp.flags.syn == 1 && tcp.flags.ack == 1 покажет SYN-ACK ответы от открытых портов. Соотнесите: строка open в Nmap = SYN-ACK в Wireshark, closed = RST, filtered = ни одного ответного пакета.SYN-скан требует root-привилегий. Без root Nmap переключается на TCP connect scan (
-sT), который завершает рукопожатие полностью - работает, но оставляет записи в логах целевого сервиса и заметнее для IDS. Для тех кто в танке - разница как между подглядыванием в замочную скважину и стуком в дверь.TCP флаги SYN ACK FIN RST: арсенал для разведки и атак
TCP-заголовок содержит шесть основных флагов - каждый занимает один бит:| Флаг | Назначение в протоколе | Использование атакующим |
|---|---|---|
| SYN | Инициация соединения | SYN-скан, SYN flood |
| ACK | Подтверждение приёма | ACK flood, ACK-скан для определения правил firewall |
| FIN | Корректное завершение | FIN-скан закрытых/открытых портов |
| RST | Принудительный разрыв | RST-инъекция, TCP Reset Attack |
| PSH | Немедленная доставка приложению | Маркер активного обмена данными |
| URG | Пометка срочных данных | XMAS-скан (в комбинации с FIN и PSH) |
По классификации из анализа ElastiFlow, атаки с манипуляцией TCP-флагами делятся на разведывательные (FIN/NULL/XMAS/ACK-сканирование) и деструктивные (SYN flood, ACK flood, RST-атака, SYN-ACK reflection).
FIN, NULL и XMAS: сканирование через нестандартные флаги
Все три типа сканирования эксплуатируют поведение TCP-стека по RFC 793: если закрытый порт получает пакет без флага SYN, RST или ACK - он отвечает RST. Открытый порт такой пакет молча игнорирует.FIN-скан (
nmap -sF) - пакет только с флагом FIN. Закрытый порт ответит RST, открытый промолчит.NULL-скан (
nmap -sN) - пакет вообще без установленных флагов. Невалидное состояние по стандарту TCP - пакет, что называется, «в чём мать родила». Реакция аналогична FIN-скану.XMAS-скан (
nmap -sX) - одновременно установлены FIN, PSH и URG. Название от аналогии: пакет «горит как новогодняя ёлка» - все три флага зажжены.Критическое ограничение: все три метода не работают против Windows. TCP-стек Windows отвечает RST на любые нестандартные пакеты вне зависимости от состояния порта. Все порты показываются как закрытые. Эти сканы полезны только против Unix/Linux-хостов. [Применимо: внешний/внутренний пентест, Linux/BSD-инфраструктура.]
Второе ограничение - stateful firewall. Любой современный firewall (от iptables с conntrack до Palo Alto) отслеживает состояние TCP-соединений. Пакет с FIN, не принадлежащий существующей сессии, будет дропнут. FIN/NULL/XMAS сканы работают только против stateless ACL - legacy Cisco ACL на маршрутизаторах без inspect. В современных средах эффективность стремится к нулю. [Применимо: legacy-инфраструктура, stateless ACL.]
ACK-скан (
nmap -sA) - отправляет пакет с установленным ACK. Не определяет открытые порты, но выявляет правила firewall: stateless ACL пропустит ACK, stateful - дропнет. Полезен для маппинга правил фильтрации на периметре. [Применимо: внешний пентест, определение типа firewall.]Атаки на TCP/IP стек: SYN flood, session hijacking, IP спуфинг
TCP SYN flood атака
SYN flood - классическая DoS-атака, эксплуатирующая механизм трёхстороннего рукопожатия. Атакующий генерирует массу SYN-пакетов с поддельными source IP. Сервер для каждого SYN выделяет запись в SYN-очереди и шлёт SYN-ACK на несуществующий адрес. Ответный ACK никогда не приходит, полуоткрытые соединения копятся до исчерпания ресурсов.Воспроизведение в Scapy (только в изолированной лаборатории):
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме
TCP session hijacking и IP спуфинг атаки
TCP session hijacking - перехват активной TCP-сессии. Атакующий инжектирует пакеты с корректными sequence/acknowledgment numbers, маскируясь под одного из участников.Что нужно для успешного hijacking:
- Знание sequence numbers текущей сессии - через перехват трафика (ARP-спуфинг на L2) или предсказание ISN (legacy-системы).
- IP спуфинг - возможность отправки пакетов с поддельным source IP.
- Отсутствие шифрования - TLS и SSH делают инъекцию payload бесполезной: данные зашифрованы, ключ сессии атакующему неизвестен.
- BCP38/RFC 2827 - большинство провайдеров фильтруют пакеты с source IP, не принадлежащим их адресному пространству (ingress filtering). Отправить пакет с произвольным source IP через провайдера с ingress filtering не выйдет.
- Рандомизация ISN во всех современных ОС убивает blind prediction.
- Для реального hijacking атакующий должен быть в позиции MitM - тот же сегмент сети, ARP-спуфинг. Тогда sequence numbers видны в реальном времени.
Анализ TCP пакетов в Wireshark: фильтры для пентеста
Wireshark - основной инструмент для верификации того, что происходит на уровне пакетов. Набор фильтров, которые я применяю при анализе дампов:Обнаружение SYN-сканирования:
tcp.flags.syn == 1 && tcp.flags.ack == 0 - все SYN-пакеты без ACK. Если с одного IP идут сотни таких пакетов на разные порты - это сканирование. Группировка по source IP через Statistics → Endpoints покажет масштаб.Обнаружение SYN flood: тот же фильтр, но группировка по source IP выявит тысячи уникальных адресов-отправителей. Соотношение SYN к SYN-ACK в нормальном трафике близко к 1:1. При flood - SYN пакетов на порядок больше.
XMAS-пакеты:
tcp.flags.fin == 1 && tcp.flags.push == 1 && tcp.flags.urg == 1 - одновременно FIN, PSH и URG. В легитимном трафике такая комбинация не встречается никогда. Если нашли - кто-то сканирует.NULL-сканирование:
tcp.flags == 0 - пакеты без единого установленного флага. Валидных TCP-пакетов с нулевыми флагами не существует в природе.RST-инъекция:
tcp.flags.reset == 1 - все RST-пакеты. Внезапный всплеск RST от хоста, который вёл нормальный обмен данными, - признак RST-атаки или TCP Reset Attack.Незавершённые рукопожатия:
tcp.flags.syn == 1 && !tcp.flags.ack - SYN без ответа SYN-ACK. Применив Follow TCP Stream к такому пакету, увидите, что сессия не состоялась - firewall дропнул или сервис недоступен.При анализе дампов с пентеста я всегда начинаю с Protocol Hierarchy (Statistics → Protocol Hierarchy). Аномальное количество TCP-пакетов без payload или с нестандартными комбинациями флагов - первый сигнал сканирования или атаки.
Сетевые атаки на транспортный уровень: слепые зоны IDS и stateful firewall
Современные IDS - Suricata, Snort 3.x, Zeek - детектируют большинство описанных атак. Но не все и не всегда.Что ловится надёжно:
- SYN flood - по аномальному соотношению SYN/SYN-ACK. Suricata и Snort содержат threshold-правила из коробки.
- XMAS и NULL сканирование - невалидные комбинации флагов ловятся сигнатурным анализом. Suricata:
alert tcp any any -> $HOME_NET any (msg:"XMAS Scan detected"; flags:FPU; classtype:attempted-recon; sid:1000001; rev:1;). - Массовый SYN-скан - сотни SYN на разные порты одного хоста за короткий интервал.
- Медленное сканирование. Nmap с
-T1(sneaky) или-T0(paranoid) растягивает сканирование на часы. Один SYN в 15 секунд не вызывает срабатывания threshold-правил, настроенных на всплески. Для выявления нужна корреляция на уровне SIEM (Elastic 8.x+, Splunk) с анализом событий за длинное окно. - Рандомизация порядка портов. Nmap по умолчанию рандомизирует порядок сканируемых портов. Последовательное сканирование (1, 2, 3, 4...) детектируется легче, чем хаотичное (443, 22, 8080, 3389...).
- Фрагментация (
nmap -f) - разбивает TCP-заголовок на несколько IP-фрагментов. Suricata и Snort 3.x собирают фрагменты корректно, но legacy-системы (Snort 2.x без обновлений) могут пропустить. [Применимо: обход legacy IDS.] - ACK-скан (
nmap -sA) - ACK-пакеты выглядят как часть существующего соединения. Stateless ACL пропускает. Stateful firewall дропнет, так как нет записи в таблице сессий. Сама IDS может не сгенерировать алерт, если ACK-пакеты не сопровождаются аномальным объёмом. - RST-инъекция - для IDS инжектированный RST с корректным sequence number неотличим от легитимного завершения сессии. Выявление возможно только через корреляцию: разрыв сессии + немедленное установление новой с того же source IP, но другим поведением. Это самая неприятная слепая зона - атака прячется в потоке нормального трафика.
Распространённый подход при изучении TCP/IP - начинать с модели OSI: заучивают семь уровней, рисуют диаграммы инкапсуляции и забывают через неделю. Это костыль для экзамена, не более. Понимание TCP/IP начинается в тот момент, когда открываешь Wireshark и руками разбираешь, почему конкретный SYN-ACK пришёл с определённым MSS, почему RST выглядит именно так, почему Nmap показал
filtered вместо closed. Я провёл больше тридцати воркшопов, и паттерн один: участники, которые начинали с Scapy и собирали TCP-пакет руками - через два часа понимали рукопожатие глубже, чем те, кто читал учебник два месяца.Неудобная правда: FIN/NULL/XMAS сканирование, которое красиво выглядит на CTF и в учебниках, в реальных сетях 2025 года почти мертво - stateful firewall убивает эти техники на корню. Но разбирать их всё равно нужно, потому что именно через них формируется мышление: «Какой бит я ставлю и что получу в ответ?» Это мышление потом спасает на реальном пентесте, когда инструмент отказывает, а ты открываешь Scapy и собираешь пакет вручную.
Попробуйте сами: поднимите Kali + Metasploitable 2 в изолированной сети, запустите
nmap -sX и параллельно смотрите дамп в Wireshark. Найдите XMAS-пакеты фильтром из раздела выше. Если получилось за три минуты - вы уже понимаете TCP-флаги лучше, чем половина выпускников ИБ-факультетов. Если хочется копнуть глубже и отработать эти техники на полноценных лабах - на WAPT в Codeby Academy есть модуль по сетевой разведке с живыми мишенями.