Подтвердите номер для подтверждения данных в scapy

Я играю со scapy, пытаясь сделать что-то вроде nmap, мне удалось выполнить трехстороннее рукопожатие, и я автоматически получаю данные, если подключаюсь к smtp-серверу, но я не могу это подтвердить.

Я подключился к нему через netcat, чтобы понять, почему он не работает, и nc фактически отправляет пакет ACK с полем TCP ack, установленным на длину полученного сегмента данных + 1. Итак, я пытаюсь сделать то же самое с scapy, но Я не знаю, где найти длину сегмента TCP. Я попробовал lsc (TCP), но не вижу поля.

Вот захват соединения netcat с помощью wireshark:

введите описание изображения здесь

И детали пакета:

введите описание изображения здесь

Как видите, поле ack пакета чуть ниже данных равно 37 + 1 = 38.

Кто-нибудь знает, где и как его можно найти?

РЕДАКТИРОВАТЬ:

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

    tcp_seg_len = len(rp.getlayer(Raw).load)
    # or
    ip_total_len = rp.getlayer(IP).len
    ip_header_len = rp.getlayer(IP).ihl * 32 / 8
    tcp_header_len = rp.getlayer(TCP).dataofs * 32 / 8
    tcp_seg_len = ip_total_len - ip_header_len - tcp_header_len

    ans_ack,unans_ack = sr(IP(dst=ip)/TCP(sport=pkt[1].dport, \
                                          dport=pkt[1].sport, \
                                          seq=rp[1].ack, \
                                          ack=tcp_seg_len + 1, \
                                          flags="A"), \
                           verbose=0, timeout=1)

Однако, когда я печатаю значения, я получаю хороший номер подтверждения, но когда я смотрю захват wireshark, у меня огромный номер подтверждения, и пакет помечен как «Невидимый сегмент с подтверждением». Однако, когда я смотрю на байты в шестнадцатеричном формате, я получаю правильное значение. Кто-нибудь знает, почему это происходит и как это решить?


person Jeff Bencteux    schedule 02.11.2015    source источник


Ответы (2)


Wireshark использует относительные числа в своем отображении, поэтому правая scapy строка:

    ans_ack,unans_ack = sr(IP(dst=ip)/TCP(sport=pkt[1].dport, \
                                      dport=pkt[1].sport, \
                                      seq=rp[1].ack, \
                                      ack=rp[1].seq + tcp_seg_len, \
                                      flags="A"), \
                       verbose=0, timeout=1)

И следующий код (см. РЕДАКТИРОВАТЬ в вопросе) работает:

ip_total_len = rp.getlayer(IP).len
ip_header_len = rp.getlayer(IP).ihl * 32 / 8
tcp_header_len = rp.getlayer(TCP).dataofs * 32 / 8
tcp_seg_len = ip_total_len - ip_header_len - tcp_header_len
ans_ack,unans_ack = sr(IP(dst=ip)/TCP(sport=pkt[1].dport, \
                                      dport=pkt[1].sport, \
                                      seq=rp[1].ack, \
                                      ack=rp[1].seq + tcp_seg_len, \
                                      flags="A"), \
                           verbose=0, timeout=1)
person Jeff Bencteux    schedule 02.11.2015
comment
Пробуя ваш фрагмент кода, я обнаружил, что int() необходим для tcp_seg_len, который в противном случае был бы для меня плавающим, что неудивительно, что scapy разбился... - person mozzbozz; 10.02.2019
comment
Зачем вам нужны все эти расчеты длины tcp-сегмента? То, что вы сделали в вопросе tcp_seg_len = len(rp.getlayer(Raw).load), отлично сработало для меня. - person Tomerikoo; 09.05.2021

Чтобы получить длину сегмента TCP (это было проверено для трафика IPv6):

tcp_header_len = rp.getlayer(TCP).dataofs * 32 / 8
tcp_seg_len = rp.plen - tcp_header_len
person Smrithi Komalan    schedule 18.08.2016