Hu KeとNir Avrahamによる研究で分かったこと
機内モードの偽装
その名の通り、機内モードは飛行中に安全にモバイルデバイスを使用するためのものであり、飛行制御機器との干渉を避けるためにデバイスのモバイルデータ通信を無効にするものです。
しかし、機内モードはフライトでの使用にとどまらず、バッテリーを節約するために使う人もいれば、オンラインの世界からしばし自分を切り離すために使う人もいます。さらに、瞑想のテクニックとして使用することを提案する人さえいるようです。
サイバーパラノイア(サイバー偏執症)やテクノフォビア(科学技術恐怖症)の人にとっては、機内モードをオンにすることで、心の平穏とプライバシーの強化を感じられるというメリットもあるでしょう。
しかし、セキュリティとプライバシーを守るために機内モードを使うべきなのでしょうか?
改めてiOSの機内モードの基礎となるテクノロジーについて深掘りし、飛行モードが有効になっているとユーザが信じている間に、攻撃者がモバイルデータ通信経由で特定のアプリケーションへのアクセスを維持する方法について説明します。
飛行モードの基本
まずは、機内モードがどのように機能するかについて見ていきましょう。機内モードを切り替えるタスクを主に担うのは2つのデーモンです。SpringBoardはUI上の変更を担当し、CommCenterは基盤となるネットワークインターフェースの操作を担当します。さらにCommCenterは、「特定のアプリに対するモバイルデータアクセスをブロック」する機能の管理も担当しています。
通常は、ユーザが機内モードを有効にすると、ネットワークインターフェース「pdp_ip0」(モバイルデータ)がIPv4/IPv6のIPアドレスの表示をストップします。これにより、少なくともユーザレベルではモバイルデータ通信が切断されます。
人工的に作り出された機内モード
ここからは、特定のアプリケーションに対するモバイルデータ通信を維持しながら、UIの変更も含めた偽の機内モードを作り出す方法について説明します(この「特定のアプリケーション」とはデバイスを悪用するために攻撃者がインストールするマルウェアのことを指します)。
まずは、コンソールのログから見ていきましょう。機内モードをオンにした場合、それに関連するもっとも古いログは、「#N User airplane mode preference changing from...」(赤線で囲まれた部分)となります。
この文字列を使って、逆アセンブラでそれを参照しているコードを探します。すると、シンボルなしのC++関数が見つかります。
この関数が機内モードを有効にする呼び出しのチェーンの最初の方にあることを望みつつ、私たちはそれを空白(または何もしない)関数にフックし置き換えることに成功しました。これにより、機内モードを偽装することができたのです。この状態でユーザが機内モードを有効にすると、デバイスはモバイル通信から切断されず、インターネットアクセスが維持されます。
ユーザエクスペリエンスの維持
機内モードをさらに本物らしく見せるには、UIの調整が必要になります。例えば、モバイルデータ通信のアイコンを暗くして操作できないようにする方法があります。
これは、Objective-Cの2つのメソッド(-[SBStatusBarStateAggregator _noteAirplaneModeChanged]と -[CCUIModularControlCenterOverlayViewController _beginPresentationAnimated:interactive:])をフックし、モバイルデータ通信アイコンを変更するコードの一部を注入することで達成できました。
オフライン状態の偽装
Wi-Fi接続がない状態で機内モードを有効にすると、ユーザはSafariを開いてもインターネットに接続されないと思うはずです。このような場合、通常は機内モードを無効にするようユーザに通知するウィンドウが開きます。このような状態を作り上げたい場合、前述のCommsCenterの機能を利用して「特定のアプリへのモバイルデータアクセスをブロック」し、以下のフック機能を通じて機内モードを偽装することが可能です。
以下は、「特定のアプリに対するモバイルデータアクセスをブロック」する機能により通常表示されるメッセージ(左)と、通知ウィンドウをフックして正常な機内モードのメッセージに見せかけたもの(右)を示しています。
このようにウィンドウを置き換えるのは可能であるとしても、実際に機内モードを無効にしてデバイス全体でインターネットを使えないようにする以外に、Safariにアクセスできないようにする方法はあるのでしょうか?この点をクリアせずに、機内モードが有効になっているとユーザに信じ込ませることはできません。
「モバイルデータ通信が無効になっています」ウィンドウの仕組み
前述のアイコンを操る方法と同様に、私たちはシステムUIマネジャであるSpringBoardがCommCenterからの通知を受けて警告ウィンドウを表示させることを突き止めました。また、このことについてさらに詳しく調べてみたところ、登録されたオブザーバーまたはコールバック関数を通じてCommCenterがカーネルから通知を受けていることがわかったのです。
CommCenter`CellularUsagePolicyController::createNEConfigurationStore_sync
-> NetworkExtension.framework`-[NEPathEventObserver initWithQueue:eventHandler:]
-> libnetwork.dylib`network_config_cellular_blocked_observer_create
これらのnetwork_config_*関数は、カーネルとやりとりするために内部的にsocket()/ioctl()を呼び出します。
network_config_cellular_blocked_observer_create
-> network_config_policy_observer_create
-> __network_config_policy_observer_create_block_invoke
-> network_config_setup_policy_event_watcher
-> socket(32, 3, 1)
-> ioctl(...)
私たちはfsevents`を使用し、CommCenterデーモンがSQLデータベースファイルである/private/var/wireless/Library/Databases/CellularUsage.dbを管理することも確認しました。このデータベースには、各アプリのモバイルデータアクセスのステータスが記録されています。
アプリケーションがモバイルデータへのアクセスをブロックされている場合、「flags」の値は8に設定されます。このSQLデータベースファイルでは、アプリケーションのバンドルIDの一覧を確認し、そのプリセット値を取得できるので便利です。
インストール済みのアプリケーションのバンドルIDが確認できるこのデータベースを使用する場合には、以下のコードを使って各アプリに対してWi-Fiまたはモバイルデータ通信へのアクセスをブロックまたは許可することができます。これを前述の他のテクニックと組み合わせることで、本物そっくりの機内モードを偽装しながら、バックドア型トロイの木馬などのマルウェアのみにインターネットアクセスのブロックが適用されないようにすることが可能です。
高度な攻撃を検出しユーザを保護するJamf Executive Threat Protectionについても併せてご検討ください。
Jamfブログの購読
市場トレンドやAppleの最新情報、Jamfのニュースなどをお届けします。
当社がお客様の情報をどのように収集、利用、移転、および保存するかに関しては、プライバシーポリシーをご参照ください。