在玩鹰鱼时,我观察到以下行为。虚假的手册页建议像这样的示例
a=sniff(filter="tcp port 110")
...
sendp(a)
重新注入捕获的数据包。但是,当我自己尝试此操作时,wireshark告诉我所有重新注入的数据包的 ETHERNET FRAME CHECK SEQUENCE INCORRECT 。 (捕获和重新注入的数据包无关紧要。)当我用scapy交互地检查数据包时,我注意到未显示以太网预告片(和校验和)。而且,没有方法可以修改或设置预告片。
显然,scapy无法正常工作-我想念什么?如何重新插入以太网框架的副本,使其看起来有效?
在此示例中,我考虑了ARP数据包。但是,其他数据包类型也存在此问题。
这是wireshark记录的内容(由tcpdump -v -XX -r ...
转储):
14:05:39.517932 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 192.168.141.150 tell 192.168.140.193, length 46
0x0000: ffff ffff ffff 90b1 1c47 c81e 0806 0001 .........G......
0x0010: 0800 0604 0001 90b1 1c47 c81e c0a8 8cc1 .........G......
0x0020: 0000 0000 0000 c0a8 8d96 0000 0000 0000 ................
0x0030: 0000 0000 0000 0000 0000 0000 ............
这是scapy3的看法:
>>> x = sniff(count=1, filter='arp')
>>> bytes(x[0])
b'\xff\xff\xff\xff\xff\xff\x90\xb1\x1cG\xc8\x1e\x08\x06\x00\x01\x08\x00\x06\x04\x00\x01\x90\xb1\x1cG\xc8\x1e\xc0\xa8\x8c\xc1\x00\x00\x00\x00\x00\x00\xc0\xa8\x8d\x96\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> x[0].show()
###[ Ethernet ]###
dst= ff:ff:ff:ff:ff:ff
src= 90:b1:1c:47:c8:1e
type= ARP
###[ ARP ]###
hwtype= 0x1
ptype= 0x800
hwlen= 6
plen= 4
op= who-has
hwsrc= 90:b1:1c:47:c8:1e
psrc= 192.168.140.193
hwdst= 00:00:00:00:00:00
pdst= 192.168.141.150
###[ Padding ]###
load= '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
然后...
>>> sendp(x[0])
.
Sent 1 packets.
这是wireshark捕获的
14:14:44.901556 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 192.168.141.150 tell 192.168.140.193, length 60
0x0000: ffff ffff ffff 90b1 1c47 c81e 0806 0001 .........G......
0x0010: 0800 0604 0001 90b1 1c47 c81e c0a8 8cc1 .........G......
0x0020: 0000 0000 0000 c0a8 8d96 0000 0000 0000 ................
0x0030: 0000 0000 0000 0000 0000 0000 3203 3136 ............2.16
0x0040: 3803 3139 3207 696e 2d61 8.192.in-a
如您所见,最后14个字节非常奇怪。实际上,常规ARP数据包的长度为46,而不是60。(Wireshark将其显示为长度为74,请参见下图)。
这是strace
在捕获时看到的内容(请注意:这是与上例不同的数据包)
2552 recvfrom(12, "\xff\xff\xff\xff\xff\xff\x00\x50\x56\xbf\x0c\x83\x08\x06\x00\x01\x08\x00\x06\x04\x00\x01\x00\x50\x56\xbf\x0c\x83\xc0\xa8\x8d\xb0\x00\x00\x00\x00\x00\x00\xc0\xa8\x8e\x6b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 65535, 0, {sa_family=AF_PACKET, sa_data="\x08\x06\x02\x00\x00\x00\x01\x00\x01\x06\x00\x50\x56\xbf\x0c\x83"}, [20->18]) = 60
这就是strace
在重新发送(与之前的捕获匹配)时看到的内容
2552 sendto(12, "\xff\xff\xff\xff\xff\xff\x00\x50\x56\xbf\x0c\x83\x08\x06\x00\x01\x08\x00\x06\x04\x00\x01\x00\x50\x56\xbf\x0c\x83\xc0\xa8\x8d\xb0\x00\x00\x00\x00\x00\x00\xc0\xa8\x8e\x6b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 60, 0, NULL, 0) = 60
以防万一,请注意:该平台是Kali Linux(4.16.0-kali2-amd64),该平台定期保持最新状态,不予干预。操作系统在Virtualbox VM(Virtualbox 5.2.12)中运行。我尝试过的另一个平台是带有Kali Linux(无VM)的DELL PC。
一个以太网帧必须至少包含64个字节,包括14个字节的标头和4个字节的FCS,因此有效负载必须至少具有46个字节(Wireshark通常显示标头,但不显示FCS,这就是Wireshark显示的原因ARP数据包有60个字节而不是64个字节)。 ARP数据包(用于以太网/ IPv4)具有28个字节。剩下18个字节的填充。由于某些原因,我仍然不知道,如果我通过sendto()
发送60字节(不包括FCS)的原始数据,那么(驱动程序?)会附加另外14字节,弄乱了FCS。
下面是我在scapy中调用strace -x -s 1000 -e trace=%network -p ...
时得到的sendp(pkt)
的转储(对于另一个数据包):
socket(AF_PACKET, SOCK_RAW, 768) = 12
setsockopt(12, SOL_SOCKET, SO_RCVBUF, [0], 4) = 0
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 13
setsockopt(12, SOL_PACKET, PACKET_ADD_MEMBERSHIP, {mr_ifindex=if_nametoindex("eth0"), mr_type=PACKET_MR_PROMISC, mr_alen=0, mr_address=}, 16) = 0
bind(12, {sa_family=AF_PACKET, sll_protocol=htons(ETH_P_ALL), sll_ifindex=if_nametoindex("eth0"), sll_hatype=ARPHRD_NETROM, sll_pkttype=PACKET_HOST, sll_halen=0}, 20) = 0
setsockopt(12, SOL_SOCKET, SO_RCVBUF, [1073741824], 4) = 0
setsockopt(12, SOL_SOCKET, SO_SNDBUF, [1073741824], 4) = 0
getsockname(12, {sa_family=AF_PACKET, sa_data="\x00\x03\x02\x00\x00\x00\x01\x00\x00\x06\x08\x00\x27\xbc\xeb\x8a"}, [20->18]) = 0
sendto(12, "\xff\xff\xff\xff\xff\xff\x00\x50\x56\xbf\x0c\x83\x08\x06\x00\x01\x08\x00\x06\x04\x00\x01\x00\x50\x56\xbf\x0c\x83\xc0\xa8\x8d\xb0\x00\x00\x00\x00\x00\x00\xc0\xa8\x8e\x6b\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", 60, 0, NULL, 0) = 60
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 11
setsockopt(12, SOL_PACKET, PACKET_DROP_MEMBERSHIP, {mr_ifindex=if_nametoindex("eth0"), mr_type=PACKET_MR_PROMISC, mr_alen=0, mr_address=}, 16) = 0
答案 0 :(得分:0)
您可能正在使用Wirehark在生成它们的盒子上捕获传出数据包,这些传出数据包就是您看到的带有不正确帧检查序列(FCS)的数据包。这是因为,在发送时,网络适配器实际上在发送帧时进行计算并附加FCS,但是提供给Wireshark的帧的副本是从内存版本转移到网络之前的适配器。 (几乎所有现代的NIC都是如此:校验和是在适配器中计算的,因为它可以使用硬件CRC生成器,其速度比软件快。)
因此,即使您可能未经修改地重新传输先前接收到的帧,其原始FCS也会在此过程中被丢弃,并且在输出时会生成新的FCS,但是在传输盒上,您可以没看到,所以wireshark正在查看从libpcap
获得的缓冲区中帧内该位置的任何数据(可能是全零)。
我敢打赌,如果您在LAN上的另一个站点(例如,目的地)捕获了这些相同的数据包,您会发现它们实际上具有正确的校验和。
顺便说一下,wireshark的“以太网协议首选项”窗格中有几个设置可以控制如何处理/报告这些设置。