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, он не обязан этого делать, и большинство стеков 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. Поскольку данный метод является приближённым, то некоторого перебора избежать не получится, однако математическое моделирование позволяет на много порядков (с ~ до ~) сократить количество пакетов, необходимых атакующему, чтобы провести удачную атаку.
Подмена окна
Однако, не всегда бывает возможным провести предварительную математическую оценку значений ISN. Также, в некоторых случаях значение выбирается более-менее времянезависимым, и, следовательно, математическая оценка бывает затруднена или невозможна. В таком случае приходится прибегать к более грубым методам как перебор всевозможных значений этих параметров. Однако, при внимательном изучении стандарта RFC 793, ситуация несколько упрощается.
Первое, что следует упомянуть — это механизм окон в TCP протоколе. Пакеты при распространении по Интернету могут обгонять друг друга. Чтобы не потерять прибывшие раньше предшественников пакеты, получатель устанавливает так называемое окно, в котором он может восстановить порядок пакетов. Таким образом, если значение поля Sequence Number лежит внутри окна получателя, протокол TCP примет и обработает этот пакет. Это значительно уменьшает количество попыток, которые придется сделать атакующему: оно уменьшается с до .
В зависимости от операционной системы, размер окна может варьироваться от байт (Windows XP с SP2) и 5840 байт (Linux kernel 2.4 и 2.6).
Окно уменьшит количество sequence number, которое необходимо использовать атакующему. В случае Windows XP это число опускается до . Другими словами, атакующему придётся сгенерировать только атакующих пакетов, чтобы инъектировать RST-пакет и, таким образом, обрушить соединение. Это очень маленькое число.
Всё становится ещё хуже, если участники соединения поддерживают изменяемый размер окна. Эта функция TCP увеличивает вероятность нахождения подходящего sequence number за короткое время. Изменение размера окна предназначено для соединений, которым требуется большее окно из-за больших задержек или занятой полосы пропускания. Чтобы позволить всем передавать без наложений, эта технология расширяет размерность окна до 14 бит (Microsoft Windows), то есть до .
Однако, атакующему придётся преодолеть ещё одно препятствие: указать IP-адреса и порты отправителя и получателя. IP-адрес вряд ли является проблемой — атакующий обычно знает, на кого он нацеливается; также легко определяется порт получателя. Немного труднее определить порт отправителя, который теоретически может лежать в диапазоне от 0 до 65535. На практике же порты ниже 1024 и выше порога, определяемого операционной системой, зарезервированы для специальных задач.
Linux с версией ядра 2.4 или 2.6 использует в качестве порта отправителя числа от до . Остальные вариантов распределены не случайным образом; ядро распределяет их по конкретной схеме. Таким образом, у атакующего не возникнет особых проблем с предсказанием порта отправителя. Существует лишь несколько исключений, например, OpenBSD, которая распределяет их произвольным образом. Например, Windows XP начинает с порта для первого соединения, и увеличивает порт на 1 для каждого последующего. Linux (Fedora Core 3 с ядром 2.6.9 в частности) с опять-таки увеличивает по порядку. Системы Cisco увеличивают значение порта на 512 для каждого нового соединения, но это не делает механизм безопаснее.
Атакующему не нужно угадывать номер порта, если известно количество соединений на машине жертвы. Всё, что обычно необходимо сделать атакующему — начать с первого значения и перепробовать, скажем, 50 портов. Также для атакующего не представляет сложности узнать операционную систему жертвы. Так что, по сути, определение порта не является серьёзным препятствием.