TCP hijacking

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск

TCP Hijacking — Разновидность атаки «Человек посередине», когда атакующий способен просматривать пакеты участников сети и посылать свои собственные пакеты в сеть. Атака использует особенности установления соединения в протоколе TCP, и может осуществляться как во время «тройного рукопожатия», так и при установленном соединении.

Проблема возможной подмены TCP-сообщения важна, так как анализ протоколов FTP и TELNET, реализованных на базе протокола TCP, показал, что проблема идентификации FTP и TELNET-пакетов целиком возлагается данными протоколами на транспортный уровень, то есть на TCP.

Установка TCP соединения[править | править вики-текст]

Для идентификации TCP-пакета в TCP-заголовке существуют два 32-разрядных идентификатора, которые также играют роль счётчика пакетов — Sequence Number и Acknowledgment Number. В случае, если хост A хочет установить TCP-соединение с хостом B, происходит т. н. «тройное рукопожатие», в процессе которого хосты обмениваются следующими пакетами:

  • хост A посылает хосту B пакет с установленным битом SYN и 32-битным значением ISSa в поле Sequence Number
  • хост B отвечает хосту A пакетом с установленными битами SYN и ACK, 32-битным значением ISSb в поле Sequence Number, и значением (ISSa+1) в поле ACK
  • хост A отвечает хосту B пакетом с установленным битом ACK, значением (ISSa+1) в поле Sequence Number, и значением (ISSb+1) в поле ACK.

На этом пакете завершается установка соединения, поэтому в следующем пакете хост A передает хосту B полезную информацию

  • хост A отвечает хосту B пакетом с установленным битом ACK, значением (ISSa+1) в поле Sequence Number, и значением (ISSb+1) в поле ACK. В этом пакете включена вся полезная информация.

Принцип атаки[править | править вики-текст]

Рассмотрев схему установки соединения, описанную выше, можно заметить, что единственными идентификаторами, по которым конечный хост может различать TCP-абонентов и TCP-соединения, являются поля Sequence Number и Acknowledge Number. Таким образом, если атакующий определит значения ISSa и ISSb для данного соединения, то он сможет сформировать ложный TCP-пакет, который будет воспринят и обработан конечным хостом.

Один из видов атаки подразумевает, что атакующий встраивает в TCP-пакет контрольный бит RST (Reset). Согласно стандарту RFC 793, этот флаг говорит хосту-мишени сбросить соединение без каких-либо дальнейших взаимодействий. По полю Sequence Number хост-мишень определяет, обрабатывать или игнорировать команду сброса, причём мишени запрещено посылать ответ с установленным битом RST. Важно заметить, что хост-мишень проверяет подлинность RST запроса только по Sequence Number, и закрывает соединение, если оно попадает в текущее TCP окно. И, несмотря на то, что хост-мишень может рассчитать acknowledgment number, он не обязан этого делать, и, как обнаружил Paul Watson, большинство стеков TCP просто игнорируют этот шаг.

Принятый RST пакет всегда приведет к завершению соединения. Соединения, рассчитанные на длительное время, например BGP-соединения между роутерами, чрезвычайно уязвимы к таким атакам. Прежде всего, у нападающего будет достаточно времени для внедрения аккуратно спланированного пакета, и, с другой стороны, огромные потери вызовет DoS. Роутерам приходится перенастраивать таблицу соседей, что может занять несколько минут в реальных условиях.

Менее очевиден факт, что флаг SYN также может обрушить соединение. Согласно RFC 793, когда флаг SYN устанавливается при установке соединения, поле Sequence Number содержит начальное значение, которое будет использовано в дальнейшем. Если впоследствии по этому соединению будет принят SYN пакет, RFC 793 будет трактовать это как ошибку. Вследствие чего получателю придется отменить соединение путём посылки RST пакета. В отличие от RST пакета, хост ответит на SYN пакет отправкой RST пакета. Это открывает возможность ещё одной DoS атаки. Атакующий впоследствии может использовать полосу пропускания жертвы. Эта атака особо успешна в ADSL линиях.

В то время как RST и SYN атаки не используют полезную нагрузку IP-датаграммы, третья технология встраивает данные в существующее соединение. Атакующий может вставить любые данные которые приведут к разрыву соединения, или аккуратно сформировать данные, которые приведут к состоянию ошибки, либо же будут выполнять какую-либо функцию во благо атакующего. Жертва может даже не заметить этих манипуляций. К примеру, протоколы FTP и TelNET не проверяют IP-адрес отправителя, и следовательно при успешном формировании ложного TCP-запроса ответят на реальный IP-адрес атакующего, что позволит полностью перехватить соединение.

Итак, для осуществления атаки необходимо знать два параметра TCP-соединения. В случае, если атакующий может непосредственно прослушивать канал связи между хостами A и B, эти параметры определяются простым анализом трафика. В противном же случае приходится прибегать к более сложным методам.

Математическая оценка параметра ISN[править | править вики-текст]

Данный метод основывается на предположении, что выбор исходных параметров ISSa и ISSb (так называемого ISN — Initial Sequence Number) при установлении соединения некоторым образом зависит от времени. Наилучшим с точки зрения безопасности был бы выбор ISN абсолютно произвольным, что сделало бы предсказывание практически неприменимым, однако, в описании протокола TCP в RFC 793 рекомендуется увеличивать значение этого счётчика на 1 каждые 4 микросекунды, что делает предсказание этого значения тривиальным. На практике, анализ исходного кода старых ядер Linux’а, а также поведения операционной системы Windows NT 4.0 и младше подтверждают функциональную зависимость выбираемого значения ISN от времени.

В общем случае, при существовании такой зависимости, она будет выражаться некоторой формулой вида ISN = F(mcsec), где mcsec — количество микросекунд по аппаратным часам исследуемой операционной системы.

Таким образом, атакующему необходимо провести некоторый анализ функции зависимости назначаемого значения ISN от времени. Для этого в исследуемую сетевую ОС передается серия обычных запросов на создание TCP-соединения и принимается соответствующие количество ответов с текущими значениями ISN операционной системы в каждый момент времени. При этом замеряются временные интервалы (в микросекундах) прихода ответов на запросы. Построив таблицу зависимости полученных ISN от времени t, прошедшего с начала эксперимента, и аппроксимировав её любыми математическими инструментами, получим с погрешностью, сравнимой с погрешностью исходных данных, непрерывную функцию изменения ISN от t, справедливую на данном временном промежутке: ISN(t) = F(t);

Эта формула даст нам возможность по предыдущему значению ISN, измерив время, прошедшее с его назначения, получить актуальное на данный момент времени значение ISN.

В дальнейшем, атакующему остаётся лишь следить за поведением исследуемых хостов, и, вычислив момент создания соединения, примерно оценить диапазон значений выбранных хостами значений ISSa и ISSb. Поскольку данный метод является приближённым, то некоторого перебора избежать не получится, однако математическое моделирование позволяет на много порядков (с ~~2^{64} до ~~100^2) сократить количество пакетов, необходимых атакующему, чтобы провести удачную атаку.

Подмена окна[править | править вики-текст]

Однако, не всегда бывает возможным провести предварительную математическую оценку значений ISN. Также, в некоторых случаях значение выбирается более-менее времянезависимым, и, следовательно, математическая оценка бывает затруднена или невозможна. В таком случае приходится прибегать к более грубым методам как перебор всевозможных значений этих параметров. Однако, при внимательном изучении стандарта RFC 793, ситуация несколько упрощается.

Первое, что следует упомянуть — это механизм окон в TCP протоколе. Пакеты при распространении по Интернету могут обгонять друг друга. Чтобы не потерять прибывшие раньше предшественников пакеты, получатель устанавливает так называемое окно, в котором он может восстановить порядок пакетов. Таким образом, если значение поля Sequence Number лежит внутри окна получателя, протокол TCP примет и обработает этот пакет. Это значительно уменьшает количество попыток, которые придется сделать атакующему: оно уменьшается с ~2^{32} до ~2^{32} / window size.

В зависимости от операционной системы, размер окна может варьироваться от ~65535 байт (Windows XP с SP2) и 5840 байт (Linux kernel 2.4 и 2.6).

Окно уменьшит количество sequence number, которое необходимо использовать атакующему. В случае Windows XP это число опускается до ~65000. Другими словами, атакующему придётся сгенерировать только ~65000 атакующих пакетов, чтобы инъектировать RST пакет и, таким образом, обрушить соединение. Это очень маленькое число.

Всё становится ещё хуже, если участники соединения поддерживают изменяемый размер окна. Эта функция TCP увеличивает вероятность нахождения подходящего sequence number за короткое время. Изменение размера окна предназначено для соединений, которым требуется большее окно из-за больших задержек или занятой полосы пропускания. Чтобы позволить всем передавать без наложений, эта технология расширяет размерность окна до 14 бит (Microsoft Windows), то есть до ~16384.

Однако, атакующему придется преодолеть ещё одно препятствие: четвёрку IP-адрес/порт отправителя и получателя. IP адрес вряд ли является проблемой — атакующий обычно знает, на кого он нацеливается; также легко определяется порт получателя. Немного труднее определить порт отправителя, который теоретически может лежать в диапазоне от 0 до 65535. На практике же порты ниже 1024 и выше порога, определяемого операционной системой, зарезервированы для специальных задач.

Linux с версией ядра 2.4 или 2.6 использует в качестве порта отправителя числа от ~32768 до ~61000.

К удовольствию атакующего, остальные ~28232 вариантов распределены не случайным образом; ядро распределяет их по конкретной схеме. Таким образом, у атакующего не возникнет особых проблем с предсказанием порта отправителя. Существует лишь несколько исключений, например, OpenBSD, которая распределяет их произвольным образом. Например, Windows XP начинает с порта ~1050 для первого соединения, и увеличивает порт на 1 для каждого последующего. Linux (Fedora Core 3 с ядром 2.6.9 в частности) с ~32768 опять-таки увеличивает по порядку. Системы Cisco увеличивают значение порта на 512 для каждого нового соединения, но это не делает механизм безопаснее.

Атакующему не нужно угадывать номер порта, если известно количество соединений на машине жертвы. Всё, что обычно необходимо сделать атакующему — начать с первого значения и перепробовать, скажем, 50 портов. Также для атакующего не представляет сложности узнать операционную систему жертвы. Так что, по сути, определение порта не является серьёзным препятствием.