Атака сброса TCP — TCP reset attack
Атака сброса TCP, также известная как «поддельные сбросы TCP», «поддельные пакеты сброса TCP» или «Атаки сброса TCP» — это способ подделать и разорвать Интернет-соединение, отправив поддельный пакет сброса TCP. Этот метод взлома может использоваться брандмауэром по доброй воле или использоваться злоумышленником для прерывания интернет-соединений.
Великий брандмауэр Китая и иранские интернет-цензоры, как известно, используют атаки сброса TCP, чтобы мешать и блокировать соединения, в качестве основного метода проведения интернет-цензуры.
- 1 Предпосылки
- 2 Сброс TCP
- 3 Формирование сброса TCP
- 4 Законное использование инъекции сброса TCP
- 5 Противоречие
- 6 Предотвращение
- 7 См. Также
- 8 Ссылки
- 9 Внешние ссылки
Предпосылки
Интернет, по сути, представляет собой систему для индивидуальных компьютеров для обмена электронными сообщениями или пакетами IP-данных. Эта система включает оборудование для передачи сообщений (например, медный кабель и оптоволоконный кабель ) и формализованную систему форматирования сообщений, называемую «протоколами». Основным протоколом, используемым в Интернете, является IP (Internet Protocol ), который обычно сочетается с дополнительными протоколами, такими как TCP (Transmission Control Protocol ) или UDP (User Datagram Протокол ). TCP / IP — это протокол, используемый для электронной почты и просмотра веб-страниц. Каждый протокол имеет блок информации, называемый заголовком, который находится в начале каждого пакета. Заголовки содержат информацию о том, какой компьютер отправил пакет, какой компьютер должен его получить, размер пакета и т. Д.
TCP используется с IP, когда между двумя компьютерами требуется двустороннее виртуальное соединение. (UDP, с другой стороны, представляет собой IP-протокол без установления соединения.) Программное обеспечение TCP на двух машинах, которые будут взаимодействовать (например, рабочая станция с браузером и веб-сервером) путем обмена потоком пакетов. Использование TCP-соединения дает компьютерам простой способ обмениваться элементами данных, слишком большими для одного пакета, такими как видеоклипы, вложения электронной почты или музыкальные файлы. Хотя некоторые веб-страницы достаточно малы для размещения одного пакета, для удобства они отправляются через TCP-соединения.
TCP сбрасывает
В потоке пакетов TCP-соединения каждый пакет содержит TCP-заголовок. Каждый из этих заголовков содержит бит, известный как флаг «сброса» (RST). В большинстве пакетов этот бит установлен в 0 и не действует; однако, если этот бит установлен в 1, он указывает принимающему компьютеру, что компьютер должен немедленно прекратить использование TCP-соединения; он не должен отправлять больше пакетов, используя идентификационные номера соединения, вызываемые порты, и отбрасывать любые дальнейшие пакеты, которые он получает с заголовками, указывающими, что они принадлежат этому соединению. Сброс TCP в основном мгновенно уничтожает TCP-соединение.
При использовании по назначению это может быть полезным инструментом. Одним из распространенных приложений является сценарий, когда компьютер (компьютер A) выходит из строя во время выполнения TCP-соединения. Компьютер на другом конце (компьютер B) продолжит отправлять TCP-пакеты, поскольку он не знает, что компьютер A потерпел крах. Когда компьютер A перезагружается, он будет получать пакеты от старого соединения, которое было до сбоя. Компьютер A не имеет контекста для этих пакетов и не знает, что с ними делать, поэтому он может отправить сброс TCP на компьютер B. Этот сброс позволяет компьютеру B узнать, что соединение больше не работает. Теперь пользователь компьютера B может попробовать другое соединение или предпринять другие действия.
Формирование сброса TCP
В приведенном выше сценарии бит сброса TCP был отправлен компьютером, который был одной из конечных точек соединения. Третий компьютер может отслеживать TCP-пакеты в соединении и затем отправлять «поддельный» пакет, содержащий сброс TCP на одну или обе конечные точки. Заголовки в поддельном пакете должны ложно указывать на то, что он пришел от конечной точки, а не от фальсификатора. Эта информация включает IP-адреса конечных точек и номера портов. Каждое поле в заголовках IP и TCP должно быть установлено на убедительное поддельное значение, чтобы фальшивый сброс заставил конечную точку закрыть TCP-соединение. Правильно отформатированные поддельные сбросы TCP могут быть очень эффективным способом разорвать любое TCP-соединение, которое может отслеживать фальсификатор.
Законное использование инъекции сброса TCP
Одно из очевидных применений поддельного сброса TCP — злонамеренное прерывание TCP-соединений без согласия двух сторон, владеющих конечными точками. Однако также были разработаны системы сетевой безопасности, использующие поддельные сбросы TCP. В 1995 году был продемонстрирован прототип программного пакета «Buster», который отправлял поддельные сбросы на любое TCP-соединение, которое использовало номера портов из краткого списка. Добровольцы Linux предложили сделать что-то подобное с брандмауэрами Linux в 2000 году, а в проекте с открытым исходным кодом Snort использовались сбросы TCP для прерывания подозрительных соединений еще в 2003 году.
IETF рассмотрел сброс TCP с помощью брандмауэров, загрузка -балансировщики и веб-серверы вредны в RFC3360.
Comcast Controversy
К концу 2007 года Comcast начал использовать поддельные сбросы TCP, чтобы нанести вред одноранговой сети и определенному групповому ПО приложения на компьютерах клиентов. Это вызвало споры, за которыми последовало создание группы сетевого нейтралитета (NNSquad) Лорен Вайнштейн, Винт Серф, Дэвид Фарбер, Крейг Ньюмарк и другие известные основатели и поборники открытости в Интернете. В 2008 году NNSquad выпустила NNSquad Network Measurement Agent, программу для Windows, написанную компанией, которая могла обнаруживать поддельные сбросы TCP Comcast и отличать их от реальных сбросов, генерируемых конечной точкой. Технология обнаружения сбросов была разработана на основе более раннего программного обеспечения «Buster» с открытым исходным кодом, которое использовало поддельные сбросы для блокировки вредоносных программ и рекламы на веб-страницах.
В январе 2008 года FCC объявила, что расследует использование Comcast поддельных сбросов, а 21 августа 2008 года приказала Comcast прекратить эту практику.
Предотвращение
Шифруя соединения с помощью VPN, злоумышленник должен провести атаку сброса TCP на все зашифрованные соединения, вызывая сопутствующий ущерб.
См. Также
Ссылки
Внешние ссылки
- Официальный сайт SNORT
- Отчет EFF об использовании Comcast сброса
- ICMP-атак против TCP. Подобные атаки с использованием ICMP
- Повышение устойчивости TCP к слепым атакам в окне
What is a TCP Reset (RST)?
When an unexpected TCP packet arrives at a host, that host usually responds by sending a reset packet back on the same connection. A reset packet is simply one with no payload and with the RST bit set in the TCP header flags.
There are a few circumstances in which a TCP packet might not be expected; the two most common are:
- The packet is an initial SYN packet trying to establish a connection to a server port on which no process is listening.
- The packet arrives on a TCP connection that was previously established, but the local application already closed its socket or exited and the OS closed the socket.
Other circumstances are possible, but are unlikely outside of malicious behavior such as attempts to hijack a TCP connection.
TCP-протокол и странные FIN,ACK,RST. Вопросы.
Нормально закрывать TCP-коннект между А и Б по инициативе А так:
- А шлёт FIN («я всё сказал»)
- Б шлёт FIN + ACK («вас понял, я тоже всё»)
- А шлёт ACK («вас понял»).
Три вопроса вопроса:
- Непонятно, зачем посылать FIN на шаге (1), когда можно послать RST и забыть обо всём. Видимо это не экологично: потеря RST приведёт к сохранению коннекта на Б, в сценарии выше (1) можно повторить, если долго не будет (2)?
- А есть какая-то другая причина, почему после (1) коннекшн ещё остаётся? Может ли Б после получения FIN что-то PUSH в этот коннекшн? Но это бессмысленно, софтина на А уже вызвала close() на сокете.
- Проводил эксперимент:
- A — C++ сервер вида «socket();setsetsockopt();bind();listen(port 12345);accept();». Также, в этом сервере написано «По приходу чего-нибудь в коннект, вычитать всё через read() и сразу сделать close(socket)»;
- Б: «nc 127.0.0.1 12345»
- Б что-то PUSH в коннекшн (печатаю в nc рандомную строку, жму enter), A это вычитывает из сокета и делает сразу close(socket);
- В tcpdump видно, как от А к Б прилетает FIN + ACK. Зачем тут ACK? ACK на PUSH прилетело пакетом ранее….
- В ответ на FIN от Б прилетает один ACK, как будто nc не собирается закрывать. Всмысле? Какой смысл тут не хотеть закрывать?
- Ввожу в nc ещё одну строку, отправляю (от Б летит PUSH + ACK). Зачем тут опять ack?
- От A приходит RST. Это уже выглядит как «слыш ты кто»?
tcpfinhello
17.04.21 20:37:57 MSK
когда можно послать RST и забыть обо всём.
Можно и дверью хлопнуть, но, так ведь о отлететь что-то может. А 4 или 3-way handshake для «gracefully» shutdown.
А есть какая-то другая причина, почему после (1) коннекшн ещё остаётся?
Чтобы дождаться последних данных от клиента и его ответного «я всё сказал».
Но это бессмысленно, софтина на А уже вызвала close() на сокете.
Есть shutdown() с SHUT_WR .
gag ★★★★★
( 17.04.21 21:27:38 MSK )
Непонятно, зачем посылать FIN на шаге (1), когда можно послать RST и забыть обо всём.
Ну вот представь, что с той стороны тебе шлют RST, а ты как раз в сокет пишешь. Хренак, SIGPIPE, ты мертв.
Еще вопросы остались?
t184256 ★★★★★
( 17.04.21 21:31:11 MSK )
Пакеты идут по сети в рандомном порядке и в нем же [не]приходят. Close/rst означает выкинуть все нахрен, что ОС и делает, включая буферы невычитанные процессом или неотправленные в железо, на обеих сторонах. В случае потери пакета ретрансляции также не будет. На loopback ты такого не увидишь.
Поэтому все не выпендриваются и делают грейсфул шатдаун.
anonymous
( 18.04.21 10:50:42 MSK )
бессмысленно, софтина на А уже вызвала close() на сокете.
Ну это этой софтины проблемы. Нормальные люди ждут результата SHUT_WR (блоком или в фоне) и только потом клозят, хотя у линукса есть свои загоны по этому поводу.
anonymous
( 18.04.21 10:54:50 MSK )
Ответ на: комментарий от anonymous 18.04.21 10:54:50 MSK
Нормальные люди ждут результата SHUT_WR (блоком или в фоне) и только потом клозят,
Непонятно. Я хочу закрыть соединение в приложении, я могу вызывать только close(). Я не могу вызвать i_wait_close();
hellonik
( 18.04.21 16:56:34 MSK )
а если надо заново создать соединение то тебя шлют
doc0 ★
( 18.04.21 21:08:25 MSK )
Последнее исправление: doc0 18.04.21 21:19:49 MSK (всего исправлений: 1)
Ответ на: комментарий от t184256 17.04.21 21:31:11 MSK
SIGPIPE может прилететь и от того что кто-то рубанул свет в датацентре. Те, кто не обрабаытают SIGPIPE (или читают без MSG_NOSIGNAL) — обмылки и для них есть отдельный котел.
PPP328 ★★★★★
( 18.04.21 21:29:03 MSK )
тут мне кажется задействовано много устройств и чем они более информированы в ситуации тем лучше работает вся сеть
doc0 ★
( 18.04.21 21:33:01 MSK )
Ответ на: комментарий от t184256 17.04.21 21:31:11 MSK
будто этот кейс обрабатывать не надо.
deep-purple ★★★★★
( 18.04.21 22:05:59 MSK )
Последнее исправление: deep-purple 18.04.21 22:06:09 MSK (всего исправлений: 1)
Ответ на: комментарий от PPP328 18.04.21 21:29:03 MSK
По соседству с теми, кто шлет RST сразу за данными в штатной ситуации в асинхронных протоколах.
t184256 ★★★★★
( 18.04.21 23:46:14 MSK )
Ответ на: комментарий от hellonik 18.04.21 16:56:34 MSK
Потому что close() это аналог free() для сокета. С точки зрения юзерленда он не закрывает сокет, а просто выкидывает его, и для этого не надо ничего ждать (но см. нюанс ниже).
Чтобы нормально закрыть сокет надо помнить, что это дуплекс-канал, а не односторонний или файл, и закрытий не одно, а два. Чтобы не скипать полную логику, рассмотрим полностью асинхронное двустороннее общение, т.е. не запрос-ответ, а что-то вроде чата.
- открылся
- читаешь-пишешь as usual
- если ты решил закрыться
- посылаешь FIN (shutdown(SHUT_WR))
- больше ничего не пишешь
- но пир все еще может считать, что не договорил
- как и его ядро при потерях
- он шлет FIN
- получаешь read() == 0
- больше не читаешь
- дописываешь все, что хотел, as usual
- посылаешь FIN (так же)
- теперь можно выкинуть (close())
Вы оба проходите TCP стейты FIN-WAIT-1, CLOSE-WAIT, FIN-WAIT-2, LAST-ACK, TIME-WAIT, CLOSING, скипая некоторые, в зависимости от рейсов, кто быстрее закрыл, и какие пакеты где задержались. Если закрыть сокет не дожидаясь, ядро просто шлет RST, и там уже кто не успел, тот опоздал.
Поскольку хопы между вами могут терять любые пакеты, гарантированного общения/подтверждения нет, и в ядре все держится на таймаутах, после которых общение гарантированно не имеет смысла. Но для вас это выглядит как блокирующие вызовы read/write (или нонблок аналоги), -1/SIGPIPE, явный EOF (FIN/SHUT_WR/read 0) и «просто» close().
Последний тоже может быть блокирующим, но это афаир как раз прикол для тех, кто не осилил грейсфул, или на уровне соглашения работает запрос-ответом — при включенном SO_LINGER close() сначала дождется отправки и подтверждения прошлых write() и только потом пошлет FIN и дропнет сокет. Иначе неотправленное просто выкинется. То есть это такой graceful_close() для бедных.
Из-за асинхронки пиров/сети, разных стейтов соединения во времени, того что write() разблокируется не по ACK, а просто по факту отправки, возникает куча нюансов, которые я сам не до конца понимаю, поэтому если хочешь вкурить, то выдели месяц-другой, не меньше. Кроме того, разные стеки ведут себя по-разному, и тут два слоя понимания: что происходит в самом стеке, и как системные вызовы/возвраты мапятся на события в нем. Но с точки зрения юзерленда схема выше это текстбук мастхев, если ты в фуллдуплексе.
Если ты строго в запрос-ответе, то наверное можно опираться на лингер, но лично я такое ни разу не писал и не тестил, не могу комментировать. Кроме того, в лингере ты отчасти живешь в фулл-блок режиме на запись со стороны отдающего ответ, а это ну сам понимаешь уровень хелло ворлда на коленке, а не реального сервера.
TCP Reset (TCP RST ACK) — что это и как искать причину?
Каждый TCP пакет несёт заголовок и в нем есть биты завершения соединения:
- FIN – все данные переданы успешно, получены все подтверждения и соединение завершается логичным способом;
- RST — обычно этот бит установлен в «0» и ничего не значит. Но иногда он получает значение 1 и это ведет к немедленному прекращению данного соединения.
Хорошо это или плохо, так как красный сигнал не предвещает ничего хорошего? Все, конечно же, зависит от ситуации, когда они происходят.
TCP RST ACK – это нормальный и предусмотренный RFC 793 процесс разрыва соединения, но если их много и это оказывает влияние на производительность приложения и пользователей, то это бесспорно повод задуматься. Как всегда дьявол кроется в деталях и необходимо задать себе несколько вопросов.
В каком месте общения между устройствами происходит TCP Reset?
Нажимаем Analyze – Conversation Filter — IPv4. Если TCP IP Reset отправлен одной из сторон после обмена данными, то надо проверять настройки оборудования. Например, данные отправлены, но соединение держится в открытом состоянии и по прошествии какого-то времени — посылается TCP RST. И это не является проблемой.
Если TCP Reset происходит в начале соединения, то это тоже не проблема для пользователя. На примере ниже мы запрашиваем файл с облака, но его уже там нет. Поэтому клиент дважды попытался его получить и оба раза сервер ответил TCP IP Reset.
Если TCP Reset происходит в середине процесса передачи данных, то потребуется дополнительный анализ, так как это может быть проблема на сервере, в приложении или даже клиенте. Пользователь запросил данные через браузер и затем закрыл его, не дожидаясь ответа. В данном случае будет однозначно отправлен TCP Reset.
Почему TCP RST отправлен сразу после SYN?
Причин может быть также несколько. Обычно это означает, что порт, по которому пытаются открыть соединение, недоступен. Сервер отключен, сервер занят или такой порт закрыт. Поэтому происходит сброс SYN и все.
Кто отправил TCP RST ACK?
Важно также понимать кто инициатор разрыва соединения. Клиент, сервер, сетевое оборудование внутри собственной инфраструктуры или на пути от провайдера (см. TTL, а также IP адрес отправителя). На все эти вопросы мы можем получить ответ, анализируя трафик с помощью анализатора протоколов.
См. также:
- Какие параметры и как измеряются при анализе производительности сервисов и приложений?
- Как правильно подключиться к сети для захвата трафика? Часть 1. Захват трафика на стороне клиента или сервера
- Wireshark за 8 шагов: от установки программы до перехвата и анализа трафика