Сокращение полезной нагрузки TCP с помощью Scapy приводит к тому, что [Предыдущий сегмент TCP не захвачен] - PullRequest
1 голос
/ 25 октября 2019

Я пытаюсь изменить полезную нагрузку TCP, удалив несколько байтов.

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

Если байты удаляются, Wireshark показывает сообщение [Предыдущий сегмент TCP не захвачен] в дампе.

Я удаляю обе контрольные суммы и длину пакета измененного пакета, чтобы Scapy пересчиталвсе они при отправке пакета:

# Delete the old checksums
del packet_mod[IP].chksum
del packet_mod[TCP].chksum

# Delete the old packet length
del packet_mod[IP].len

Модификация работает, если я также отключаю len (stripped_bytes) в конце измененного пакета, так как повторно отправленный сегмент TCP добавляется визмененный пакет получателем.

Например: я убираю 20 байтов полезной нагрузки TCP. Модификация тогда работает, только если я также отрежу дополнительные 20 байтов в конце полезной нагрузки.

Чего мне не хватает?

1 Ответ

2 голосов
/ 27 октября 2019

Я не понимаю, что означает эта часть:

Например: я убираю 20 байтов полезной нагрузки TCP. Тогда модификация работает только в том случае, если я также обрежу дополнительные 20 байтов в конце полезной нагрузки.

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

Приемник TCP использует порядковые номера сегментов и длины сегментов (длина сегмента). вычисляется по длине дейтаграмм IP, которые доставили сегмент) для построения непрерывного потока байтов из полученного трафика. Например, если получатель ранее собрал все данные до позиции последовательности 200 и следующие входящие сегменты выглядят так:

  (segment 1) sequence=200 length=80 data='data data data ...'
  (segment 2) sequence=280 length=60 data='more data ...'
  (segment 3) sequence=340 length=70 data='even more data ...'

, то получатель знает, что теперь он собрал все данные до (но не включая) позицию 410. Поскольку пробелов нет, эти данные готовы для передачи в приложение.

Обратите внимание, что номера сегментов (1), (2), (3) равны не присутствует в заголовке TCP. Эти числа существуют только для того, чтобы это описание могло относиться к ним.

Очевидно, что если сегмент (2) был потерян, а получатель получил только сегменты (1) и (3), то получатель будет знать, чтобыл пробел в полученных данных. И он точно знал бы, где был этот разрыв: ему не хватает 60 байтов, начиная с позиции 280. TCP обещает доставить полный поток данных в порядке, поэтому до тех пор, пока этот промежуток не будет заполнен, получателю не разрешено доставлять более поздние байты. (например, 70 байтов в позиции 340, которые он получил в сегменте 3) для приложения. Если пропущенные байты не приходят очень скоро, то получатель сообщит отправителю о разрыве, и отправитель повторно передаст пропущенные данные.

Вот почему удаление байтов из сегмента TCP вызывает проблемы. Если ваша программа удалила 20 байтов из сегмента (2), то получатель увидит это:

  (segment 1) sequence=200 length=80 data='data data data ...'
  (segment 2) sequence=280 length=40 data='more data ...'
  (segment 3) sequence=340 length=70 data='even more data ...'

и получатель заключит, что обнаружил разрыв в 20 байтов в позиции 320.

Если Wireshark наблюдает за этим трафиком, он придет к тому же выводу. Ни получатель TCP, ни Wireshark не знают, что причиной пропущенных байтов является то, что сегмент (2) был отредактирован. Наиболее разумным предположением Wireshark является то, что отсутствующие байты были в сегменте, который каким-то образом не был доступен для проверки, и именно поэтому он показывает сообщение «Предыдущий сегмент не захвачен». Он говорит «предыдущий», потому что он не обнаруживает, что есть разрыв, пока он не исследует сегмент (3), затем один после пропуска.

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

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

Ссылки: Базовый механизм порядковых номеров TCP описан в RFC 793 , а давняя лучшая практика использования порядковых номеров для повышения безопасности описана в RFC 1948 и формализована какстандарт в RFC 6528 .

...