Scapy: get/set 数据包的频率或通道

Scapy: get/set frequency or channel of a packet

我一直在尝试使用 Linux 捕获 WIFI 数据包,并查看捕获数据包的 frequency/channel。我尝试了 Wireshark,但没有成功,也没有来自 Wireshark 的 help. Though using a sample packets,我可以看到 frequency/channel.

所以现在我正在试验 Scapy。我想弄清楚嗅探数据包的 frequency/channel,但仍然没有运气。有没有办法用 Scapy 做到这一点。

P.S。 如果有比 Scapy 或 Python 更好的工具,欢迎评论

此答案仅限于问题的标题和内容:Providing getters and setters for frequency and channel of a packet。

对于此解决方案,请使用 wpa-Induction.pcap file in Wireshark's Sample Captures

闲逛

查看一个数据包以查看 Scapy 在 Scapy 解释器中可以访问哪些字段是很有用的。

>>> pkts = rdpcap('wpa-Induction.pcap')
>>> pkts[0].summary()
"RadioTap / Dot11FCS / Dot11Beacon / Dot11Elt / Dot11EltRates / Dot11Elt / Dot11Elt / Dot11Elt / Dot11Elt / Dot11EltRSN / Dot11Elt / Dot11EltVendorSpecific / Dot11EltMicrosoftWPA / SSID=''"
>>> pkts[0].show()
###[ RadioTap dummy ]###
  version= 0
  pad= 0
  len= 24
  present= Flags+Rate+Channel+Lock_Quality+Antenna+dB_AntSignal+RXFlags
  Flags= FCS
  Rate= 2
  Channel= 2412
  ChannelFlags= CCK+2GHz
  Antenna= 84
  notdecoded= '\x00\x00+\x00\x00\x9fa\xc9\'

... <output truncated> ...

虽然 2412 是频率,不是频道,但这是我们想要的数据。 RadioTap 是每个 pkts[0].summary() 的层。放在一起,

>>> frequency = pkts[0][RadioTap].Channel
>>> print(frequency)
2412

Scapy does not provide access到频道,但是将频率转换为频道是微不足道的。

放在一起

获取频率

给定文件和数据包编号,我们现在可以获得数据包的信道和频率。

from scapy.all import RadioTap, rdpcap

def getChannel(frequency):
    base = 2407              # 2.4Ghz
    if frequency//1000 == 5: 
        base = 5000          # 5Ghz
    # 2.4 and 5Ghz channels increment by 5
    return (frequency-base)//5

def getFrequency(file, packet_number):
  pkts = rdpcap(file)
  # Scapy mixes up Channel/Frequency here
  frequency = pkts[packet_number][RadioTap].Channel
  return frequency

freq = getFrequency('wpa-Induction.pcap', 0)
chan = getChannel(freq)
print("Channel: {0} \nFrequency: {1}".format(freq, chan))

设置频率

假设我们想将频率更改为 5300 并保存。这只需要遍历数据包列表,更改每个数据包的频率,并保存结果。在 scapy 解释器中:

>>> for i in range(len(pkts)):
...     pkts[i][RadioTap].Channel = 5300
>>> wrpcap('temp.pcap', pkts)
>>> pkts2 = rdpcap('temp.pcap')
>>> pkts[0].Channel
5300

found out that RadioTab headers are not part of any Dot11 protocol but are merely added by the network interface. And the reason I got the RadioTab headers on sample packets from Wireshark.org 而不是来自我的实时 wireshark 捕获是因为一些网络适配器不添加 RadioTap 而其他人添加并且我的笔记本电脑的网络适配器不添加 RadioTab headers。我用一个新的外部 WiFi 适配器检查了这个,它确实添加了 RadioTap headers.

If the adapter does not inject the additional information as it captures frames, then no radiotap headers will be added.

所以对于我的主要问题,如何 get/set 数据包的频率。 我希望 Scapy 有这个选项,但它没有,也不应该。原因是频率取决于网络适配器上的设置。所以我所做的是将我的 WiFi 适配器的 frequency/channel 设置为不同的。我的外部 WiFi 适配器可以在各种频道中工作,所以我更改了每个频道并使用 RadioTap header 进行了确认。有一个简单的 linux commands/tools 可以帮助我检查我的 WiFi 接口支持的频道,并切换到特定的频道。

To capture/send packets at a certain frequency or channel, you need to change the working channel of your interface and set the sniffer/sender interface in scapy to that interface.

编辑 - 我遇到的其他问题和解决方案:

如果您在 linux 上,并且您想要更改接口的工作频道,您需要为该接口禁用 network-manager 并执行此操作 第一的 将以下代码段添加到 /etc/network/interfaces

auto $iface
iface $iface inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

$iface 替换为您的接口名称。这将使您可以自己控制界面。然后将以下行添加到 /etc/wpa_supplicant/wpa_supplicant.conf

ctrl_interface=/var/run/wpa_supplicant

network={
    ssid="Your_AP_SSID"
    psk="Your_Passphrase"
    freq_list=2412 2437 2462
}

请注意,2412 2437 2462 是您的界面可供选择的频率(在本例中为频道 1、6、11)。您可以将它们编辑为所需的频率。 Source。但首先您必须检查您的接口是否支持这些频率。检查

iwlist channel

终于在一切都完成之后。

sendp(Ether()/IP(dst="1.2.3.4",ttl=(1,4)), iface="wlp3s0")

这将以 wlp3s0 设置的频率向您发送数据包。