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