8

Linux 上の Python から、802.11 管理の「プローブ要求」フレームを盗聴したいと思います。これは、次のように Scapy から可能です。

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

または、次のように tshark から:

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

tshark からの出力をリダイレクトし、Python で丸呑みすることもできます (きれいではありませんが、機能します)。

ただし、これらのオプションには両方とも GPL ライセンスが適用されるため、潜在的な商用プロジェクトは扱いにくいものになります。したがって、この特定の問題に対してPythonで「低レベル」のソリューションを見つけようとしています。Google から、次の 2 つの方向性を試すことができました。

  1. Pcap ライブラリ: Python で使用できる 3 つの pcap ライブラリがあるようです: pylibpcappypcap、およびpcapy。上記の機能をこれらに組み込む方法がよくわかりません。サンプルコードやソリューションは素晴らしいでしょう。

  2. 生のソケット: PF_PACKET: "パケット ソケットは、デバイス ドライバー (OSI レイヤー 2) レベルで生のパケットを送受信するために使用されます。ユーザーは、物理層の上のユーザー空間にプロトコル モジュールを実装できます。"

これは、pcap を完全にバイパスする別のオプションのように思えます。これは、pcap ライブラリのオーバーヘッドを取り除くより良いアプローチである可能性があるというコメントを聞いたことがあります。ただし、どこからこれに取り組み始めればよいかわかりません。

これを解決するための助けをいただければ幸いです。

4

1 に答える 1

8

私はなんとかこれを解決することができました。これが私が経験したプロセスです:

  1. いくつかの802.11管理の「プローブ要求」フレームをキャプチャします。

    tshark -n -i mon0 subtype probereq -c 5 -w probe.pcap
    
  2. RadioTapを理解する

    RadioTapのドキュメントを読んで、 RadioTapフレームが次のフィールドで構成されていることに気付きました。

    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
    

    したがって、it_lenを使用すると、radiotapデータに続く802.11フレームの先頭を見つけることができます。

  3. Pythonのコーディングソリューション

    以前の投稿で見つけた3つのpcapライブラリオプションからpylibpcap を使用することを選択し、 802.11フレームを解析するためのdpktモジュールを発見しました。ドキュメントは非常に薄いため、Pythonインタープリターで再生することにより、キャプチャファイルからMACを抽出し、SSIDをプローブし、信号強度を取得するために、次のコードを作成することができました。

    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)
    
于 2013-03-06T00:25:51.200 に答える