【问题标题】:ICMP packet sniffing not receiving any data (Black Hat Python Book)ICMP 数据包嗅探未收到任何数据(Black Hat Python Book)
【发布时间】:2020-08-01 12:05:03
【问题描述】:

我从 Black hat Python 第 3 章。网络:原始套接字和嗅探一书中发现了这段代码 sn-p:

import socket
import os

host = "x.x.x.x"        # Host to listen on

# Create a raw socket and bind it to the public interface
if os.name == "nt":
    socket_protocol = socket.IPPROTO_IP
else:
    socket_protocol = socket.IPPROTO_ICMP
    
sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol)
sniffer.bind((host, 0))
sniffer.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)     # We want the IP headers included in the capture
# if we're using Windows, we need to send an IOCTL
# to set up promiscuous mode
if os.name == "nt":
    sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
print(sniffer.recvfrom(65565))      # Read in a single packet

# If we're using Windows, turn off promiscuous mode
if os.name == "nt":
    sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

当我执行ping google.com 时,上面的代码应该捕获第一个 ping 数据包,但在print(sniffer.recvfrom(65565)) 行中无限期等待数据包

我尝试使用 host 作为我机器的本地 IP 和 localhost,并尝试更改缓冲区大小,如 similar question 中所示。但是效果不好。

我在设置host = "" 并执行ping 127.0.0.1 时工作,但在我ping 其他网址时却不行。

谁能告诉我怎么回事?

我正在使用 Python 3.8.2 和 Ubuntu 18.04。

【问题讨论】:

  • 当您 ping 其他 IP/url 时,它会直接向其他 IP/ulr 发送请求,并且没有理由发送到您的本地 IP。
  • 据我所知,捕获数据包的工具需要库 ​​pcap (packet capture)。我还必须在 Linux Mint(基于 Ubuntu 18.04)上以root(使用sudo)运行代码。我用0.0.0.0 监听了我所有的网卡(LANWiFi),我得到了一些结果。
  • @furas 感谢您的评论,我得到了解决方案,因为您告诉您它可以工作。我分析了为什么它在某些情况下有效,这让我找到了答案。

标签: python python-3.x sockets packet-sniffers icmp


【解决方案1】:

问题实际上不在于代码,而是兼容性问题,ping 更现代的服务器是由 IPv6 完成的,而代码仅选择 IPv4 ICMP 数据包。一个简单的解决方案是将 ping 限制为 IPv4

ping -4 google.com

IPv6 的嗅探器只需要对IPv4 版本进行小改动,如下:

import socket
import os

host = ""       # Host to listen on

# Create a raw socket and bind it to the public interface
if os.name == "nt":
    socket_protocol = socket.IPPROTO_IPV6
else:
    socket_protocol = socket.IPPROTO_ICMPV6
    
sniffer = socket.socket(socket.AF_INET6, socket.SOCK_RAW, socket_protocol)
sniffer.bind((host, 0))
sniffer.setsockopt(socket.IPPROTO_IPV6, socket.IP_HDRINCL, 1)       # We want the IP headers included in the capture
# if we're using Windows, we need to send an IOCTL
# to set up promiscuous mode
if os.name == "nt":
    sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
print(sniffer.recvfrom(65565))      # Read in a single packet

# If we're using Windows, turn off promiscuous mode
if os.name == "nt":
    sniffer.ioctl(socket.SIO_RCVALL, socket.RCVALL_OFF)

【讨论】:

    猜你喜欢
    • 2015-06-01
    • 2011-09-29
    • 1970-01-01
    • 1970-01-01
    • 2013-01-28
    • 1970-01-01
    • 2010-10-02
    • 2015-11-24
    • 1970-01-01
    相关资源
    最近更新 更多