Python Scapy --arp 请求和响应

Python Scapy --arp request and response

我用这条线发送一个arp数据包广播:

send(ARP(op=ARP.who_has, psrc="192.168.5.51", pdst=the_ip))

我的问题是:如何查看响应(在本例中:远程 ip 的 mac)?我知道我能做到:

pkt = sniff(filter=arp , count=10) 
print (pkt.summary()) 

但是我不想统计数据包,因为我不知道什么时候打印(可能在接下来的10或100个数据包中)

有没有办法在它嗅探时打印摘要,从而看到我正在寻找的 mac 地址?

编辑:我有一个想法,我可以嗅探 10 个数据包吗,如果数据包中有 ip,则打印 mac 地址,否则再嗅探 10 个数据包......这种技术似乎没有做一个好人...

Scapy's user manual建议使用sr()sr1()函数发送包和接收应答:

The sr() function is for sending packets and receiving answers. The function returns a couple of packet and answers, and the unanswered packets. The function sr1() is a variant that only returns one packet that answered the packet (or the packet set) sent. The packets must be layer 3 packets (IP, ARP, etc.). The function srp() does the same for layer 2 packets (Ethernet, 802.3, etc.)

The official API documentation 指定他们的完整签名。这些似乎是这个用例的相关参数:

retry: if positive, how many times to resend unanswered packets. if negative, how many consecutive unanswered probes before giving up. Only the negative value is really useful.
timeout: how much time to wait after the last packet has been sent. By default, sr will wait forever and the user will have to interrupt (Ctrl-C) it when he expects no more answers.
inter: time in seconds to wait between each packet sent.

这里是sr()函数的执行示例:

In [1]: from scapy.all import *
WARNING: No route found for IPv6 destination :: (no default route?)

In [2]: results, unanswered = sr(ARP(op=ARP.who_has, psrc='192.168.1.2', pdst='192.168.1.1'))
Begin emission:
.....*Finished to send 1 packets.

Received 6 packets, got 1 answers, remaining 0 packets

In [3]: results
Out[3]: <Results: TCP:0 UDP:0 ICMP:0 Other:1>

In [4]: result = results[0]

In [5]: result
Out[5]: 
(<ARP  op=who-has psrc=192.168.1.2 pdst=192.168.1.1 |>,
 <ARP  hwtype=0x1 ptype=0x800 hwlen=6 plen=4 op=is-at hwsrc=XX:XX:XX:XX:XX:XX psrc=192.168.1.1 hwdst=XX:XX:XX:XX:XX:XX pdst=192.168.1.2 |>)

In [6]: original_packet, answer = result

In [7]: original_packet
Out[7]: <ARP  op=who-has psrc=192.168.1.2 pdst=192.168.1.1 |>

In [8]: answer
Out[8]: <ARP  hwtype=0x1 ptype=0x800 hwlen=6 plen=4 op=is-at hwsrc=XX:XX:XX:XX:XX:XX psrc=192.168.1.1 hwdst=XX:XX:XX:XX:XX:XX pdst=192.168.1.2 |>

In [9]: answer.hwsrc
Out[9]: 'XX:XX:XX:XX:XX:XX'

这里是sr1()函数的执行示例:

In [10]: result = sr1(ARP(op=ARP.who_has, psrc='192.168.1.2', pdst='192.168.1.1'))
Begin emission:
.....Finished to send 1 packets.
*
Received 6 packets, got 1 answers, remaining 0 packets

In [11]: result
Out[11]: <ARP  hwtype=0x1 ptype=0x800 hwlen=6 plen=4 op=is-at hwsrc=XX:XX:XX:XX:XX:XX psrc=192.168.1.1 hwdst=XX:XX:XX:XX:XX:XX pdst=192.168.1.2 |>

In [12]: result.hwsrc
Out[12]: 'XX:XX:XX:XX:XX:XX'

注意: 演示了如何提取 MAC 地址,并且编辑了此答案以反映它。

我知道这是一个迟到的答案,但对于其他人来说,根据最新版本的 scapy,您可以通过索引从该 arp 响应中提取 mac,例如:

如果你做了这样的事情:

pkt = Ether(dst='ff:ff:ff:ff:ff')/ARP(pdst='192.168.43.1')
ans,unans = sendp(pkt)

然后你可以用

提取远程ip的mac
ans[0][1][ARP].hwsrc

据我所知,您无法使用正则表达式提取它。上面的代码将为您提供字符串格式的 mac 地址。

同样,您可以通过弄乱索引,通过反复试验来提取所有其他字段。