Accessing 802.11 Wireless Management Frames from Python

喜夏-厌秋 提交于 2019-12-05 22:19:16

问题


From Python on Linux I would like to sniff 802.11 management 'probe-request' frames. This is possible from Scapy like so:

# -*- coding: utf-8 -*-
from scapy.all import *

def proc(p):
        if ( p.haslayer(Dot11ProbeReq) ):
                mac=re.sub(':','',p.addr2)
                ssid=p[Dot11Elt].info
                ssid=ssid.decode('utf-8','ignore')
                if ssid == "":
                        ssid="<BROADCAST>"
                print "%s:%s" %(mac,ssid)

sniff(iface="mon0",prn=proc)

Or from tshark like so:

tshark -n -i mon0 subtype probereq -R 'wlan.fc.type_subtype eq 4' -T fields -e wlan.sa -e wlan_mgt.ssid

We could redirect the output from tshark, and slurp it up with some Python (not pretty, but it works).

However, both of these options have GPL licensing, which makes potential commercial projects tricky. I'm therefore trying to figure out a 'lower level' solution in Python for this specific problem. From Google I've managed to work out two potential directions to try:

  1. Pcap libraries: There seem to be three pcap libraries available for Python: pylibpcap, pypcap, and pcapy. I'm not too sure how to approach incorporating the above functionality into these. Any sample code or solutions would be great.

  2. Raw sockets: PF_PACKET: "Packet sockets are used to receive or send raw packets at the device driver (OSI Layer 2) level. They allow the user to implement protocol modules in user space on top of the physical layer."

This sounds like it could be another option, bypassing pcap altogether. I've heard comments that this may even be a better approach, removing the overhead of pcap libraries. I'm not sure where to start tackling this, though.

Any help in solving this would be greatly appreciated.


回答1:


I've managed to work this out. Here's the process I went through:

  1. Capture some 802.11 management 'probe-request' frames:

    tshark -n -i mon0 subtype probereq -c 5 -w probe.pcap
    
  2. Understand RadioTap

    Reading RadioTap documentation, I realised that RadioTap frames are comprised of the following fields:

    it_version (2 bytes) - major version of the radiotap header is in use. Currently, this is always 0
    it_pad (2 bytes) - currently unused 
    it_len (4 bytes) - entire length of the radiotap data, including the radiotap header
    it_present (8 byte) - bitmask of the radiotap data fields that follows the radiotap header
    

    Therefore the it_len allows us to locate the beginning of the 802.11 frame that follows the radiotap data.

  3. Coding solution in Python

    I chose to use pylibpcap from three pcap library options I found in my previous post, and discovered the dpkt module for parsing 802.11 frames. Documentation was very thin, so by playing in the Python interpreter I managed to work out the following code to extract MAC, probe SSID, and signal strength from our capture file:

    f = open('probe.pcap')
    pc = dpkt.pcap.Reader(f)
    dl=pc.datalink()
    if pc.datalink() == 127: #Check if RadioTap
            for timestamp, rawdata in pc:
                    tap = dpkt.radiotap.Radiotap(rawdata)
                    signal_ssi=-(256-tap.ant_sig.db)        #Calculate signal strength
                    t_len=binascii.hexlify(rawdata[2:3])    #t_len field indicates the entire length of the radiotap data, including the radiotap header.
                    t_len=int(t_len,16)                     #Convert to decimal
                    wlan = dpkt.ieee80211.IEEE80211(rawdata[t_len:])
                    if wlan.type == 0 and wlan.subtype == 4: # Indicates a probe request
                        ssid = wlan.ies[0].info
                        mac=binascii.hexlify(wlan.mgmt.src)
                        print "%s, %s (%d dBm)"%(mac,ssid,signal_ssi)
    


来源:https://stackoverflow.com/questions/15214189/accessing-802-11-wireless-management-frames-from-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!