【问题标题】:sending ICMP packets in scapy and choosing the correct interface在 scapy 中发送 ICMP 数据包并选择正确的接口
【发布时间】:2014-12-04 03:41:20
【问题描述】:

我们可以对第 3 层 ICMP 数据包使用 srp() 函数吗?我看到当我们制作一个 ICMP 回显请求数据包并使用 sr() 发送/接收时,我们没有看到它被发送出接口,因此没有来自目的地的响应。但是,如果我们使用 srp() 函数,我们会看到相同的数据包响应。什么时候应该使用 sr(),什么时候应该使用 srp()?在文档中,它声明 sr() 用于 L3 数据包,而 srp() 用于 L2?但就我而言,我不确定为什么 sr() 不适用于 ICMP 数据包?有高手能帮我理解一下吗?

如果总是需要“iface”参数,也有人可以告诉我。没有那个scapy怎么知道它应该通过哪个接口发送数据包?

案例 1:sr() 函数以 iface 作为参数:

sr(icmp,iface="eth0")

开始发射:

WARNING: Mac address to reach destination not found. Using broadcast.
Finished to send 1 packets.
^C
Received 0 packets, got 0 answers, remaining 1 packets
(<Results: TCP:0 UDP:0 ICMP:0 Other:0>, <Unanswered: TCP:0 UDP:0 ICMP:1 Other:0>)

上面我没有看到来自 IP 192.168.25.1 的任何 ICMP 响应

案例 2:没有 iface 的 sr() 函数:

sr(icmp)   
.Begin emission:
......WARNING: Mac address to reach destination not found. Using broadcast.
.Finished to send 1 packets.
...............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................^C
Received 887 packets, got 0 answers, remaining 1 packets
(<Results: TCP:0 UDP:0 ICMP:0 Other:0>, <Unanswered: TCP:0 UDP:0 ICMP:1 Other:0>)

如果您看到上面收到的数据包更多,但我没有看到任何 ICMP 响应。

案例 3:使用 srp() 代替 sr() 发送 ICMP 数据包:

srp(icmp,iface="eth0")
Begin emission:
Finished to send 1 packets.
*
Received 1 packets, got 1 answers, remaining 0 packets
(<Results: TCP:0 UDP:0 ICMP:1 Other:0>, <Unanswered: TCP:0 UDP:0 ICMP:0 Other:0>)

这里我使用了 srp() 函数而不是 sr() 函数,现在我看到 ICMP 回显请求已正确发送,并且我也收到了响应。

>>> icmp.show2()
###[ Ethernet ]###
  dst: 02:00:00:11:01:03
  src: 02:00:20:ee:64:01
  type: 0x800
###[ IP ]###
     version: 4L
     ihl: 5L
     tos: 0x0
     len: 28
     id: 1
     flags:
     frag: 0L
     ttl: 64
     proto: icmp
     chksum: 0xc78c
     src: 192.168.25.2
     dst: 192.168.25.1
     \options\
###[ ICMP ]###
        type: echo-request
        code: 0
        chksum: 0xf7ff
        id: 0x0
        seq: 0x0
>>>                  

【问题讨论】:

    标签: python scapy


    【解决方案1】:

    sr 函数根据 official API documentation:

    sr(pkts, filter=None, iface=None, timeout=2, inter=0, verbose=None, chainCC=0, retry=0, multi=0)

    使用conf.L3socket 超级套接字在第 3 层发送和接收数据包。

    srp 函数:

    srp(pkts, filter=None, iface=None, timeout=2, inter=0, verbose=None, chainCC=0, retry=0, multi=0, iface hint=None)

    srp 相同,但用于在第 2 层使用conf.L2socket 超级套接字。

    由于 ICMP 数据包的第 2 层字段也已填充,如 ICMP.show2() 的输出所示,您应该使用 srp 函数。如果您像 this tutorial 中所做的那样保持它们不变,您可以使用 sr 函数。


    现在,关于您关于 ICMP 分类为第 2 层协议或第 3 层协议的问题。许多人认为它是第 3 层协议,例如 here,因为它使用 IP 标头并“位于”它之上。但是,其他人认为它是第 2 层协议,例如 hereThis is a question 在这个问题上有一些很好的答案,但请注意它们指的是 OSI 模型,因此分层方案编号有点不同。这是我设法找到的最好的,来自here

    IP 本身没有建立和维护连接的机制,甚至没有包含数据作为直接负载的机制。 Internet Control Messaging Protocol只是IP的附加,用于承载错误、路由和控制消息和数据,通常被认为是网络层的协议。

    编辑 - 我刚刚遇到 this link,并认为值得一提:

    ICMP 是 TCP/IP 堆栈中的一种协议,主要用于提供控制、故障排除和错误消息。它像 TCP 和 UDP 一样在 IP 上运行,但它是像 IP 一样的网络层协议,而不是像 TCP 和 UDP 那样的传输层协议。 (是的,这有点奇怪,ICMP 被封装在 IP 中,而与 IP 处于同一层。但话说回来,您也可以将 IP 封装在 IP 中。)

    RFC 792 也很明确:

    ICMP,使用IP的基本支持,就好像它是一个更高级别的协议,然而,ICMP实际上是IP的一个组成部分。

    RFC 1122也是如此:

    ICMP 是一种控制协议,被认为是 IP 的一个组成部分,尽管它在架构上是在 IP 上分层的,即它使用 IP 来端到端地传输其数据,就像 TCP 或 UDP 一样的传输协议确实。
    ...
    尽管 ICMP 消息封装在 IP 数据报中,但 ICMP 处理被认为是(并且通常作为)IP 层的一部分。


    关于你最后一个关于明确指定接口的问题,请参阅scapy's tutorial

    send() 函数将在第 3 层发送数据包。也就是说,它将为您处理路由和第 2 层。 sendp() 函数将在第 2 层工作。由您选择正确的接口和正确的链路层协议。

    官方API文档更详细一点:

    当 Scapy 启动时,它的路由表会与主机的路由表同步。对于在第 3 层发送的数据包,目标 IP 确定要使用的输出接口、源地址和网关。对于二层报文,可以精确输出接口,也可以通过IP的形式给出提示来确定输出接口。如果没有给出输出接口或提示,则使用conf.iface

    具体来说,iface参数用于设置输入接口(但也设置输出接口,如果iface_hint不使用):

    iface:仅在提供的界面上收听答案

    要在output 接口上进行提示,请使用iface_hint 作为第 2 层功能:

    还有一个附加参数iface_hint,它提供了一个提示,可以帮助选择正确的输出接口。默认情况下,如果iface 未指定,则选择conf.iface。提示采用第 2 层数据包可能目的地的 IP 的形式。 Scapy 路由表 (conf.route) 用于确定使用哪个接口来访问此 IP。

    【讨论】:

    • 伟大的约尔。我在没有提供 Ether() 的情况下制作了一个 ICMP 数据包,我注意到 sr() 的工作方式如前所述。我还注意到 scapy 中的路由表不同步。我重新同步了它,现在它为 sr() 采用了正确的退出 iface。感谢您的及时回复。
    猜你喜欢
    • 1970-01-01
    • 2020-05-16
    • 1970-01-01
    • 1970-01-01
    • 2020-03-24
    • 2021-03-19
    • 2015-07-28
    • 1970-01-01
    • 2013-12-26
    相关资源
    最近更新 更多