Ack 号以确认 scapy 中的数据

Ack number to acknowledge data in scapy

我正在玩 scapy,尝试做一个类似 nmap 的操作,我成功地进行了三次握手,如果我连接到 smtp 服务器,我会自动接收数据,但我无法确认它。

我已经通过 netcat 连接到它以查看它为什么不起作用,并且 nc 实际上发送了一个 TCP ack 字段设置为接收到的数据段的长度 + 1 的 ACK 数据包。 所以我试图对 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)

然而,当我打印这些值时,我得到了正确的 ack 号,但是当我观察 wireshark 捕获时,我有一个巨大的 ack 号并且数据包被标记为 "ACKed unseen segment"。当我查看 hexa 中的字节时,我得到了正确的值。有谁知道为什么会这样以及如何解决?

Wireshark uses relative numbers 在它的显示中所以右边的 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)

获取 TCP 段长度(已针对 IPv6 流量验证):

tcp_header_len = rp.getlayer(TCP).dataofs * 32 / 8
tcp_seg_len = rp.plen - tcp_header_len