Ack编号用于确认scapy中的数据

时间:2015-11-02 11:29:01

标签: python network-programming scapy

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

我通过netcat连接到它,看看为什么它不起作用,并且nc实际发送一个ACK数据包,其中TCP ack字段设置为接收的数据段的长度+ 1。 所以我试图用scapy做同样的事情,但我不知道在哪里可以找到TCP段的长度。我尝试了一个lsc(TCP),但我看不到该字段。

以下是netcat连接的wireshark捕获:

enter image description here

包的细节:

enter image description here

如您所见,数据正下方的数据包的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捕获时,我有一个巨大的确认号码,并且数据包被标记为“确认看不见的段”。当我查看hexa中的字节时,我得到了正确的值。有谁知道为什么会发生这种情况以及如何解决它?

2 个答案:

答案 0 :(得分:3)

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)

以下代码(请参阅问题中的EDIT)确实有效:

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)

答案 1 :(得分:0)

获取TCP段长度。这已针对IPv6流量进行了验证

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