Кратко

  • RFC 1948 описал злоумышленника, который узнавал начальный номер настоящего соединения, подставлял адрес доверенного компьютера и угадывал следующую цифру сервера, чтобы закончить рукопожатие, ответа на которое он не видел.
  • Предложенная схема сохраняла ход часов M для повторных соединений той же четвёрки адресов и портов, но добавляла для каждой четвёрки секретное смещение F. Образец из одного разговора переставал служить линейкой для другого.

Сначала вор действовал как обычный посетитель: устанавливал TCP-соединение и записывал начальный номер, названный сервером. RFC 1948, опубликованный в мае 1996 года, показал, как эта запись помогала предсказать следующий номер. Затем злоумышленник выдавал себя за машину, чьему IP-адресу сервер доверял. Ответ сервера уходил настоящей машине и оставался невидимым для подражателя. Верно угаданный номер и молчание настоящей машины позволяли послать завершающее подтверждение. Служба удалённых команд, доверявшая адресу, принимала пакеты злоумышленника как пакеты знакомого.

Слабость возникала между двумя разговорами. Настоящее соединение показывало начальный номер последовательности, ISN. В производных от Berkeley реализациях, описанных в RFC, номер рос предсказуемыми шагами со временем и при каждом новом соединении. Поддельному разговору требовался номер следующего шага. Выведя его из первого наблюдения, атакующий завершал открытие, не получив ответа сервера на ложный адрес. Автомат с талонами позволял подсмотреть порядок выдачи соседних талонов.

Случайное число для каждого нового разговора звучало заманчиво. Но первоначальная спецификация TCP, RFC 793, продвигала часы начальных номеров вперёд, чтобы старые пакеты предыдущего воплощения соединения не выглядели свежими при его повторном открытии. RFC 1948 также напоминал о TIME-WAIT в системах семейства BSD. Разные разговоры нуждались в несвязанных стартах; новые воплощения одной и той же пары сторон — в движении вперёд. Чистая лотерея нарушала второе требование.

RFC 1948 разделил роли. Соединение TCP задают четыре значения: локальные IP-адрес и порт, удалённые IP-адрес и порт. Начальный номер предлагалось вычислять как M + F(четвёрка). M — идущий счётчик времени. F — смещение из идентификатора соединения и секретных данных. Каждая четвёрка получила свою числовую дорожку; при возвращении к той же четвёрке часы сдвигали старт вперёд. Билет с одной дорожки не открывал начальную отметку соседней.

Секретность смещения была существенной. RFC 1948 предлагал криптографический хеш четвёрки вместе с тайным материалом и называл доступный тогда MD5 примером. Варианты включали случайные данные, секрет узла, время загрузки и его идентификатор. Если посторонний вычислил бы F, у него снова оказалась бы карта билетных касс. Формула одновременно избавляла от необходимости хранить вечный список всех закрытых соединений.

Смена секрета на работающей машине требовала оглядки. Для вновь открытого соединения с той же четвёркой она сдвигала числовую дорожку, пока старые пакеты могли ещё находиться в сети. RFC 1948 предписывал сохранить состояние завершённых соединений или выдержать тишину в течение двух максимальных сроков жизни сегмента. Тайна разъединяла дорожки; время разводило старое и новое внутри каждой. Меняя замок, надо проверить, не застряло ли в дверях вчерашнее письмо.

RFC 6528 от 2012 года превратил идею в стандарт, заменил RFC 1948 и обновил RFC 793. Он точнее сформулировал псевдослучайную функцию с четырьмя реквизитами соединения и секретным ключом, сохранил M + F и разобрал длину и смену ключа. Суть 1996 года осталась: часы упорядочивают повторения одной идентичности, секрет скрывает расстояния до других.

Вор и после этого мог честно взять талон и рассмотреть его. RFC 1948 лишил его линейки, которой можно измерить начало очереди у соседнего окна. Смещение хранилось за стойкой.