mDNSでブラウザからmacOSユーザーの実名をブルートフォースする
(fingerprint.com)- macOSのデフォルトのローカルホスト名にはユーザー名が含まれることがあり、Webサイトは権限なしで mDNS名前解決の時間差 を使って名前候補を絞り込める
- 攻撃者は国・性別ごとの人気名50個とデバイス名候補を組み合わせ、実験では平均 65% のケースでmacOSユーザーの名前を特定した
- ブラウザのJavaScriptは任意のUDPソケットを開けないが、
fetch、iframe、Image、WebRTCリクエストで.localアドレスの 応答遅延 を比較できる - タイムゾーン、言語、IP位置情報、Safariの
navigator.language、画面解像度、screen.isExtendedのような情報が、ロケールやデバイスモデル候補を絞るのに使われる - 実用性は低く、開発者ツールのネットワークタブで見つかりやすいが、同じmDNS探索手法はプリンター、スマートTV、スマートスピーカー、IoT機器の検出にも使える
macOSのローカルホスト名から名前が漏れる仕組み
- macOSユーザーの実名は権限要求なしでブラウザから推定でき、その中核は mDNSプロトコル とデフォルトのローカルホスト名の形式にある
- 特定の国出身者について性別別の人気名50個のリストだけを使っても、平均 65% のケースでmacOSユーザーの名前を正しく特定できた
- Fingerprintはこの手法を製品に使用しておらず、クロスサイトトラッキングサービスも提供していない
- 公開議論の目的は、ブラウザ提供者がこうした手法を迅速に修正できるようにすることにある
mDNSとApple Bonjourの動作方式
- multicast DNS は、ローカルネットワーク上でデバイス名を登録・探索・ブロードキャストするためのプロトコル
- プリンターのような機器は
224.0.0.251の予約内部IPへUDP登録パケットを送り、HP_LaserJet_Printer.localのようなホスト名を含めることがある .localトップレベルドメインは、そのホスト名が mDNS で解決されるべきであることを示す- ルーターはこのようなパケットをローカルネットワーク上の他の機器へ自動的にブロードキャストし、ホスト名をキャッシュできるようにする
- 機器は同じ予約IPへクエリパケットを送り、ネットワーク上に存在するかもしれない特定名の機器を探す
- ホスト名の例は次のとおり
johns-mac-mini.localdavid-ZenBook-UX431DA-UM431DA.localjames-iphone.localcanon-mf644c.localbedroom-appletv.localdlinkrouter.local
- Appleデバイスでは、mDNSは Apple Bonjour 機能の一部として広く使われている
- デフォルトのローカルホスト名にユーザー名が現れることがあり、macOSでは System Settings > Sharing でローカルホスト名を確認または変更できる
ブラウザでmDNSホスト名を確認する回避手法
- mDNSはUDPパケットベースのため、ブラウザのJavaScript環境では任意のUDPソケットとして直接利用できない
- その代わり、ブラウザがURLのホスト名を解決しようとする性質を利用して タイミング攻撃 を行う
- 概念実証では、存在する
device-1.localと存在しないdevice-2.localに通常のfetchGETリクエストを送る - アドレスが解決されると、ブラウザは80番ポートへTCPパケットを送るが、このポートはたいてい閉じている可能性が高い
- ネットワークレベルでは異なるエラーが現れる
- 存在する
device-1.local:ERR_CONNECTION_REFUSED - 存在しない
device-2.local:ERR_NAME_NOT_RESOLVED
- 存在する
- JavaScriptでは両方のエラーが同じ
Failed to fetchエラーにマップされるため、エラー種別そのものには依存できない - ローカルネットワークは高速なので、有効なmDNSホスト名はデフォルトの接続タイムアウトよりはるかに速く解決される
- 例では、有効なアドレスは 4ms、無効なアドレスは 5秒 で分かれた
- このアプローチは概念実証には十分な一貫性があり、主要ブラウザで同様に動作する
- 実際には
fetch以外にも、iframe、Image、WebRTCのようなネットワークJavaScript APIでDNS解決のタイミング攻撃を行える
macOSユーザー名をブルートフォースする方法
- デフォルトのmacOSローカルホスト名にはユーザー名とデバイス名が含まれ、その形式はシステム言語のロケールによって変わる
- English:
<name>s-macbook-pro.local - French:
macbook-air-de-<name>.local - Russian:
mac-mini-<name>.local
- English:
- 単純な方法として、上位1,000個の名前、上位10個のロケール、一般的なmacOSデバイス名5個を組み合わせると、50,000個 のホスト名を調べる必要がある
- この場合、全件の検査に1時間以上かかる可能性がある
- より効率的な戦略は、探索範囲を単一ロケール・単一デバイス・そのロケールで一般的な名前50個に絞る方法
- 範囲を狭めると精度は下がるが、攻撃時間が短くなり、より現実的なシナリオになる
- ロケールの選択には、ブラウザのタイムゾーン、言語、IPアドレスの位置情報を利用できる
- Safariは
navigator.languageプロパティでシステムロケールを公開しており、この値は通常、対象ホスト名のロケールと一致する - ユーザーの出身国を見つける別の回避手法として、以前に扱われた Apple ID region detection の方法がある
- デバイス候補は画面解像度で絞り込める
- たとえば
1728x1117の解像度は16インチMacBook Proである可能性が高い - 拡張画面は
screen.isExtendedプロパティで検出できる - 拡張画面が検出された場合、デバイス候補を最も一般的なApple製macOSデバイス3〜5個に戻せる
- たとえば
制限と他の応用可能性
- この攻撃は本質的な弱点と複数の制約のため 実用的ではない
- Webサイト運営者が訪問者を意図的に匿名解除しようとするのでなければ、ブラウザの開発者ツールのネットワークタブで簡単に検出される
- この方法を installed applications detection と組み合わせると、権限なしでユーザーの実名や使用中の専門アプリケーション一覧に基づく役職を表示する有害なWebサイトを作れる可能性がある
- AppleデバイスでmacOSを実行しているケースが主な例だが、mDNS探索手法はさまざまな形に拡張できる
- ローカルネットワークのスキャンを通じて、プリンター、スマートTV、スマートスピーカー、その他の家庭用IoT機器の検出にも利用できる
- iPhoneとiPadにも適用可能で、条件は Wi-Fi syncing またはSafariのリモートデバッグ機能が有効であること
1件のコメント
Hacker News のコメント
macOS で Little Snitch を使っているが、ネットワークリクエストを許可する前にローカルユーザーへ明示的に確認するよう設定できる、よくできた UI だと思う
https://www.obdev.at/products/littlesnitch/index.html
リモートログイン中にたまに引っかかることがあり、たいてい SSH セッションが NPM から NodeJS コンポーネントを取得するような形で何かを新しくダウンロードしようとしたとき。テキスト端末上の SSH ダウンロードが止まり、原因が Little Snitch だと突き止めると、階下の机まで行ってマウスを動かしてモニターを起こし、スクリーンセーバーを解除して Little Snitch のダイアログで「Allow」を押さなければならない
意図どおりに動いているということではある。ただ、こうしたツールはデフォルトでローカルネットワークへのリクエストを静かに許可する設定になっていることが多いので、元記事のいたずらが自分の環境でも通用するかは分からない
アプリが裏でどんなソケット接続を開いているかを見ると驚く。銀行アプリも例外ではない
https://havoc.app/package/netfence
https://news.ycombinator.com/item?id=35363343
Confirmを押すまでは 1.1.1.1 への実際の接続は作られないネットワークに Pi-hole を追加すれば、時間・お金・投資を後悔することはないはず
より広いインターネット上の Web サイトが、自分のローカルネットワークへネットワークリクエストを送れないようにする方法はあるのだろうか。これがデフォルトで許可されるべき理由が想像しにくい
IE の Local Intranet Zone 権限を復活させようという意味ではない
しかし https://192.168.2.1 で何かを動かしていたとしても、192.168.2.1 のサービスが
Originとして my-own-domain.com を許可していない限り、https://my-own-domain.com で動作する Web アプリからはアクセスできないhttps://brave.com/privacy-updates/27-localhost-permission/
HN の投稿: https://news.ycombinator.com/item?id=36574775
ブラウザが Discord チャンネルの招待ページへ移動すると、このポート経由で localhost にリクエストを送り、チャンネル ID をクライアントに渡す。するとアプリはネイティブな「Join Channel」体験を表示できる
シークレットモードでも動作し、ブラウザ側で Discord からログアウトしていた状態でもこの挙動が続くのを見て気づいた。よくない。デスクトップの世界では、すべてのアプリケーションのサンドボックス化を大幅に改善する必要がある
||local^$allこれにより、.local 自体から来たリクエストも含め、.local 宛てのすべてのリクエストをブロックする。Web サーバーを動かすなどの理由で foo.local が自分自身と通信することを許可したい場合は、ドメインごとに追加の例外が必要になる:
@@||foo.local^$domain=foo.local,allあるいは .local 全体を信頼して、任意の foo.local が任意の bar.local と通信できるよう許可したいなら、.local 全体の例外を 1 つ追加できる:
@@||local^$domain=local,all時間がたつほど、インターネットは基本的に Qubes マシン上で、使い捨ての Whonix/Tor VM から、JavaScript をオフにして使うほうが気が楽になってくる
これは本当に気持ち悪い。驚きはしないが、それが可能だという事実自体が多くの意味でひどい
fingerprint.com を知らないなら、彼らは「深いユーザープロファイリング」を行っている。コンピューター、ブラウザ、OS が違っても同じユーザー ID を維持し続けるようなものだと思えばいい。メインページにデモがあり、どれほど正確に当てるか少しぞっとする
デモを壊す uBlock Origin フィルタ:
||fpjscdn.net同種のタイミング攻撃により、ブラウザからローカルマシンやローカルネットワーク上の他のデバイスをポートスキャンできる
https://github.com/Flu1dTeam/PortScanner
以前、eBayがこれをやって発覚した
https://blog.nem.ec/2020/05/24/ebay-port-scanning/
デバイス名をいつも変更しておいてよかった
Appleのデフォルトの命名はプライバシー上の失敗だ。以前、法執行機関にいる人と初デートしたことがある。相手は一人で来た女性で、自分の身を守ることに明らかに気を配る人だったので、私の身元調査をしていて、周囲のコミュニティの何人かにも私たちの居場所を知らせておいたと言っていた
一方で私は相手の姓すら知らず、それを冗談のネタにしていた。夕食後に車に乗ったとき、ダッシュボードの画面にiPhoneが自動ペアリングされたと表示され、そのiPhone名が相手の名と姓になっているのを見て興味を引かれた。私はそれを指摘せず、ドライブが終わるまで、どうやって名前を知ったのか当ててみてと言った
問題は、車を返す前に自分のプロファイルを消すよう自分に思い出させるのが一番難しい点だ
上の例では、有効なアドレスは4ミリ秒、無効なアドレスは5秒かかっている
これは意外だ。DNSルックアップの失敗は、成功したDNSルックアップの後に発生するデフォルトの接続タイムアウトよりずっと速いと思っていた
それでも、s-mac-xxxxは常に少し妙な選択だと思っていた。特にプライバシーを大きな売り文句にしている会社だと考えるとなおさらだ。実名を使わないだろうと期待していたのか、ここでは「ユーザーフレンドリーさ」が優先されたのだろう。プライバシーの観点では、Windowsのランダム生成ホスト名のほうがましだ
† 厳密には完全に正しいわけではない。あるデバイスがその名前を自分のものだと認識している場合は、ノーと言うことができる
記事はよく書けていて興味深い。特に「内在する弱点と多くの制約を考えると、この攻撃は実用的ではない」のような誇張のないトーンが気に入った
この方法は、ネットワーク上に特定のホスト名が存在するかをテストできるようにする
一意のホスト名1つなら大した問題ではないかもしれないが、IoTの世界でよくある固定ホスト名やデフォルトホスト名はどうだろう
Webサイトが、ユーザーが特定のデバイスを所有しているかをこっそり推測できるようになる。標的型攻撃に使えばさらに悪い。ネットワーク内の一部のデバイスを知っていれば、アクセスしてきたユーザーが標的ネットワーク内にいるかを推測できる
JavaScriptをオフにすることが、エンドユーザー体験までオフにすることにならなければよかったのに
それでも今後は、プライバシー上の懸念からデフォルトでオフにせざるを得なくなりそうだ
幸い、自分のデバイス名はたいてい「xxxs's MacBook Pro (34)」のような形式だ。バグではなく機能だ
user、ホスト名はhostnameに設定しよう。こうする人が多いほどよい興味深く、記事もよく書けていて、ちゃんとした概念実証まである。よくできている
面白い対策として、デバイスのホスト名をatemptingurl.localのようなものに変えて、攻撃者がそのWebサイトを訪れてみたくなるようにできそうだ。そのページは同じ手法を攻撃者に対して実行するよう巧妙に作っておき、こんなメッセージを返すというわけだ:
「こんにちは、[ハッカーのデバイス名]さん!あなたのマシン情報、IPアドレス、地理的位置、その他のフィンガープリント情報が収集され、[恐ろしげなサイバー機関名を挿入]に報告されました。」熟練のベテランでスクリプトキディでなくても、少なくとも笑わせることはできるだろう
人々には笑う理由がもっと必要だ :-)