ラック・セキュリティごった煮ブログ

セキュリティエンジニアがエンジニアの方に向けて、 セキュリティやIT技術に関する情報を発信していくアカウントです。

【お知らせ】2021年5月10日~リニューアルオープン!今後はこちらで新しい記事を公開します。

株式会社ラックのセキュリティエンジニアが、 エンジニアの方向けにセキュリティやIT技術に関する情報を発信するブログです。(編集:株式会社ラック・デジタルペンテスト部)
当ウェブサイトをご利用の際には、こちらの「サイトのご利用条件」をご確認ください。

デジタルペンテスト部提供サービス:ペネトレーションテスト

高級ホテルの客室タブレットに潜む危険:他客室も操作、盗聴可能だった脆弱性を発見するまで

しゅーとです。

新婚旅行で沖縄に行ってきたのですが、そこで泊まった高級リゾートホテルの客室にタブレットが置いてありました。

このタブレットを調査したところ、客室内の盗聴・盗撮が可能となる脆弱性や、第三者がネットワーク上から他客室のコントロール、チャットの盗聴が可能となる脆弱性を発見しました。この問題はIPAを通して開発者に報告し、報告から2年の年月を経て影響する全ホテルへの改修が完了し、公表されました。

本記事ではキオスクアプリ開発者がよりセキュアなシステムを構成できるように、発見した脆弱性の原因と対策を解説します。

客室に設置されていた脆弱性を有するタブレット

※今回は稼働中システムに対する調査という背景を鑑み、他者の情報・資産を侵害しないよう細心の注意をもって調査しており、他者の情報が関連するセンシティブな問題についてはアクセスなどの実際の検証を行わず、複数の間接的な証跡をもって報告しております。
読者の皆様におかれましては、不用意に他者へ影響を及ぼす行為は厳に慎むようお願いいたします。


みなさんは客室タブレットと聞いて何をイメージするでしょうか。

最近は様々なホテルにタブレットが導入されていますが、一般的にはホテルの周辺情報閲覧、アラームが設定できるだけとか、制限ブラウザで簡単なWeb閲覧ができるようなものを連想されると思います。

しかしこのホテルに置いてあるタブレットはただのWeb閲覧端末ではなく、以下の機能をもつ大変興味深いものでした。

  1. 客室空調・ライトの遠隔操作(電源操作・温度設定・風量設定)
  2. ルームサービスの注文
  3. 部屋付けにしたサービスの履歴と合計金額の明細表示
  4. コンシェルジュとのチャット
  5. 新聞・雑誌サービスの無料購読

客室タブレットの空調・照明操作

AndroidDeviceOwner(Android Enterprise)LockTaskモード という機能を組み合わせて、OS起動時に特定のアプリのみ起動できるようにする、いわゆるキオスクモードが存在します。居酒屋などの注文タブレットや客室用タブレットは一般的にこのキオスクモードで動いています。

今回の端末もこれらの機能によってOS起動直後からキオスクアプリが自動実行され、他のアプリの実行は行えず、通知領域の表示、ホーム画面への遷移も制限されていました。

それなら安心でしょうか?答えはNoです。こういったタブレットは設定の穴をついて何でもできる可能性があるのです。客室という大変プライバシー性が高い空間に脆弱なタブレットがあったら怖いですよね。もし端末が攻撃者に乗っ取られていつのまにか盗聴されていたりしたら怖くて寝られません。

そこで本当にこの端末がセキュリティ的に大丈夫なのか、端末に永続的な影響を与えない程度で、配偶者が寝ている夜中の数時間で調査することにしました。

そして調査の結果、下記の複数の脆弱性があることを確認しました。

  1. 特定の条件下でUSBデバッグ接続が可能
  2. 再起動後に一時的に端末の設定操作が可能
  3. セーフモードでのOS起動が可能
  4. ブートローダーアンロックすることによりroot権限に昇格可能
  5. 他の客室端末になりすまして空調・ライト操作、注文、明細表示、チャットの盗聴が可能

このうち1, 2, 3は検証済みですが、4, 5は他者の情報・資産や端末に影響を及ぼす可能性があるため、実際に悪用するような検証は行なっていません。

今回問題を確認した端末は沖縄のホテルに設置されていたものですが、キオスクアプリの解析の結果、このシステムは全国のラグジュアリーホテルに導入されているものと思われます。実際、後日東京の高級ホテルに泊まった時も類似したUIで同等機能を有するタブレットに出会ってしまいました。このことから脆弱性の影響を受けたホテルは少なくないと思われます。

さて、私が見つけた問題をひとつづつ見ていきましょう。


問題1:特定の条件下でUSBデバッグ接続が可能

タブレットが置いてあったら攻撃者がまず試すのがUSBデバッグです。AndroidはUSBデバッグ接続が可能な場合、接続したPCを通して端末内のアプリデータや画像・動画ファイルを収集したり、好きなアプリをインストールすることが可能です。攻撃者はそれを悪用して事前にカメラ・マイクを有効にするバックドアアプリをインストールすることで、客室内のプライバシーを侵害することが可能です(ただし非root化環境では悪用条件が厳しい)。

ただしシステム開発者はそのリスクを知っているので、不特定多数が触れる端末ではUSBデバッグをできないようにしていることが殆どです。

今回も想定通り、ホテルのキオスクアプリが表示されている状態では端末のUSBポートをPCに接続しても、「USBデバッグを許可しますか?」というウインドウが表示されず、デバッグ接続が行えませんでした。参考までに、USBデバッグがオンの状態でUSB接続したときに出現するシステムダイアログ画像を記載します。

USBデバッグ設定がオン時に出現するダイアログ。キオスクアプリ起動中は出現しないが・・・?

今回ダイアログは出ませんでしたが、奇妙な点があります。以下はキオスクアプリが表示されている状態でUSBポートにPCを接続したときの、PC上のadb devicesの結果です。

user@vm-tester:~/work$ adb devices
List of devices attached
HA0LCPL0        unauthorized


user@vm-tester:~/work$

端末はadbサーバを認識しているもののunauthorized状態になっています。おかしいですね。USBデバッグがオフであれば、一般的にはデバイス一覧に表示されないはずなのです。

ということは、USBデバッグはオンだけれども、何らかの理由で承認されないor承認ダイアログが表示されないだけだと推測されます。

この状況の突破口がないか、画面上をスワイプしてみたり、端末の物理ボタンを押したり試してみました。

すると端末の電源ボタンを長押しすることで、端末の電源メニューが表示されることがわかりました。 そのため「電源を切る」「再起動」「スクリーンショット」の操作が可能です。

ここから再起動を選択することで、OS再起動が行えました。再起動を行うと、Android起動後、ランチャーが一瞬表示されたかと思うとすぐにキオスクアプリが表示されます。ここでキオスクアプリが表示されるまでの数秒の猶予でPCとUSB接続が行われると、なんと画面上にデバッグ許可のダイアログが表示されることがわかりました。

許可を選択すると、PCにてadbコマンドを使ってシェルの立ち上げなど様々なデバッグ機能を利用することができました。

動画を撮影したのでご覧ください。

youtu.be

adb接続が成功したときのPC画面

adbコマンドはinstallサブコマンドを用いて任意のバックドアアプリをインストールすることも可能です。権限周りや永続化の検討は必要ですが、これで盗聴を行うアプリを端末に忍ばせることも可能でしょう。

また、この状態でadb backupを行うことで、キオスクアプリのapkファイルと設定ファイルを抽出することが可能でした。攻撃者はキオスクアプリを解析することで、客室タブレットシステムのさらなる攻撃が容易となります。

原因の推測と対策

なぜこんなことになったのでしょうか?

根本はOSの設定でUSBデバッグが許可されていたためです。開発者の意図を推測するに、エンドユーザーからのUSBデバッグを防ぎながらも、保守メンテナンス時にはUSBデバッグを行いたい。このような理由でUSBデバッグをオンにしつつもキオスクアプリ側で承認ダイアログを抑制する措置がなされていた可能性があります。

キオスクアプリの解析の結果、アプリはDeviceOwner設定がされており、OS起動完了時にシステムから発出されるブロードキャスト「BOOT_COMPLETED」を受け取って初期化を行うアクティビティが存在しました。これで十分と思ってしまいがちですが、開発者は攻撃者が何らかの方法で端末を再起動して、キオスクアプリに処理が移る前(=OS起動直後からBOOT_COMPLETEDが発出されるまでのわずかな時間)に攻撃を行うことを想定する必要がありました。

対策

USBデバッグのオフ

まずはUSBデバッグをオフにすることです。そして、メンテナンス時にUSBデバッグを行いたい場合にのみ管理者のみがUSBデバッグをオンにできるような処理をキオスクアプリ(MDM)に加えるようにします。

端末の物理ボタン操作を無効化する(緩和策)

緩和策にはなりますが、攻撃の機会を防ぐために、ポリシー設定で端末の電源操作を容易に行えないようにしましょう。また機種によってはハードリセットが行える場合もあります。可能であれば物理的にボタンを封印するとよいでしょう。ただし狡猾な攻撃者はWeb閲覧機能でバッテリーを浪費させ、強制的に再起動を企図することも考えられます。

端末のUSBポートへの物理的アクセスを制限(緩和策)

端末のUSBポートが露出していたため、容易にアクセスが可能でした。これを防ぐため端末ケースを導入するとよいでしょう。ケースが容易に開けられない構造であればカジュアルなハックは防げますし、こじあけた場合はわかりやすく証拠が残ります。ただしワイヤレスデバッグを有効にしているとUSBポートを塞いでいてもデバッグ接続が可能な場合もありますので注意しましょう。


問題2:再起動後に一時的に端末の設定操作が可能

問題1の関連となりますが、OS再起動後はキオスクアプリが直接起動するわけではなく、まずランチャーが表示、そしてそのあとキオスクアプリに遷移する動きとなっていました。そのためキオスクアプリに遷移するまでの数秒の猶予にて通知領域を表示し、設定アプリのショートカットを選択することで、設定アプリを開くことができました。

OS起動直後に通知領域をスワイプして設定アプリを開く様子

そしてUI操作中は恐らく処理の優先度の関係かキオスクアプリへの自動遷移はないように見受けられ、この猶予を利用して設定アプリからUSBデバッグのオンオフ設定などが可能であることを確認しています。(ちなみにUI操作をやめるとすぐにキオスクアプリに遷移します)

つまり、仮に今回USBデバッグがオフだったとしても、この問題を悪用することでUSBデバッグをオンにすることは可能だったということです。

原因の推測と対策

なぜこのような奇妙な動作になったのでしょうか。確実なことはわかりませんが、キオスクアプリの解析と端末の設定から以下の推測が立ちました。

キオスクアプリはBOOT_COMPLETEDブロードキャストを受信してメインアクティビティが実行されるようになっていました。次に端末で実行したdumpsysの結果を解析した結果、端末ベンダーであるLenovoのランチャーアプリがPRE_BOOT_COMPLETEDブロードキャストを受け取るように設定されていることを確認しました。PRE_BOOT_COMPLETEDブロードキャストはランチャーなど特殊アプリがBOOT_COMPLETEDよりも先に処理をするために存在するものです。そのため、ランチャーアプリがキオスクアプリより先に実行され、さらにユーザのUI操作によりシステムからのBOOT_COMPLETEDの発出が遅れたのだと推測しています。

PRE_BOOT_COMPLETEDブロードキャストを受け取るアプリ一覧。Lenovoのランチャーが含まれているがキオスクアプリは含まれていない

対策

キオスクアプリをデフォルトランチャーにする

デフォルトのランチャーアプリを無効化し、キオスクアプリをPRE_BOOT_COMPLETEDを受信できるランチャーアプリとして設定することが考えられます。MDMによってはより柔軟な設定が可能かもしれません。


問題3:セーフモードでのOS起動が可能

これも問題1, 2との関連事象ですが、電源メニューにおいて再起動のアイコンを長押しすることで、セーフモードでのOSの起動が可能でした。セーフモードではキオスクアプリが自動実行されず、ホーム画面が表示されます。そのため攻撃者が端末にて任意の画面操作および設定変更を行うことが可能となります。

再起動後、ホーム画面にて設定アプリを開き、設定変更が可能であることを確認しました。

この状態ではキオスクアプリに遷移することがないため、システムを時間の猶予を気にせず端末の調査や設定の変更を行うことが可能となります。
もちろんこの問題を悪用することでもUSBデバッグをオンにすることが可能です

原因の推測と対策

これは問題1と同様、端末の物理ボタン操作が可能だったことに起因します。端末の物理ボタン操作を無効化しましょう。MDMサービスによってはセーフモードを無効にできるものもあるようですが、Android バージョンや端末ベンダーによって挙動が異なり、一部の端末では標準APIだけで完全にはブロックできない可能性があります。その場合は物理ボタンを封印するなど運用面で対処する必要があります。


問題4: ブートローダーアンロックすることによりroot権限に昇格可能

問題2, 3の問題を利用することで、設定アプリの画面操作が可能です。設定アプリではOEMロック解除の有効無効項目が存在しており、有効にした上でアンロック操作を行うことで、ブートローダーアンロックが可能です(推測)。 ブートローダーアンロックを行った端末は任意のブートローダーやカスタムROMを書き込み可能であるため、いわゆるroot化が可能です。

※永続的に影響を与える可能性があるため、検証は行っていません。

USBデバッグが有効であるだけでは、非root化環境では、バックグラウンドでのマイク盗聴やカメラ盗撮がAndroidのセキュリティ設計上困難です。しかし今回のタブレットOEMロック解除が設定可能であったため、攻撃者は端末をroot化し、バックグラウンドで実行するステルスなスパイアプリをインストールすることが可能であったわけです。

ただし一般的に端末をroot化するためにはブートローダーをアンロックし、カスタムROMを端末にインストールする必要があります。その際は端末内データも消去されるため、MDM管理下の業務端末では正常なシステム反映が行われないなど、実際の攻撃は困難である可能性もあります。

原因の推測と対策

OEMロック解除の設定が可能かどうかは基本的に端末ベンダーの方針に依存します。今回使われていたLenovoタブレットは仕様上、不特定ユーザによってブートローダーをアンロックすることが可能な機種であったため、これを防ぐのは困難です。対策を行うためには不特定ユーザによるアンロックをサポートしていない機種を選定する必要があります。


問題5: 他の客室端末になりすまして空調・ライト操作、注文、明細表示、チャットの盗聴が可能

※本問題は影響を鑑みて、実際の検証を行っておりません。あくまで解析結果から可能であることを推定したものとなります。

客室タブレットシステムの話に戻りましょう。

客室タブレットは前述のとおり、空調・ライト操作、注文、明細表示、チャット機能を有していますが、キオスクアプリの解析の結果、これらの機能は端末が接続しているネットワーク上のコントロールサーバで集中管理されており、端末からの要求に応じて操作されることがわかりました。

そして各機能はキオスクアプリで詳細に画面が定義されているものではなく、各機能ごとに個別のコントロールサーバのURLが用意されており、アイコンをタップすることで機能に応じたURLをアプリ内ブラウザで開くことがわかりました。

これはどういうことでしょうか。以下に明細表示機能の画面を示します。

この画面は一見するとキオスクアプリのUIに思えます。しかし実装ルーチンでは、アプリ内の利用明細表示アイコンをクリックしたときにあくまで内蔵ブラウザで当該URLにアクセスするような処理が行われていることがわかります。

つまりキオスクアプリはあくまでコントロールサーバのWebページを表示しているだけにすぎないのです。

以下はアプリ解析で得られた、明細を端末上で表示するときの、端末がアクセスするコントロールサーバのURLです。(※Room No.はマスクしています)

http://***************/?room_no=****&lang=ja&clock_mode=12

さらに解析を進めると、コントロールサーバには客室ごとの認証機能は存在せず、URLに存在するRoom No.のパラメーターを変更することで、任意の客室の空調・ライトの変更、ルームサービスの注文、コンシェルジュとのチャット、利用明細の取得が可能であるように見受けられました。

これを強く推定できるのが以下の図です。この画面は問題3で発見したセーフモードを利用して、セーフモードで起動したタブレットの標準ブラウザで当該URLにアクセスしたときの画面です。

画面上部にアドレスバー等が表示されているのがわかるでしょうか。端末ベンダーがプリインストールする標準ブラウザは、客室タブレットシステムに関連する認証機能はないはずです。標準ブラウザで表示できるということは、少なくともアプリケーションレイヤによる認証はないと推定できます。

チャット機能での例

他のアプローチでの推定もしてみましょう。以下はアプリ解析の過程で得られた、コンシェルジュとのチャット機能を利用するときのチャット用URLの取得メソッドであるgetChatUrl()です。

    private String getChatUrl() {
        String string;
        String string2 = Ciphers.encode((String)String.format("%s,%s", new SimpleDateFormat("yyyyMMdd").format(Calendar.getInstance().getTime()), this.myPrefs.room_number().get()));
        string2 = string = "http://*******/" + string2;
        if ((Boolean)this.myPrefs.initialized_chat().get() != false) return string2;
        string2 = string + "-init";
        return string2;
    }

URLのパラメータには日付情報と、Room No.であるthis.myPrefs.room_number()をもとに構成されたテキストが利用されています。 room_number()は以下であり、キオスクアプリに同梱されたアプリデータであるMyPrefs.xmlのroom_numberの値から取得しています。

public final class MyPrefs_
extends SharedPreferencesHelper {
    public MyPrefs_(Context context) {
        super(context.getSharedPreferences("MyPrefs", 0));
    }
(..snip..)
    public StringPrefField room_number() {
        return this.stringField("room_number", "0006");
    }

以下はMyPrefs.xmlの該当部分です。

    <string name="room_number">****</string>

このことから、攻撃者は各機能のURLを特定して端末のブラウザでアクセスするか、キオスクアプリのMyPrefs.xmlデバッグ機能で書き換え、別客室の端末としてなりすますことで、任意の客室の機能を操作することが可能と推定できます。

外部の攻撃者が端末の掌握なしに任意の客室の操作を行う

先ほどまでの悪用に際して、攻撃者は任意の部屋の操作を行うためには、まずコントロールサーバにアクセス可能である客室タブレットを掌握する必要がありました。

ただしこれでは、攻撃者が他の客室をハックするためには、毎回実際の宿泊客として任意の客室タブレットに侵入する必要があります。 そのため次は客室タブレットなしに攻撃者がコントロールサーバにアクセスする方法を模索しました。

コントロールサーバのIPアドレスは172.********であり、adb接続で得られるデバッグログから、通常のHTTP接続で接続可能であることがわかります。 しかしながら、当該サーバは、客室ゲストに開放されているゲスト用アクセスポイントからの接続は行えませんでした。

以下はゲストに開放されている*******-Guestに接続したPCからコントロールサーバのIPアドレスへのpingの結果です。

user@shu-mbp ~ % ping 172.********
PING 172.******** (172.********): 56 data bytes
Request timeout for icmp_seq 0
^C
--- 172.******** ping statistics ---
2 packets transmitted, 0 packets received, 100.0% packet loss

pingのレスポンスがないことから、ゲスト用アクセスポイントからコントロールサーバへの疎通がとれていません。よって攻撃者はコントロールサーバにアクセスするために、まずはコントロールサーバに疎通可能なネットワークに接続する必要があるとわかります。

なおタブレットは、客室機能を客室端末の操作で実現するためにコントロールサーバへのアクセスが可能となっています。 以下はデバッグ接続によって確立した端末のシェルでのpingの結果です。

user@vm-tester:~/work$ adb shell
2|X705F:/ $ ping 172.********
PING 172.******** (172.********) 56(84) bytes of data.
64 bytes from 172.********: icmp_seq=1 ttl=62 time=272 ms
^C
--- 172.******** ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 272.203/272.203/272.203/0.000 ms

タブレットからコントロールサーバへの疎通が可能であることから、端末はゲスト用アクセスポイントではないネットワークへアクセスしているか、何らかのIPフィルタリングが行われていることが推測できます。

そこでキオスクアプリの解析をさらに進めました。するとタブレットにはステルスの専用アクセスポイントが用意されていることが判明しました。つまり、ゲストに公開されているSSIDではコントロールサーバにアクセスできないようにネットワークレイヤでフィルタリングされているということです。

それでは安心でしょうか。いいえ、残念ながら

以下はキオスクアプリのメインアクティビティで実行されるwifiSetting()メソッドのコードです。端末がネットワークに接続していない場合、ステルスSSIDである*******-Tabletに、パスフレーズ**********で接続を行う処理となっています。

    private void wifiSetting() {
        Object object = (WifiManager)this.getSystemService("wifi");
        WifiConfiguration wifiConfiguration = new WifiConfiguration();
        try {
            ConnectivityManager connectivityManager = (ConnectivityManager)this.getSystemService("connectivity");
            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
            boolean bl = networkInfo != null && networkInfo.isConnectedOrConnecting();
            Log.w((String)"wifi", (String)String.valueOf(bl));
            if (!bl) {
                Log.w((String)"wifi", (String)"HOTEL_WIFI\u8ffd\u52a0");
                wifiConfiguration.SSID = "\"*********-Tablet\"";
                wifiConfiguration.hiddenSSID = true;
                wifiConfiguration.allowedProtocols.set(1);
                wifiConfiguration.allowedProtocols.set(0);
                wifiConfiguration.allowedKeyManagement.set(1);
                wifiConfiguration.allowedPairwiseCiphers.set(2);
                wifiConfiguration.allowedPairwiseCiphers.set(1);
                wifiConfiguration.allowedGroupCiphers.set(0);
                wifiConfiguration.allowedGroupCiphers.set(1);
                wifiConfiguration.allowedGroupCiphers.set(3);
                wifiConfiguration.allowedGroupCiphers.set(2);
                wifiConfiguration.preSharedKey = "\"**********\"";
                wifiConfiguration.status = 2;
                int n = object.addNetwork(wifiConfiguration);
                Log.w((String)"wifi", (String)String.valueOf(n));
                object.enableNetwork(n, false);
                object.enableNetwork(n, true);
                object = 0;
                while ((Integer)object < 5) {
                    SystemClock.sleep((long)1000L);
                    object = (Integer)object + 1;
                }
            } else {
                Log.w((String)"wifi", (String)String.valueOf(networkInfo.isConnected()));
            }
            bl = (object = connectivityManager.getActiveNetworkInfo()) != null && object.isConnectedOrConnecting();
            Log.w((String)"wifi", (String)String.valueOf(bl));
            return;
        }
        catch (Exception exception) {
            exception.printStackTrace();
            return;
        }
    }

このように専用SSIDはクライアント証明書などの認証は行われず、あくまでパスフレーズでの認証を行っており、そしてそのパスフレーズがアプリ内にハードコーディングされているのです。

次に、ネットワーク接続の裏付けを取るため、タブレットが実際に接続しているアクセスポイントを確認しました。以下は端末をセーフモードで起動し、設定アプリでWifi接続情報を表示したときの画面です。

画像のとおり、端末はゲスト用SSID********-Guestではなく、アプリ内で定義されている********-Tabletに接続されていることがわかります。このことから、攻撃者は当該アクセスポイントに接続することでコントロールサーバにアクセスできることが推定できました。

以上、攻撃者は悪用のために客室内の端末を掌握する必要はなく、ネットワーク上からコントロールサーバに対して任意のタイミングで任意の部屋のコントロールが可能であるとわかりました。

実際の環境ではアクセスポイント********-Tabletの電波が届く範囲内でのみ悪用できる形ですが、攻撃者は事前にネットワーク上へバックドアを設置しておけば(どこかの客室にラズパイを設置したり、タブレットマルウェアをインストールしたり)、設置後は場所を問わず攻撃することが可能です。

原因の推測と対策

この問題の原因はずばり認証の欠如です。さらに今回はネットワーク分離という障壁は存在したものの、「WPAエンタープライズ」などの強固な認証方式は利用されず、「WPAパーソナル」という攻撃者にパスフレーズが漏れると容易に悪用されうる方式を利用していました。さらに内部で利用されるRoom No.も現実世界の部屋番号とリンクしており、攻撃者は容易に攻撃ターゲットを絞ることが可能でした。

対策

コントロールサーバの認証を実装する

各端末で異なるパスワードもしくはクライアント証明書を発行し、コントロールサーバで検証します。これで仮に1つの客室タブレットが掌握されたとしても他客室への影響は及びません。

Wifiネットワークの認証にWPAエンタープライズを採用する

攻撃を防ぐ意図かは不明ですが、SSIDによってネットワーク分離していたのはセキュリティ上望ましいです。ただしWPAパーソナルを利用していたため、アプリ解析などでパスフレーズが窃取されると攻撃者による悪用が容易となります。そのためWPAエンタープライズ(EAP-TLS)と呼ばれる攻撃者が悪用しづらい強固な認証方式を利用するべきです。なお認証に利用する証明書はハードウェア保護されたAndroid Keystoreに保管しておけば証明書や秘密鍵が端末外に取り出しにくくなり、仮にキオスクアプリが解析されてもパスフレーズのように簡単に悪用できない利点があります。

アプリを難読化する(緩和策)

今回他客室情報へのアクセスを行わないまでもここまで短時間で脆弱性を示す間接的な証跡を得られたのは、キオスクアプリが難読化されていなかったからです。そもそもキオスクアプリ開発者はapkファイルが抽出されるとは思わなかったでしょうが、こういった地道な防御策も攻撃者から身を守ります。もちろん時間をかければ難読化されていても突破されるため、あくまで緩和策となります。

まとめ

高級ホテルに存在した客室タブレットシステムの脆弱性について解説しました。

他客室のなりすましが可能になるまでにいくつもの技術的ハードルがありましたが、複数の設定不備を組み合わせる事でここまで至りました。

設定不備項目 結果
USBデバッグが有効 侵入ポイントになった
キオスクアプリの起動順位が不十分 侵入ポイントになった
物理ボタン操作が有効 攻撃タイミングが増大
セーフモードでの起動が可能 端末設定のデバッグ・切り分けが容易に
アプリが難読化されていない 解析容易化・さらなる攻撃の足掛かりに
OEMロック解除が可能な端末 スパイ悪用の容易化・永続化(未検証)
ネットワーク分離が不十分 ネットワーク上からのアクセスが可能に
サーバによる認証が欠如 任意の客室の操作が可能に

今回は旅行中という限られた数時間でここまで調査できたわけですが、どれかひとつでも障壁があればこのような結果にはならなかったかもしれません。

キオスクアプリを開発する際はこれらの設定不備項目に該当するものがないかひとつひとつ確認し、確実に穴をふさぐことを推奨します。

ちなみにここで詳細は記載しませんが、客室タブレットには新聞閲覧機能を有しており、その認証情報がアプリデータに平文で保存されていた脆弱性も発見しています(報告・修正済み)。このようにアプリデータは全て攻撃者に確認されるという意識をもって開発しなければなりません。

脆弱性の公表について

発見した脆弱性は技術的詳細情報を含めてホテル運営者および開発者にIPAを通して報告を行っており、稼働中のシステムは全て改修済みの旨の連絡を受けています。また、稼働中システムに関連する脆弱性としては珍しくCVE-IDが発行され、JVNによる公表もされました。

客室向けタブレットシステムにおける複数の脆弱性(JVN#42445661) | LAC WATCH

開発者様においては報告した問題に対して真摯な対応をとっていただき誠に感謝しております。

タイムライン

  • 2022/09/16: 脆弱性の発見
  • 2022/09/30: 複数のホテルに導入されている可能性を鑑み、ソフトウェア製品の脆弱性としてIPAに報告
  • 2022/10/03: IPAより受信報告
  • 2023/02/17: IPAより受理報告、「ホテル独自のカスタマイズによる問題の可能性を考え、ホテル運営者にWebアプリケーションの脆弱性としていったん通知、応答によってはソフトウェア製品の脆弱性として扱う」旨を受領
  • 2023/02/27: IPAより開発者へ連絡開始
  • 2024/03/29: IPAに対して対応状況の確認を行う
  • 2024/04/01: IPAを通じて開発者から「導入中のホテルに対して改修作業中」である旨を受領
  • 2024/09/30: 脆弱性情報の公表(JVN#42445661)

弊社では客室タブレットシステムを含むあらゆるモノに対してのペネトレーションテストを行っております。サービスの詳細については別途お問い合わせください。