mcpField
P
performing-wireless-security-assessment-with-kismet

performing-wireless-security-assessment-with-kismet

github.com/mukul975セキュリティ35.2k87 回インストール8 週間前に更新
リポジトリ

performing-wireless-security-assessment-with-kismet について

Kismetを使い、無線ネットワークを受動的に評価するためのセキュリティチーム向けスキルです。設定、取得、分析を通じて、不正なアクセスポイントや弱い暗号化、クライアントの挙動を調べます。

主な機能

  1. 01802.11フレームの受動的な取得
  2. 02アクセスポイントとクライアントの識別
  3. 03暗号化方式と隠しネットワークの確認
  4. 04未許可アクセスポイントの検出
  5. 05クライアントのプローブ要求分析

活用シーン

  1. 01許可を得た無線セキュリティ評価
  2. 02未許可アクセスポイントの調査
  3. 03無線暗号化設定の確認
  4. 04クライアントのプローブ挙動の調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill performing-wireless-security-assessment-with-kismet

インストール後、Claude Code で/performing-wireless-security-assessment-with-kismetを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

LICENSE
references/
api-reference.md
scripts/
agent.py

詳細

Kismet を使用したワイヤレスセキュリティ評価

概要

Kismet は、802.11a/b/g/n/ac/ax に対応するオープンソースのワイヤレスネットワーク検出ツール、パケットスニファー、ワイヤレス侵入検知システム(WIDS)です。アクティブスキャナーとは異なり、Kismet はパッシブモニターモードで動作するため、評価対象のネットワークから検知されません。パケットを送信せずに、生の 802.11 フレームをキャプチャし、アクセスポイント、クライアント、プローブ要求、暗号化方式を特定します。このスキルでは、包括的なワイヤレスセキュリティ評価を実施するための Kismet の導入、不正なアクセスポイントの特定、脆弱な暗号化の検出、隠れたネットワークのマッピング、クライアントの動作分析について説明します。

使用する場面

  • Kismet を使用したワイヤレスセキュリティ評価を含むセキュリティ評価を実施する場合
  • 関連するセキュリティイベントに対するインシデント対応手順に従う場合
  • 定期的なセキュリティテストや監査を実施する場合
  • 実地テストを通じてセキュリティ制御を検証する場合

前提条件

  • Kismet 2023 以降がインストールされた Linux システム(Kali Linux、Ubuntu 22.04 以降)
  • モニターモードに対応したワイヤレスアダプター(例:Alfa AWUS036ACH、TP-Link TL-WN722N v1)
  • ワイヤレス評価の書面による許可(法的要件)
  • GPS 受信機(任意。地理位置マッピング用)
  • 対象環境のワイヤレスネットワークに関するドキュメント

主な概念

Kismet のアーキテクチャ

Kismet はクライアント・サーバーアーキテクチャを使用します。

  • kismet - パケットをキャプチャして処理するメインサーバープロセス
  • kismet_cap_linux_wifi - Linux WiFi インターフェース用のキャプチャソース
  • kismet_cap_linux_bluetooth - Bluetooth 用のキャプチャソース
  • Web UI - http://localhost:2501 のブラウザーベースのインターフェース
ワイヤレスフレームの種類
フレームの種類目的セキュリティ上の関連性
ビーコンAP が自身の存在を通知しますSSID、暗号化方式、ベンダー
プローブ要求クライアントがネットワークを検索します優先ネットワークが明らかになります
プローブ応答AP がクライアントのプローブに応答します隠された SSID が開示されます
認証クライアントが AP に対して認証します認証方式の特定
認証解除クライアントを AP から切断します攻撃の可能性を示す指標
アソシエーションクライアントがネットワークに参加しますクライアントと AP の関係
暗号化の評価
暗号化方式状態リスク
オープン(暗号化なし)安全でない重大 - すべての通信を傍受できます
WEP破られています重大 - 数分で解読可能です
WPA-TKIP非推奨高 - 既知の脆弱性があります
WPA2-PSK (CCMP)許容可能中 - パスフレーズの強度によります
WPA2-Enterprise (802.1X)推奨低 - 証明書ベースです
WPA3-SAEベストプラクティス低 - オフライン攻撃への耐性があります

ワークフロー

ステップ 1:ワイヤレスアダプターを準備する
# Identify wireless interfaces
iwconfig

# Check adapter capabilities
iw list | grep -A 10 "Supported interface modes"

# Kill processes that may interfere
sudo airmon-ng check kill

# Enable monitor mode
sudo ip link set wlan0 down
sudo iw dev wlan0 set type monitor
sudo ip link set wlan0 up

# Verify monitor mode
iw dev wlan0 info | grep type
ステップ 2:Kismet を設定して起動する

/etc/kismet/kismet.conf を編集します。

# Data sources
source=wlan0:name=WiFi-Monitor,channel_hop=true,channel_hoprate=5/sec

# Logging configuration
log_types=kismet,pcapng
log_prefix=/opt/kismet/logs/assessment

# Enable all 802.11 channels (2.4GHz and 5GHz)
channel_hop_speed=5
channel_list=IEEE80211:1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,149,153,157,161,165

# GPS configuration (if available)
gps=gpsd:host=localhost,port=2947

# Alert configuration
alert=ADVCRYPTCHANGE,5/min,1/sec
alert=BSSTIMESTAMP,5/min,1/sec
alert=CRYPTODROP,5/min,1/sec
alert=DISASSOCTRAFFIC,10/min,1/sec
alert=DEAUTHFLOOD,10/min,2/sec
alert=PROBENOMFP,5/min,1/sec

Kismet を起動します。

# Start Kismet server
sudo kismet -c wlan0

# Access web interface
# Open browser to http://localhost:2501
# Default credentials: kismet / kismet (change immediately)
ステップ 3:評価スキャンを実施する

不正なアクセスポイントの検出:

# Export device list via Kismet REST API
curl -u kismet:kismet http://localhost:2501/devices/summary/devices.json | \
    python3 -m json.tool > all_devices.json

# Filter for access points
curl -u kismet:kismet \
    'http://localhost:2501/devices/summary/devices.json' \
    -d 'json={"fields":["kismet.device.base.macaddr","kismet.device.base.name","kismet.device.base.type","kismet.device.base.crypt","kismet.device.base.channel","kismet.device.base.manuf","dot11.device/dot11.device.advertised_ssid_map/dot11.advertisedssid.ssid"]}' \
    > access_points.json

クライアントのプローブ分析:

プローブ要求から、クライアントが以前接続したネットワークが明らかになります。これは、次のことを示している可能性があります。

  • 企業デバイスが安全でない家庭内ネットワークに接続している
  • 既知の悪意ある SSID をデバイスが検索している(イービルツインの影響を受けやすい)
  • 企業内に個人所有の未承認デバイスが存在する
ステップ 4:結果を分析する

Kismet データベース用の Python 分析スクリプト:

#!/usr/bin/env python3
"""Analyze Kismet capture database for wireless security findings."""

import sqlite3
import json
import sys
from collections import defaultdict


def analyze_kismet_db(db_path: str):
    """Analyze Kismet SQLite database for security issues."""
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()

    findings = []

    # Query all devices
    cursor.execute("""
        SELECT devmac, type, device
        FROM devices
    """)

    devices = cursor.fetchall()
    ap_count = 0
    client_count = 0
    open_networks = []
    wep_networks = []
    wpa_tkip_networks = []
    hidden_networks = []
    all_aps = []

    for mac, dev_type, device_json in devices:
        try:
            device = json.loads(device_json)
        except json.JSONDecodeError:
            continue

        base = device.get('kismet.device.base.type', '')

        if 'Wi-Fi AP' in base or 'Wi-Fi Device' in base:
            ap_count += 1
            ssid_map = device.get('dot11.device', {}).get(
                'dot11.device.advertised_ssid_map', []
            )
            crypt = device.get('kismet.device.base.crypt', '')
            name = device.get('kismet.device.base.name', 'Unknown')
            channel = device.get('kismet.device.base.channel', '')
            manuf = device.get('kismet.device.base.manuf', 'Unknown')

            ap_info = {
                'mac': mac,
                'ssid': name,
                'encryption': crypt,
                'channel': channel,
                'manufacturer': manuf,
            }
            all_aps.append(ap_info)

            if 'None' in crypt or crypt == '':
                open_networks.append(ap_info)
            elif 'WEP' in crypt:
                wep_networks.append(ap_info)
            elif 'WPA+TKIP' in crypt and 'AES' not in crypt:
                wpa_tkip_networks.append(ap_info)

            for ssid_entry in ssid_map:
                if isinstance(ssid_entry, dict):
                    ssid = ssid_entry.get('dot11.advertisedssid.ssid', '')
                    if ssid == '' or ssid is None:
                        hidden_networks.append(ap_info)

        elif 'Wi-Fi Client' in base:
            client_count += 1

    # Generate findings
    print(f"\n{'='*70}")
    print("WIRELESS SECURITY ASSESSMENT REPORT")
    print(f"{'='*70}")
    print(f"\nTotal Access Points Detected: {ap_count}")
    print(f"Total Clients Detected: {client_count}")

    if open_networks:
        print(f"\n[CRITICAL] Open Networks (No Encryption): {len(open_networks)}")
        for net in open_networks:
            print(f"  - SSID: {net['ssid']}, MAC: {net['mac']}, "
                  f"Channel: {net['channel']}, Vendor: {net['manufacturer']}")

    if wep_networks:
        print(f"\n[CRITICAL] WEP-Encrypted Networks: {len(wep_networks)}")
        for net in wep_networks:
            print(f"  - SSID: {net['ssid']}, MAC: {net['mac']}, "
                  f"Channel: {net['channel']}")

    if wpa_tkip_networks:
        print(f"\n[HIGH] WPA-TKIP Networks (Deprecated): {len(wpa_tkip_networks)}")
        for net in wpa_tkip_networks:
            print(f"  - SSID: {net['ssid']}, MAC: {net['mac']}, "
                  f"Channel: {net['channel']}")

    if hidden_networks:
        print(f"\n[MEDIUM] Hidden SSIDs Detected: {len(hidden_networks)}")
        for net in hidden_networks:
            print(f"  - MAC: {net['mac']}, Channel: {net['channel']}, "
                  f"Vendor: {net['manufacturer']}")

    # Channel utilization analysis
    channel_usage = defaultdict(int)
    for ap in all_aps:
        ch = ap.get('channel', 'Unknown')
        channel_usage[ch] += 1

    print(f"\n[INFO] Channel Utilization:")
    for ch, count in sorted(channel_usage.items()):
        print(f"  Channel {ch}: {count} APs")

    conn.close()


if __name__ == '__main__':
    db_path = sys.argv[1] if len(sys.argv) > 1 else 'Kismet-*.kismet'
    analyze_kismet_db(db_path)
ステップ 5:不正なアクセスポイントを検出する

検出された AP を許可済みのインベントリと照合します。

#!/usr/bin/env python3
"""Detect rogue access points by comparing against authorized AP list."""

import json
import sys


def load_authorized_aps(filepath: str) -> set:
    """Load authorized AP MAC addresses from file."""
    authorized = set()
    with open(filepath, 'r') as f:
        for line in f:
            mac = line.strip().lower()
            if mac and not mac.startswith('#'):
                authorized.add(mac)
    return authorized


def detect_rogues(kismet_json: str, authorized_file: str):
    """Compare discovered APs against authorized list."""
    authorized = load_authorized_aps(authorized_file)

    with open(kismet_json, 'r') as f:
        devices = json.load(f)

    rogues = []
    for device in devices:
        mac = device.get('kismet.device.base.macaddr', '').lower()
        dev_type = device.get('kismet.device.base.type', '')

        if 'AP' in dev_type and mac not in authorized:
            rogues.append({
                'mac': mac,
                'ssid': device.get('kismet.device.base.name', 'Unknown'),
                'encryption': device.get('kismet.device.base.crypt', ''),
                'channel': device.get('kismet.device.base.channel', ''),
                'manufacturer': device.get('kismet.device.base.manuf', ''),
                'signal': device.get('kismet.device.base.signal', {}).get(
                    'kismet.common.signal.last_signal', 0),
            })

    if rogues:
        print(f"\n[ALERT] {len(rogues)} ROGUE ACCESS POINTS DETECTED\n")
        for rogue in rogues:
            print(f"  MAC: {rogue['mac']}")
            print(f"  SSID: {rogue['ssid']}")
            print(f"  Encryption: {rogue['encryption']}")
            print(f"  Channel: {rogue['channel']}")
            print(f"  Vendor: {rogue['manufacturer']}")
            print(f"  Signal: {rogue['signal']} dBm")
            print()
    else:
        print("No rogue access points detected.")


if __name__ == '__main__':
    if len(sys.argv) < 3:
        print("Usage: python detect_rogues.py <kismet_devices.json> <authorized_aps.txt>")
        sys.exit(1)
    detect_rogues(sys.argv[1], sys.argv[2])

評価チェックリスト

  • 許可済みの AP をすべて特定し、検証した
  • 不正/未承認の AP を特定し、場所を確認した
  • すべての SSID の暗号化方式を記録した
  • 隠れた SSID を検出し、記録した
  • クライアントのプローブ要求を分析し、機微なパターンを確認した
  • イービルツインの影響を受けやすいか評価した
  • すべての AP で WPS の状態を確認した
  • 電波のカバレッジ範囲をマッピングした
  • ゲストネットワークの分離を検証した
  • 管理インターフェースがワイヤレスネットワーク上に公開されていないことを確認した

ベストプラクティス

  • 書面による承認 - 無線評価を実施する前に、必ず署名済みの承認を得てください
  • パッシブモードのみ - Kismet はパッシブモードで使用し、認証解除フレームやプローブリクエストを送信しないでください
  • 包括的なチャネルカバレッジ - DFS チャネルを含む 2.4GHz 帯と 5GHz 帯の両方をスキャンしてください
  • 複数の場所 - 完全なカバレッジを得るため、複数の物理的な場所でキャプチャを実行してください
  • 実施時間 - 断続的に通信するデバイスを観察するため、少なくとも 30~60 分間キャプチャしてください
  • GPS マッピング - GPS を使用してヒートマップを作成し、信号の境界を分析してください
  • ベースラインとの比較 - 承認済み AP の一覧を管理し、各評価の結果と比較してください

参考資料

コメント