Deauthentication AttackとBeacon Flood Attackについて

Wifiに対する攻撃手法について調べる機会があったのですが、日本語の資料が無かったので個人的メモも兼ねて書いてみました。 そのうち別の攻撃手法について取り上げるかもしれませんが、とりあえずDeauthentication AttackとBeacon Flood Attackについてです。
どちらもIEEE 802.11プロトコルに対するDoS攻撃であり、WiFiを対象にした攻撃です。

Deauthentication Attackとは

Deauthentication Attackの前に、認証解除フレームの説明をします。IEEE 802.11プロトコルには、クライアントがAPからの切断をしたい場合、認証解除フレームを使う仕様があります。
認証解除フレームは

  1. クライアントが認証解除フレームを送信する
  2. APが認証解除フレームを受信する
  3. APが応答フレームを送信する
  4. クライアントが応答フレームを受信する

という流れで行われます。
このとき、認証解除フレームに含まれる情報はいくつかあるのですが、この通信では送信されるクライアントのMACアドレスが暗号化されず平文で通信されるという仕様があります。
Deauthentication AttackはこのクライアントのMACアドレスが暗号化されずに通信するという仕様を悪用した攻撃手法です。以下は攻撃者視点での攻撃の流れです。

  1. victimのMACアドレスを入手する
  2. victimの接続しているAPのMACアドレスを入手する
  3. victimのMACアドレスに偽装し、認証解除フレームを送信

これでvictimのAPとの接続が切断されます。

ちなみにDeauthentication Attackは直訳すると認証解除攻撃になります。

Beacon Flood Attackとは

まず、IEEE 802.11プロトコルのBeacon Frameについての軽い説明をします。
Beacon FrameはWLANの管理フレームの1つで、基本的にはAP側から送信されます。 このとき送信される情報には以下のようなものが含まれます。

  • Timestamp
  • Beacon interval
  • Capability
  • SSID elements
  • Supported rates element
  • Direct sequence (DS) parameter set element
  • Contention Free (CF) parameter set element (任意)

IEEE 802.11 WLAN - ビーコン フレーム - MATLAB & Simulink - MathWorks 日本 より引用

Beacon Flood Attackは、このWiFiのアクセスポイントを知らせるためのBeacon Frameを大量に送信する攻撃です。
これはAPを探しているクライアントに対してDoSを仕掛け、正常なAPへの接続を妨害します。APを探しているクライアントは大量のビーコンフレームを受信してしまい、偽のAPの中から正しいAPに接続することが困難になります。(BSSIDを覚えているような変態を除く)

まとめ

調べてみると意外とIEEE 802.11の仕様が面白かったりします。ちなみにDeauthentication Attackは4Way-Handshakeの盗聴につながったり、攻撃者の送信しているアクセスポイントへの接続を強制されたりと以外と危険だったりします。

WiresharkのPluginを作ってみた

はじめに

某CTFの問題で、USBのインタラプト転送のパケットをキーコード表とにらめっこしながら解くのが苦痛だったので読み込んだらフィールドに表示してくれるPlaginを作ってみました。
使用言語ですが、ささっと作りたかったのでluaでの実装です。

GitHub - somebodyN/Wireshark_Plugins

ソースコード

KEYCODE = {
    [0x00] = 0、
     ︙
    [0xE7] = "RIGHT GUI"
}


-- Create Protocol
proto = Proto("In_USB", "Interrupt-in_USB protocol")

-- Create Fields
local fields = proto.fields

fields.InputData = ProtoField.uint8("proto.data", "IN", base.HEX, KEYCODE)

function proto.dissector(buffer, pinfo, tree)
    pinfo.cols.protocol = proto.name

    local subtree = tree:add(proto, buffer(), "DATA")

    for i = 0, buffer:len()-1 do
        subtree:add(fields.InputData, buffer(i, 1))
    end
end

usb_table = DissectorTable.get("usb.interrupt")
usb_table:add(0xff, proto)
usb_table:add(0xffff, proto)

解説

内容ですが、最初に取得したデータをキーコードに変換するためのテーブルを定義しています。
そのテーブルを使い、以下の部分でHEXで取得したデータをキーコードに変換しています。

fields.InputData = ProtoField.uint8("proto.data", "IN", base.HEX, KEYCODE)

Dissectorではdata部分をすべて受け取り、1バイトづつサブツリーに追加しています。
最後にUSBのプロトコルで使用したいので

usb_table = DissectorTable.get("usb.interrupt")

でUSBのdissectorテーブルを取得して

usb_table:add(0xff, proto)
usb_table:add(0xffff, proto)

の2行で関連付けを行っています。

感想

表示が冗長なのをキレイにしたりマウス操作のインタラプト転送も勝手に変換されるのをメニューにon/offを追加して制御したりしていきたいですね。
あと意外とWiresharkプラグインを作るという記事が少なく、書くのに手こずったのでメモ代わりと誰かのためになればと思い今回記事にしてみました。

ちなみにキーコードに対応させるテーブルを書くのが面倒でまだ一部しか書いてないです。