
Marc Newlin のキーストローク注入概念実証(CVE-2023-45866)の Rust 実装。
⚠️ 免責事項: 研究および教育目的のみ
このプロジェクトは、Bluetooth キーストローク注入を実証する Proof of Concept(PoC)であり、Rust で再実装されています。教育およびセキュリティ研究の目的にのみ使用してください。
このコードをダウンロード、クローン、または使用することにより、責任を持って、適用されるすべての法律および規制に準拠して使用することに同意したものとみなされます。
Rusty Injector へようこそ。Marc Newlin 氏の Bluetooth キーストローク注入 PoC に触発された Rust 実装であり、CVE-2023-45866、CVE-2024-21306、CVE-2024-0230 に関連しています。
現在、このリポジトリは Linux オペレーティングシステム上の BlueZ におけるキーストローク注入の脆弱性を悪用する CVE-2023-45866 のみを実装しています。
以下は、CVSS スコアを含む NIST の説明のスクリーンショットです:
キャプチャ 1 : CVE-2023-45866 の NIST 説明。
他の CVE、CVE-2024-21306 と CVE-2024-0230 は、私自身による実装は予定していませんが、コントリビューションは大歓迎です。
詳細に入る前に、NullCon 2024 カンファレンスでの Marc Newlin 氏のプレゼンテーションをぜひご覧になることをお勧めします。これらの脆弱性について明確かつ徹底的に説明しています:Hi, My Name Is keyboard by Marc Newlin.。
*また、この脆弱性を広く紹介する動画も公開しています。こちらにあります:How a Simple Bluetooth Hack Can Hijack Your Device - Hi, my name is keyboard.
📌 以下の説明で、欠けている点、もっと簡潔にできる箇所、または潜在的な誤りに気付いた場合は、自由に修正してマージリクエストを送ってください。あなたのコントリビューションをレビューし、リポジトリに取り込むことを嬉しく思います。
ここでは Linux オペレーティングシステム向けの CVE-2023-45866 の脆弱性のみを対象としているため、BlueZ ライブラリを標的としたこの特定の悪用手順についてのみ説明します。
まず、この脆弱性は Bluetooth BR/EDR 上でのみ悪用可能であることを理解する必要があります。なぜなら、この技術の上に位置する HID プロファイルを標的にしているからです。Bluetooth のアーキテクチャ実装は、イーサネットプロトコルの OSI モデルのように複数の層に分かれていることをご存知かもしれません。以下の図で確認できます。
図 1 : 簡略化した Bluetooth BR/EDR(Basic Rate - Enhanced Data Rate)スタック。スタックの最下層は専用アンテナを備えた物理層を表し、最上位はアプリケーションレベル、あるいはオペレーティングシステムと呼ばれることもあります。2 つのデバイスが互いに通信するとき、これらの異なる層を通過します:送信パケットは上から下へ、受信 Bluetooth パケットは下から上へ。
問い合わせプロセスの後、デバイス同士が接続を確立したいと判断すると、ペアリングプロセスに進みます。このプロセスにより、デバイス間の相互認証と暗号化キーの確立が可能になり、そのキーを使用して通信が保護されます。
Bluetooth 仕様は、認証とセキュリティのさまざまなレベルを提供します。認証に使用されるメカニズムに応じて、通信のセキュリティレベルは異なる場合があります。デバイスは、所有する入出力ペリフェラルに基づいて認証できます。これは、アソシエーションモデルと呼ばれる概念です。他のデバイスに表示された PIN コードの入力を求められるなど、2 つのデバイスをペアリングする際にこれに遭遇したことがあるでしょう。
デバイスの I/O(入出力)機能によって決まる、4 つのペアリングアソシエーションモデルがあります:
以下は、私たちの IoT デバイスの機能に基づいてどのアソシエーションモデルが使用されるかを示す表です。
図 2 : Bluetooth Core Specification v5.3 - 2.3.5.1 Selecting key generation method の Table 2.8(IO 機能から鍵生成方法へのマッピング)(1573 ページ)に基づく Bluetooth BR/EDR アソシエーションモデルを示す表。セキュリティモードとアソシエーションモデルの詳細については、Thyrasec が公開したこの興味深いブログ記事を参照してください:Bluetooth Security : Classic & BLE !
'Just Works' 方式に興味をそそられていることでしょう。まさにそこに私たちの脆弱性があります。問題は次のとおりです:この方式は、ユーザーの確認や操作を必要とせずにペアリングを確立するため、ペアリングデバイスの真正性を検証する手段がありません。Linux システムでは、BlueZ スタックはデフォルトで、NoInputNoOutput に分類されるデバイスからの着信ペアリング要求を受け入れていました(後方互換性を有効にするため)。まったくもって「素晴らしい」設計判断ですね。
キャプチャ 2 : Bluetooth セキュリティを有効にし、CVE-2023-45866 にパッチを適用するための blueZ のデフォルト設定の更新。
ターゲットデバイスとペアリングした後、システムは L2CAP 層のポート 1 を介して Service Discovery Protocol(SDP)への接続を確立します。図 1 に示すように、L2CAP 層は下位サービス層と上位サービス層の中間として機能し、データパケットのセグメンテーション、多重化、再組み立てを提供します。SDP 接続を通じて、ターゲットデバイス上の利用可能なすべてのサービスを特定し、Human Interface Profile(HID)サービスに接続します。オペレーティングシステムが Bluetooth キーボードやマウスからの入力を処理するために使用する HID プロファイルは、L2CAP 層のポート 17(HID Control)と 19(HID Interrupt)を介して動作します。HID プロファイルにアクセスするために認証は不要であり、L2CAP のポート 17 と 19 に接続された任意のデバイスは HID デバイスとして認識されます。
攻撃者は Bluetooth ワイヤレスキーボードのサービスとデバイスクラスを偽装し、'NoInputNoOutput' 機能を指定して 'Just Works' アソシエーションモデルを悪用し、ターゲットデバイスに不正なキーストロークを注入できます。
正直に言うと、唯一の目的は、このエクスプロイトの洞察をより深く理解するために、Proof of Concept を Rust で再実装することでした。そのため、この最初のイテレーションでは、Marc Newlin 氏の Python PoC Github "hi_my_name_is_keyboard" から大まかなアーキテクチャを着想しました。将来のリワークでは、より Rust らしい方法で実装されるかもしれません。
この実装で使用したクレート(= Rust ライブラリ):
[dependencies]
bluer = { version = "0.17.3", features = ["l2cap", "bluetoothd", "id", "rfcomm"] }
tokio = "1.42.0"
regex = "1.11.1"
clap = { version = "4.5.23", features = ["derive"] }
私のプロジェクトの主要な依存関係は、元の BlueZ C ライブラリの上に構築された Rust API である 'BlueR' でした。彼らの作品はこちらで確認できます:GitHub BlueR。また、BlueR ライブラリが提供する async 関数を使用できるように Tokio も統合しました。さらに、コマンドライン引数パーサーである Clap と、Rust で正規表現を実装するクレートである Regex を利用して、'bt_addr'(Bluetooth アドレス)のユーザー入力を検証しました。
Marc Newlin 氏の実装を観察した後、同じ機能を再現するためにアーキテクチャをいくつかのステップに分解しました:
--iface または -i:使用する Bluetooth インターフェース/アダプターを指定します。この引数はオプションで、何も指定しない場合はデフォルトのインターフェースを探しに行きます。--target または -t:必須であり、ターゲットの Bluetooth アドレスを指定します。NoInputNoOutput 機能を持つ Bluetooth エージェントを展開し、ターゲットデバイスとの接続中に 'Just Works' ペアリング方式にアクセスできるようにします。0x002540 を登録してキーボードを偽装します。コードには可能な限りコメントを付けるようにしました。コードを追ってみれば、これらのステップを簡単に認識できるでしょう。 よりエレガントにするために、次のステップはより Rust らしくすること、グレースフルな終了処理、そしてキーボードスクリプト(準備されたペイロード)を解析する機能やグラフィカルユーザーインターフェースなどの追加機能を実装することでしょう。繰り返しますが、これは教育目的のみであり、このプログラムの別のイテレーションに取り組むかどうかはわかりません。しかし繰り返しますが、コントリビューションは大歓迎です。質問があれば、遠慮なく聞いてください。
最初に注意すべき点:このツールは Ubuntu 24.04 で開発およびテストされました。
このツールを使用するには、BlueZ によって登録されているデフォルトの HID サービスを無効にする必要があります。これにより、エクスプロイト起動時に再登録できるようになります。次の手順に従ってください:
/etc/systemd/system/bluetooth.target.wants/bluetooth.service 設定ファイルを編集しますExecStart=/usr/libexec/bluetooth/bluetoothd
以下の行に変更します:
ExecStart=/usr/libexec/bluetooth/bluetoothd --noplugin=inputsudo systemctl daemon-reload
sudo systemctl restart bluetoothプロジェクトを取得し、cargo build でビルドするか、次のように引数を指定して直接実行するだけで使用できます:
cargo run -- -i [BT_INTERFACE] -t [BT_TARGET].
キャプチャ 3 : Rusty Injector のコマンドラインインターフェース。
以下は例です:
cargo run -- -i hci0 -t AA:BB:CC:DD:EE:FF
もう 1 つ注意すべき点として、コードを変更して Configuration トレイトを通じて "set_address" 関数を使用したい場合は、ツール bdaddr をインストールする必要があります:
# build bdaddr from the bluez source
cd ~/
git clone --depth=1 https://github.com/bluez/bluez.git
gcc -o bdaddr ~/bluez/tools/bdaddr.c ~/bluez/src/oui.c -I ~/bluez -lbluetooth
sudo cp bdaddr /usr/local/bin/
なお、Bluetooth インターフェースを指定しない場合は、デフォルトのインターフェースを探しに行きます。そしてもちろん、Ubuntu オペレーティングシステムに Bluetooth インターフェースを接続することを忘れないでください。🙃
これですべてを説明したと思います。これで Rusty Injector を最大限に活用する準備ができました!問題が発生した場合やコメント・フィードバックがあれば、お気軽に issue を開いてください。素晴らしい体験とハッピーハッキングを!🚀