确认scapy中数据的确认号
问题描述
我在玩 scapy,尝试做一个类似 nmap 的东西,我成功地进行了三次握手,如果我连接到 smtp 服务器,我会自动接收数据,但我无法确认.
I'm playing around with scapy, trying to do a nmap-like, I succeeded doing a three way handshake and I automatically receive data if I connect to a smtp server but I can't acknowledge it.
我已经通过 netcat 连接到它,看看为什么它不起作用,并且 nc 实际上发送了一个 ACK 数据包,其中 TCP ack 字段设置为接收到的数据段长度 + 1.所以我试图对 scapy 做同样的事情,但我不知道在哪里可以找到 TCP 段的长度.我尝试了一个 lsc(TCP) 但我看不到该字段.
I have connected to it via netcat to see why it wouldn't work and nc actually send an ACK packet with the TCP ack field set to the length of the data segment received + 1. So I am trying to do the same with scapy but I don't know where to find the length of a TCP segment. I tried a lsc(TCP) but I can not see the field.
这是 netcat 连接的wireshark 捕获:
Here is a wireshark capture of the netcat connection :
以及数据包的详细信息:
And the detail of the packet :
如您所见,数据正下方的数据包的 ack 字段为 37 + 1 = 38.
As you can see, the ack field of the packet just below the data is 37 + 1 = 38.
有人知道在哪里或如何找到它吗?
Does someone knows where or how it can be found ?
实际上没有给出段长度的字段,但可以通过两种方法计算:
There is actually no field that gives the segment length but it can be calculated with two methods:
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 捕获时,我有一个巨大的确认号,并且数据包被标记为ACKed unseen segment".当我查看十六进制字节时,我得到了正确的值.有谁知道为什么会发生这种情况以及如何解决?
However, when I print the values I get the good ack number but when I watch the wireshark capture, I have a huge ack number and the packet is marked as "ACKed unseen segment". When I look at the bytes in hexa, I got the right value though. Does anyone knows why that happens and how to solve it?
解决方案
Wireshark 在其显示中使用相对数字,因此正确的 scapy 行是:
Wireshark uses relative numbers in its display so the right scapy line is :
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)
以下代码(请参阅问题中的编辑)确实有效:
And the following code (see EDIT in the question) does work :
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)
相关文章