
AndroidのadbdワイヤレスデバッグにおけるTLS認証バイパスの概念実証エクスプロイト。EC/RSAの鍵タイプ不一致を利用して、認証なしのリモートシェルを取得します。
免責事項: この概念実証 (PoC) は、教育および許可されたセキュリティ研究の目的に厳密に限定して提供されています。コンピュータシステムへの不正アクセスは違法です。デバイスやネットワークに対してテストを行う前に、必ず明示的な許可を得ていることを確認してください。
Android デバイスには ワイヤレスデバッグ と呼ばれる機能があり、開発者は USB ケーブルなしで Wi-Fi 経由でデバイスに接続できます。この接続を安全に保つため、デバイスは TLS 暗号化を使用し、接続するコンピュータが暗号鍵を使って自身の身元を証明することを要求します。
欠陥はどこにあるのか?
コンピュータが接続すると、Android のデーモン (adbd) は、そのコンピュータの鍵が以前に承認された鍵のいずれかと一致するかどうかを確認します。これは、3 つの数値のいずれかを返す組み込みの数学関数 (EVP_PKEY_cmp) を使用して行われます:
1 は「鍵が完全に一致する」ことを意味します。0 は「鍵が一致しない」ことを意味します。-1 は「エラー: 鍵が完全に異なる種類である (例: RSA 鍵と EC 鍵を比較している)」ことを意味します。バグ:
プログラマーは単純なチェックを書きました: if (result) { grant_access(); }。
プログラミングでは、1 と -1 の両方が「真」と見なされます。したがって、攻撃者が意図的にまったく異なる種類の鍵 (期待される RSA 鍵の代わりに楕円曲線鍵など) を送信すると、関数は -1 (エラー) を返します。バグのあるコードは -1 を見て「真」を意味すると解釈し、それでも完全なアクセスを許可してしまいます。
結果: 同じ Wi-Fi ネットワーク上の攻撃者は、認証を完全にバイパスし、元のペアリング鍵を必要とせず、ユーザーに承認プロンプトを表示することなく、デバイス上でリモートシェルを取得できます。
このエクスプロイトが機能するには、対象の Android デバイスが次の 2 つの条件を満たしている必要があります:
このスクリプトは、一時的な証明書をオンザフライで生成するために Python 3 と cryptography ライブラリを必要とします。
必要なライブラリは、apt (Debian/Ubuntu/Kali の場合) または pip のいずれかを使用してインストールできます:
apt を使用する場合 (Linux で推奨):
sudo apt update
sudo apt install python3-cryptography
pip を使用する場合(クロスプラットフォーム):
pip3 install cryptography
USBデバッグとは異なり、Androidはワイヤレスデバッグ用に、デバイスの再起動やWi-Fiネットワークの変更のたびにランダムな大きな番号のポートを割り当てます。
現在のポートがわからない場合は、nmapを使って簡単にスキャンできます。ワイヤレスデバッグのポートは通常30000から50000の間にあります。
次のコマンドを実行し、<hostname>をターゲットデバイスのIPアドレスに置き換えてください:
nmap -Pn -p T:30000-50000 <hostname>
出力の読み方:
open と表示されるポートを探します。例:
PORT STATE SERVICE
41234/tcp open unknown
この例では、41234 が次のステップで使用するポートです。
ターゲットのホスト名/IP と正しいポートを取得したら、エクスプロイトを実行できます。
完全なインタラクティブリモートシェルを開くには(SSH と同様):
python3 adb_bypass.py <hostname> <port>
例:
python3 adb_bypass.py 192.168.1.50 41234
接続すると、shell ユーザープロンプトが表示されます。終了するには Ctrl+C を押してください。
インタラクティブシェルに入らずに特定のコマンドだけを実行して出力を確認したい場合は、--cmd フラグを使用します:
python3 adb_bypass.py <hostname> <port> --cmd "id"
デバッグや調査目的で基盤となるネットワークトラフィックとハンドシェイクの詳細を確認するには、-v フラグを追加します:
python3 adb_bypass.py <hostname> <port> -v
CNXN パケットと STLS パケットを交換して TLS へのアップグレードに合意します。cryptography ライブラリを使用して、スクリプトは一時的な EC P-256 秘密鍵と自己署名 X.509 証明書をメモリ内で生成します。EVP_PKEY_cmp は -1 を返し、if (cmp) チェックが真と評価され、デバイスはその接続を認可済みとして扱います。delayed_ack ウィンドウを使用して直ちに shell: ストリームを開き、その結果、認証なしのリモートシェルを取得します。