Для некоторых личных целей мне нужно обогатить заголовок HTTP дополнительной информацией (которая будет обрабатываться приложением на стороне HTTP-сервера). Основная идея заключалась в том, чтобы изменить полученный пакет, отправить его по назначению и не беспокоиться об ответе. Очень упрощенная схема путей трафика такова:
+---+ +------+ +---+
| +<<-----o MDFY +<<------o |
| R | +------+ | S |
| C | | N |
| V | | D |
| o--------------------->>+ |
+---+ +---+
Проблема связана с номерами TCP SEQ/ACK. После TCP-рукопожатия Отправитель отправляет пакет длиной 4 байта, который приходит Модификатору, где длина меняется на 22, затем пакет приходит Получателю, и он отправляет номер ACK +23, в то время как Отправитель ожидает +5. Это сводит Отправителя с ума, и сеанс становится несинхронизированным. Я вижу это, когда, например, пробую netcat для тестирования - для немодифицированных пакетов сеанс закрывается сразу после обмена данными, в то время как для модифицированных пакетов сеанс устаревает на долгое время (на самом деле, я останавливаю его нажатием Ctrl-C).
Я не вижу простого способа справиться с этой ситуацией. Похоже, что после изменения в середине, весь сеанс должен обрабатываться Модификатором, поскольку Отправитель ничего не знает об изменении номера последовательности и будет полагаться на свои собственные номера. Это существенно повлияет как на производительность, так и на увеличение сложности, поскольку мне нужно поддерживать состояние каждого сеанса и изменять каждый пакет, приходящий с обеих сторон, чтобы поддерживать номера SEQ/ACK.
Может быть, я не вижу другого пути, кроме как написать свой DPI? :-) Любые знания, идеи и предложения приветствуются.
Спасибо.
решение1
Единственный более простой вариант, который я вижу, — это использование прозрачного прокси-сервера.
В этом случае клиент отправляет запрос на целевой сервер. Прокси-сервер перехватывает запрос, добавляет заголовок и создает другой запрос на целевой сервер. Целевой сервер возвращает ответ прокси-серверу, который затем возвращает его клиенту.
Недостатком здесь является то, что сервер видит не исходный IP-адрес клиента, а IP-адрес прокси-сервера.
Тогда для подхода MITM на уровне TCP могут существовать наборы инструментов, реализующие требуемую функциональность, так что полная реализация не требуется.
решение2
Похоже на какой-то полуоформленный NAT; и проблема как раз в том, что он полуоформленный.
Вы не можете MITM только в одном направлении потока пакетов TCP: вам нужно обрабатывать оба потока, именно для обработки таких ситуаций (стандартный NAT обычно заботится только об адресах/портах источника и назначения, но принцип тот же; если вы хотите исказить пакеты во время передачи, и вы хотите, чтобы это искажение было прозрачным для обеих конечных точек, вам нужно получитьвсеверно).
Как только вы начнете все учитывать, довольно скоро у вас появится полноценный NAT: тогда не нужно будет изобретать велосипед, существует множество реализаций, которые позволят вам искажать пакеты по вашему желанию.
Фактически доступные параметры, конечно, будут зависеть от используемой операционной системы и программного обеспечения маршрутизации/брандмауэра.