Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scapy: get/set frequency or channel of a packet

I have been trying to capture WIFI packets with Linux and see the frequency/channel at which packet was captured. I tried Wireshark and there was no luck and no help. Though using a sample packets from Wireshark, I can see the frequency/channel.

So now I'm experimenting with Scapy. I wanted to figure out the frequency/channel of a sniffed packet, but still no luck. Is there a way to do this with Scapy.

P.S. If there is a better tool than Scapy, or Python, I appreciate comments

like image 493
Aven Desta Avatar asked Mar 01 '20 08:03

Aven Desta


People also ask

Does Scapy use libpcap?

Scapy runs natively on Linux, Windows, OSX and on most Unixes with libpcap (see scapy's installation page).

What is sr1 in Scapy?

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 return one packet that answered the packet (or the packet set) sent. The packets must be layer 3 packets (IP, ARP, etc.).

What is PRN in Scapy?

The prn argument is defined as: prn: function to apply to each packet. If something is returned, it is displayed. For instance you can use prn = lambda x: x. summary().

How do you sniff packets with Scapy?

Sniffing packets using scapy: To sniff the packets use the sniff() function. The sniff() function returns information about all the packets that has been sniffed. To see the summary of packet responses, use summary(). The sniff() function listens for an infinite period of time until the user interrupts.

What is Scapy in networking?

Scapy is a packet manipulation tool for networks, written in Python. It can forge or decode packets, send them on the wire, capture them, and match requests and replies. We can use scapy to extract the TXT records as follows:

How to use Scapy to sniff packets on a network?

4.1 Scapy can also be used to sniff packets on a network very easily. When scapy is running, use the following command: #sniff() 4.2 After running the sniff() command on one virtual machine, go to the other virtual machine and send a few packets to across the virtual network using the commands from task 2.

How to send packets between two virtual machines using Scapy?

After scapy has been successfully installed on both of the virtual machines, packets can now be sent between both of them using scapy. Run scapy using the following command: #scapy 2.2 Scapy can create many different packets and send them between machines on a network. There are two useful commands to remember, which are: #ls() #ls(protocol)

What do the timestamps on a Scapy packet mean?

The timestamps appear to be the time the packet was created/rebuilt by Scapy. I would like to have better control of this, but I have not yet found a way to do that. Please leave a comment if you know of a way to do this!


2 Answers

I 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 and not from my live wireshark capture is because some network adapters do not add RadioTap while others do and the network adapter of my laptop does not add RadioTab headers. I checked this with a new external WiFi adapter and it did add the RadioTap headers.

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

So to my main question, how to get/set frequency of a packet. I expected Scapy to have this option but it doesn't, and it shouldn't. The reason is that the frequency depends on what is set on the network adapter. So what I did was to set the frequency/channel of my WiFi adapter to a different one. My external WiFi adapter can work in various channels so I changed each and confirmed with the RadioTap header. There are a simple linux commands/tools that helped me check the supported channels of my WiFi interface, and switch to a particular channel.

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.

EDIT - Other problems I faced and solutions:

If you are on linux, and you want to change the working channel of your interface you need to disable network-manager for that interface and to do this First Add the following snippet to /etc/network/interfaces

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

replace $iface with your interface name. This will let you control the interface by yourself. And then add the following lines to /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
}

Note that 2412 2437 2462 are the frequencies (channel 1, 6, 11 in this case) for your interface to choose from. You can edit them to desired frequency. Source. But first you have to check that your interface supports these frequencies. To check that

iwlist channel

Finally after everything is done.

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

This will send you packets at the frequency that wlp3s0 is set.

like image 99
Aven Desta Avatar answered Oct 10 '22 02:10

Aven Desta


This answer is scoped to the question's title and content: Providing getters and setters for frequency and channel of a packet.

For this solution, use the wpa-Induction.pcap file in Wireshark's Sample Captures.

Poking around

It's useful to poke around one packet to see what fields Scapy has access to in the Scapy interpreter.

>>> 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> ...

While 2412 is a frequency and NOT a channel, this is the data we want. RadioTap is the layer per pkts[0].summary(). Putting it together,

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

Scapy does not provide access to the channel, but it's trivial to convert frequency to channel.

Putting it Together

Getting the Frequency

Given a file and packet number, we can now get the channel and frequency for a packet.

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))

Setting the Frequency

Let's say we wanted to change the frequency to 5300 and save it. This would only require iterating over the packet list, change the frequency for every packet, and saving the result. In the scapy interpreter:

>>> for i in range(len(pkts)):
...     pkts[i][RadioTap].Channel = 5300
>>> wrpcap('temp.pcap', pkts)
>>> pkts2 = rdpcap('temp.pcap')
>>> pkts[0].Channel
5300
like image 20
Ross Jacobs Avatar answered Oct 10 '22 01:10

Ross Jacobs