2015-08-15 2 views
0

Я новичок в сетях и, в частности, TCP (я немного обманывал UDP, но это все). Я разрабатываю простой протокол, основанный на обмене сообщениями между двумя конечными точками. Эти сообщения должны быть сертифицированы, поэтому я реализовал криптографический уровень, который позаботится об этом. Однако, хотя UDP имеет звуковое определение пакета, который составляет минимальную единицу, которая может быть передана за один раз, протокол TCP (насколько я понимаю) полностью ориентирован на поток.Разметка сообщений в TCP-связи

Теперь это меня немного озадачивает. Как обмениваться сообщениями, как я могу сказать, где начать, а другой заканчивается? В принципе, я могу, очевидно, передавать сообщения фиксированной длины или сначала сообщать размер каждого сообщения в каком-то заголовке. Тем не менее, это может быть подвергнуто атакам: хотя, конечно, невозможно будет исказить или определить содержание сообщения, вышеупомянутая техника упростит полное разрушение моего общения, просто добавив один байт посередине.

Скажите, что мне нужно передать сообщение длиной 1234567 байт. Прежде всего, я связываю 4 байта с целым числом, представляющим размер сообщения. Хорошо. Затем я отправляю сообщение. Это сообщение делится на несколько пакетов, которые получают отдельно. Теперь злоумышленник просто отправляет в дополнительный пакет, подделывая его так, как если бы он был частью разговора. Это может быть только один байт: это полностью разрушает любой механизм синхронизации, который я реализовал! Сообщение имеет ложный байт в середине, и он не будет успешно декодироваться. Кроме того, последний байт первого сообщения нарушает выравнивание второго сообщения и т. Д.: Соединение разрушается и с простой, простой атакой! Насколько вероятна и возможна эта атака?

Так что мне интересно: какой максимальный блок данных может быть передан сразу? Я понимаю, что вызов на вызов не соответствует вызову для приема: сообщение можно разделить на разные куски. Как сгруппировать пакеты каким-то образом, чтобы я знал, что они собираются вместе? Есть ли способ определить сообщение более высокого уровня, которое восстанавливается и выравнивается вместе и запускает один вызов функции приема? Если нет, то какие другие решения я могу найти, чтобы поддерживать связь между собой даже в присутствии злоумышленника?

+0

http://www.ietf.org/rfc/rfc2385.txt весьма уместен для того, что вы описываете. (И несколько операционных систем поддерживают сигнатуры TCP-MD5, обычно включаемые с некоторыми вызовами setsockopt()) – nos

+0

1) TCP имеет порядковые номера; вы не можете * впрыснуть * несколько байтов в поток без обмена сообщениями. 2) Нет сообщений bounderies; вам придется реализовать свои собственные bounderies в протоколе уровня приложения, либо используя сообщения фиксированной длины, либо путем префикса * сообщений * заголовком (что ожидать) или путем их разметки * концом сообщения *, например '\ n'. – wildplasser

+1

@wildplasser Фактически вы _probably_ можете вставлять несколько байтов в поток, так как активный злоумышленник MITM также может модифицировать SEQ/ACK.И для определенных сетевых стеков это еще проще из-за их (неправильной) обработки [внеполосных данных] (https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Out-of-band_data). – vlp

ответ

0

Теперь злоумышленник просто отправляет в дополнительный пакет, подделывая его так, как если бы он был частью разговора. Это может быть только один байт: это полностью разрушает любой механизм синхронизации, который я реализовал!

Преодоление такой проблемы с инжектией связано с обеспечением потока. Создайте зашифрованный поток и отправьте через него свои пакеты.

Конечно, сам зашифрованный поток имеет эту проблему; его сообщения могут быть повреждены. Но эти сообщения имеют надежные проверки целостности. Проблема обнаружена, и соединение может быть снесено и восстановлено для повторной синхронизации.

Кроме того, между сообщениями может использоваться некоторая синхронизирующая/кадровая последовательность синхронизации с фиксированной длиной: некоторый определенный бит-шаблон. Не имеет значения, происходит ли это происхождение внутри сообщений случайно, потому что мы только когда-либо специально ищем этот шаблон, когда что-то идет не так (получено поврежденное сообщение), иначе мы пропустим эту последовательность. Если получено поврежденное сообщение, мы получаем байты до тех пор, пока не увидим шаблон синхронизации, и предположим, что все, что следует за ним, это начало сообщения (длина за которым следует полезная нагрузка). Если , что терпит неудачу, мы повторяем процесс. Когда мы получаем правильное сообщение, мы отвечаем партнеру, который будет повторно передавать все, что мы не получили.

Насколько вероятна и возможна эта атака?

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

В принципе, это не возможно для злоумышленника C, совершающего против конечных точек A и B, которые находятся вдали от C в сети. Поддельный исходный IP-адрес будет отклонен задолго до того, как C сможет достичь своего пункта назначения. Это более правдоподобно как внутреннее задание (которое включает вредоносное ПО): C близко к A и B.

2

В основном трудно контролировать способ деления потока ОС на TCP-пакеты (протокол RFC, определяющий TCP-протокол, указывает, что TCP стек должен позволить клиентам принудительно отправлять буферизованные данные с помощью функции push, но он не определяет, сколько пакетов должно быть создано. После того, как злоумышленник может изменить любой из них).

И эти TCP-пакеты могут быть разделены еще больше на IP-фрагменты во время их пути через сеть (которые могут быть отключены флагом IP-адреса «Не фрагментировать»), но этот флаг может привести к тому, что ваши пакеты не будут доставлено вообще).

Я думаю, что ваша проблема не о введения пакетов в протокол потока, но о крепящих его.

IPSec может быть очень полезным в вашем сценарии, поскольку он работает на сетевом уровне.

Он обеспечивает целостность для каждого отправленного пакета, поэтому любые изменения в проводнике обнаруживаются и недействительные пакеты удаляются. В случае TCP удаленные пакеты автоматически передаются повторно.

(Почти) все делается автоматически ОС - поэтому вам не нужно беспокоиться об этом (и делать ошибки).

Конфиденциальность также может быть гарантирована (с тем же преимуществом, чтобы не изобретать колесо).

IPSec должен предоставить вам надежный транспортный протокол, на котором вы можете использовать любой формат кадра, который вам нравится.

Другой альтернативой является использование SSL/TLS поверх сеанса TCP, которое менее надежное (поскольку оно закрывает целостное соединение при ошибке целостности).

+0

«В принципе трудно контролировать, как ОС делит поток на TCP-пакеты». Это невозможно. TCP имеет право делать это так, как ему нравится. Это протокол байтового потока. Флаг PSH, который реализует функцию «push», применяется к текущему сегменту и всему, что предшествует ему. В этом нет ничего неопределенного. И в любом случае это устарело. – EJP

+0

@EJP Определенно вы можете управлять им (то есть встроенными системами, сырыми сокетами), но это сложно :) – vlp

+0

@EJP и _push function_ не определяет _how_, стек делит поток на пакеты (что подразумевалось под неопределенным). – vlp

Смежные вопросы