首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >捕获数据包的重新注入导致不正确的以太网校验和。

捕获数据包的重新注入导致不正确的以太网校验和。
EN

Stack Overflow用户
提问于 2018-06-26 14:21:52
回答 1查看 1.4K关注 0票数 1

当我玩替罪羊时,我观察到了以下的行为。替罪羊手册页举个例子,如下所示

代码语言:javascript
复制
a=sniff(filter="tcp port 110")
...
sendp(a)

重新注入捕获的数据包。然而,当我自己尝试时,wireshark告诉我以太网帧检查序列在所有重新注入的数据包上都是不正确的。(我捕获哪些数据包并重新注入并不重要。)当我以交互的方式检查数据包时,我注意到没有显示以太网拖车(和校验和)。此外,没有修改或设置拖车的方法。

很明显,替罪羊不像我期望的那样-我错过了什么?如何重新注入以太网帧的副本,使其显示为有效?

详细实例

在这个例子中,我考虑一个ARP包。然而,这个问题也存在于其他数据包类型中。

这是wireshark记录的内容(由tcpdump -v -XX -r ...转储):

代码语言:javascript
复制
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就是这样看待它的:

代码语言:javascript
复制
>>> 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'

然后..。

代码语言:javascript
复制
>>> sendp(x[0])
.
Sent 1 packets.

这就是wireshark捕捉到的

代码语言:javascript
复制
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在捕获时所看到的(注意:这是一个不同于上面示例的数据包)

代码语言:javascript
复制
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在重发时所看到的(匹配前面的捕获)。

代码语言:javascript
复制
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-AMD 64),定期更新,不受干扰。操作系统在Virtualbox VM (Virtualbox 5.2.12)中运行。我尝试过的另一个平台是带有Kali Linux的戴尔PC (没有VM)。

洞察力

以太网帧必须包含至少64个字节,包括14个字节头和4个字节FCS,因此有效负载必须至少有46个字节(Wireshark通常显示报头,而不是FCS,这就是为什么Wireshark显示一个ARP数据包有60个字节而不是64个字节)。ARP数据包(用于以太网/IPv4 4)有28个字节。这留下了18字节的填充。由于某种原因我还不知道如果我通过sendto()发送60个字节(不包括FCS),什么(驱动程序?)追加另外14个字节,扰乱FCS。

下面是我在替罪羊中调用strace -x -s 1000 -e trace=%network -p ...时得到的sendp(pkt)的转储(另一个数据包):

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

发布于 2018-06-28 19:04:30

您可能正在使用wireshark来捕获正在生成这些数据包的框上的传出数据包,而这些传出数据包就是您看到的具有不正确的帧检查序列(FCS)的数据包。这是因为,在发送过程中,网络适配器在发送帧时实际上计算并追加了FCS,但是给wireshark的帧的副本发生在内存中的版本中,然后才转移到网络适配器。(几乎所有现代NIC都是这样的:校验和是在适配器中计算的,因为它可以使用硬件CRC生成器,这比软件所能做到的要快得多。)

所以,即使你可能不加修改地重新发送先前接收到的帧,它的原始FCS也被丢弃了,一个新的FCS在输出的时候会被生成,但是在发送框中,你看不到,所以wireshark正在查看它从libpcap获得的缓冲区中的任何数据(很可能全部为零)。

我敢打赌,如果你在局域网的另一个站(例如在目的地)捕获相同的数据包,你会发现,在线路上,它们确实有正确的校验和。

顺便说一句,wireshark中的以太网协议首选项窗格中有几个设置控制如何处理/报告。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51045222

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档