
デバイスの優先ネットワークリストからSSIDをキャプチャして表示する偵察ツール。

プリファードネットワークリストスニファ (PNLS) は、シンプルなWebインターフェースを備えたレッドチーム向けWi-Fi監査ツールであり、デバイスのプリファードネットワークリスト (PNL)1 からSSID2を傍受することができます。これは、周辺の プローブリクエスト をスニッフィングし、そこからSSIDやその他の情報を解析し、最終的にWeb UIに伝搬することで実現されます。このプロジェクトの主な動機は、802.11プローブリクエストと、それらが送信するデータに関連するプライバシーリスクを調査することでした。
図 1: PNLS システム概要
[!WARNING] このプロジェクトのすべてのコンテンツは、セキュリティ研究目的のみを対象としています。
[!NOTE]
このプロジェクトは、Wi-Fiネットワークにおけるプライバシー保護に関する現在進行中の研究の一部です。
PNLS の進行中の作業を監視するには、プロジェクトのボードを参照してください。
このプロジェクトを複製してデプロイするために必要なもの(ハードウェアおよびソフトウェアコンポーネントの両方)を以下に示します。作業環境の準備ができたら、セットアップセクションに進んでください。
sudo airmon-ng start wlan0 [2].[!NOTE]
Re4sonのカーネルを使用するKaliイメージには、外部Wi-Fiカード用のドライバと、RPi 3および4の内蔵ワイヤレスカード用のNexmonファームウェアが含まれています[3]。
図 2: 外部アンテナとバッテリーバンクを備えたRPi 4で動作するPNLS
図 3: AWUS036ACSアンテナを搭載したケースに入ったRPi 4で動作するPNLS
図 4: AWUS036ACMアンテナを搭載したRPi 4で動作するPNLS
Dockerを使用したくない場合は、Dockerなしのセットアップに進んでください。
開発インスタンスを迅速にセットアップします:
# First clone this repo.
git clone https://github.com/AleksaMCode/Preferred-Network-List-Sniffer.git
# Move to the project root folder.
cd Preferred-Network-List-Sniffer
# Build backend and frontend image.
docker compose build
# Bring up both the backend and the frontend server.
docker compose up
# Move into the sniffer folder.
cd sniffer
# Run the Sniffer service.
sudo python3 sniffer.py
現在、マルチプラットフォームイメージは利用できず、プロジェクトはARM64v8アーキテクチャのみをサポートしています。最新のプレビルドイメージをGitHub Container Registryからダウンロードし、ローカルで実行してください。
# First clone this repo.
git clone https://github.com/AleksaMCode/Preferred-Network-List-Sniffer.git
# Move to the project root folder.
cd Preferred-Network-List-Sniffer
# Download the prebuild images.
docker pull ghcr.io/aleksamcode/pnls-backend-ghcr:latest
docker pull ghcr.io/aleksamcode/pnls-frontend-ghcr:latest
# Bring up both the backend and the frontend server.
docker compose up
# Move into the sniffer folder.
cd sniffer
# Run the Sniffer service.
sudo python3 sniffer.py
バックエンド: ASGIサーバーとRedisサーバーを起動し、必要なサービスを実行するには、これらの手順を参照してください。
フロントエンド: Reactサーバーを実行するには、これらの手順を参照してください。
以下は、すべてを「手動」で実行したときのスクリーンショットです:
図 5: PNLSのスクリーンショット
プローブリクエストは、デバイスを以前に関連付けられたワイヤレスアクセスポイント (AP) に接続するために使用される管理802.11フレームです。デバイスがWi-Fiを有効にしているがネットワークに接続していない場合、定期的にPNLのSSIDを含むプローブリクエストのバーストを送信します。これらのフレームは暗号化されずに送信され、無線周波数 (RF) を監視している誰でもキャプチャして読み取ることができます。プローブはブロードキャストDAアドレス (ff:ff:ff:ff:ff:ff) に送信されます。送信後、デバイスはプローブタイマーを開始します。タイマーの終了時に、デバイスは受信した応答を処理します。応答を受信しなかった場合、デバイスは次のチャンネルに移動してプロセスを繰り返します。プローブリクエストには2つのタイプがあります:
ダイレクトプローブリクエスト: デバイスのPNLの特定のSSIDを使用
ヌルプローブリクエスト: ワイルドカードSSID(空のSSID)を使用
ブランクリクエストは、範囲内のすべての利用可能なAPから応答を得るために送信されます。
キャプチャされたすべてのパケットから802.11プローブリクエストフレームをフィルタリングすることに加えて、スニファはワイルドカードSSIDもフィルタリングします。
多くのWi-Fiクライアントが存在する大規模なローカルネットワークがある場所でプローブリクエストをキャプチャすると、PNLSは必然的にそのネットワークのSSIDを含む多くのプローブリクエストをキャプチャします。そのようなSSIDのフィルタリングは、私たちにとって価値がなく、ソケット負荷の増加を引き起こす可能性があるため、有利な場合があります。これらのSSIDをフィルタリングすると、ソケット接続の負荷が軽減されるだけでなく、Web UI上での前述のSSIDのスパムも防止できます。
この機能を使用する場合、ソースコードを少し調整する必要があります。具体的には、settings.pyファイル内のSSID_FILTERリストを、スニファが無視する値に更新する必要があります。更新後、プロジェクトを再構築してPNLSを起動してください。
このプロジェクトは、メッセージ駆動アーキテクチャの上に設計されたイベント駆動アーキテクチャ (EDA) を使用しています。このプロジェクトは集中型ソリューション(すべてがRPiから実行される)を使用していますが、EDAの使用による疎結合コンポーネントのため、必要に応じて分散型ソリューションを作成することが可能です。PNLSは、イベントパブリッシャー(スニファ)、イベントコンシューマー(Webアプリケーション)、およびイベントチャネルで構成されています。ここでは、イベントチャネルはメッセージ指向ミドルウェア (MOM) として実装されています。
図 6: PNLSシステムデプロイメント図
Asynchronous Server Gateway Interface (ASGI) は、非同期対応のPython Webサーバーとサービスの間の標準化されたインターフェースを提供します [4]。ASGIが選ばれたのは、異なるクライアント間の非同期通信を促進するために、長期間のWebSocket接続が必要だったからです。さらに、API呼び出し中にバックグラウンドコルーチンを利用することも可能にします。PNLSは、ASGI Webサーバーを使用するために、Python用のuvicorn実装を使用しています。
WebSocket通信プロトコルを利用することで、全二重の双方向通信を実現できます。このプロジェクトでは双方向通信の必要性はありませんが、システムコンポーネント間のリアルタイムの相互作用が必要です。この方法により、スニッフィングされたデータはキャプチャされ次第、エンドユーザーが利用できるようになります。
プロジェクトのMOMは、Redisを使用したメッセージブローカーによって実現されます。パブリッシュ-サブスクライブ(pub-sub)モデルでは、スニファがメッセージの生成を担当し、Webアプリケーション(サブスクライバー)が特定のトピック(Redisチャネル)に登録します。スニファがトピックにメッセージを送信すると、すべてのサブスクライブされたコンシューマーに配信され、非同期でスケーラブルな通信が可能になります。PNLSは、メッセージブロードキャストに軽量メッセージングプロトコルRedis Pub/Subを使用して、低レイテンシと大スループットで短命なメッセージを伝搬します[5][6]。これにより、データ構造をディスクに書き込める形式にエンコードする際のオーバーヘッドが回避されます。その結果、このソリューションは潜在的にパフォーマンスが向上します[7]。以下の図は、イベント駆動型ワークフローによる簡略化されたシステムアクティビティを示しています。
図 7: PNLS Pub-Subモデルのシーケンス図
[!NOTE] 実装されたMOMは、データ蓄積のための永続ストレージやメッセージキューを提供しません。つまり、サブスクライバーがいないトピックにメッセージがパブリッシュされた場合、メッセージは失われます。
以下は、公開されたテスト用SSIDを表示するWeb UIの例です。
図 8: PNLS Web - テスト用SSIDの例
https://raw.githubusercontent.com/aleksamcode/preferred-network-list-sniffer/HEAD/%E3%83%97%E3%83%AA%E3%83%95%E3%82%A1%E3%83%BC%E3%83%89%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%AA%E3%82%B9%E3%83%88%E3%81%AF%E3%80%81%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%82%92%E3%81%9D%E3%82%8C%E3%82%89%E3%81%AE%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AB%E5%88%9D%E3%82%81%E3%81%A6%E6%8E%A5%E7%B6%9A%E3%81%97%E3%81%9F%E3%81%A8%E3%81%8D%E3%81%AB%E4%BD%9C%E6%88%90%E3%81%95%E3%82%8C%E3%81%9F%E3%80%81%E8%BF%BD%E5%8A%A0%E8%A8%AD%E5%AE%9A%E3%82%92%E5%90%AB%E3%82%80%E4%BF%9D%E5%AD%98%E6%B8%88%E3%81%BFSSID%E3%81%AE%E3%82%B3%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A7%E3%81%99%E3%80%82 ↩
サービスセット識別子 (SSID) は、Wi-Fiネットワークに名前を付けるために使用される802.11 IDで、大文字と小文字を区別する英字、数字、および特殊文字を含む最大32文字で構成されます。 ↩
| PNL | プリファードネットワークリスト |
| PNLS | プリファードネットワークリストスニファ |
| SSID | サービスセット識別子 |
| UI | ユーザーインターフェース |
| RPi | Raspberry Pi |
| OS | オペレーティングシステム |
| AP | アクセスポイント |
| RF | 無線周波数 |
| EDA | イベント駆動アーキテクチャ |
| MOM | メッセージ指向ミドルウェア |
| ASGI | 非同期サーバーゲートウェイインターフェース |
| pub-sub | パブリッシュ-サブスクライブ |