Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

22
Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた Geckoと仲良くなりたい人主催 FxOS Gecko勉強会 2013.9.30 @ Mozilla Japan オフィス

description

2013年9月30日に開催される「Geckoと仲良くなりたい人主催 FxOS Gecko勉強会」の発表資料です。

Transcript of Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

Page 1: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

Geckoと仲良くなりたい人主催 FxOS Gecko勉強会 2013.9.30 @ Mozilla Japan オフィス

Page 2: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

2

本日お話する内容

• パッケージアプリとは

• パッケージ型アプリのインストール処理

• アプリの非公式インストールとその対策

Page 3: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

3

自己紹介

本発表は私の個人的な調査に基づくものです。 内容に誤りがあるかもしれませんがご了承ください

名前 西村 宗晃 (にしむねあ) ・https://www.facebook.com/muneaki.nishimura 職業 セキュリティエンジニア ・セキュア開発のコンサルティング ・Android端末~アプリの開発支援

Page 4: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

4

パッケージ型アプリとは

Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

Page 5: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

5

Firefox OSのアプリ

• HTML, JS, CSSといったWebの技術で開発 • アプリを構成するファイルの格納場所によって2種類に分類

⁃ ホスト型アプリ ファイルはWebサーバ上に置き、通常は端末からHTTP(S)でアクセスして実行する

⁃ パッケージ型アプリ ファイルはZIPファイルに圧縮し、端末上にダウンロードして実行する

• 全てのアプリにはApp Manifestファイルが必要 ⁃ アプリのインストールや動作に必要な情報(アプリ名等)を定義したファイル

ホスト型アプリの場合はサーバ上に格納 パッケージ型アプリの場合はZIPファイルの中に格納

Page 6: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

6

パッケージ型アプリの種類

Web (未信頼アプリ)

Privileged (特権アプリ)

Certified (認定アプリ)

• 通信事業者や端末メーカーによって認定されたアプリ → プリインストールアプリ

• ほぼ全てのWeb APIが利用できる

• Marketplaceによる審査を経て承認されたアプリ → Marketplaceの署名が付いたアプリ

• 限られたWeb APIしか利用できない

• 上記以外の通常アプリ • ほとんどのWeb APIが利用できない

※ 主に端末設定や課金、ハードウェア制御に関するWeb APIが利用できない

Page 7: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

7

インストール方法 Certified Privileged Web

Marketplaceから入手 × その他のウェブサイトから入手 (Apps.installPackageを使用) × × Firefox OS SimulatorからPush ×

商用端末へのインストール可否

※1 開発用ビルド(MOZ_OFFICIAL_BRANDING=false)の場合はインストール可 ※2 配布元のURLが検証されるのでMarketplaceの署名付きアプリであってもインストール不可

※1

※2

Page 8: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

8

パッケージ型アプリのインストール処理

Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

Page 9: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

9

Marketplaceからのインストール①

Firefox OS端末 Marketplaceサーバー Marketplaceアプリ Gecko Systemアプリ

アプリのインストールを要求 Apps.installPackage

Mini Manifestを取得 XmlHttpRequest

Mini Manifestファイルを送信

インストール確認画面を表示 webapps-ask-install

インストール許可を通知 webapps-install-granted

⁃ 既にインストール済みでないことを確認

⁃ HTTPレスポンスヘッダのContent-Typeがapplication/ x-web-app-manifest+jsonであることを確認

⁃ Mini Manifestに構文エラーがないことを確認 ⁃ Mini Manifestのinstalls_allowed_fromに書かれている

オリジンとアプリ配布元が等しいことを確認 ⁃ 今後のアップデート有無の確認のためにEtagを記録

↓ ↓次ページに続く↓ ↓

⁃ インストールがキャンセルされた場合は終了

Page 10: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

10

Marketplaceからのインストール②

Firefox OS端末 Marketplaceサーバー Marketplaceアプリ Gecko Systemアプリ

⁃ 取得したMini Manifestを/data/local/webapps/{uuid} /update.webappという名前で保存

アプリ本体を取得

アプリ本体 (署名付きZIPファイル)を送信 ⁃ アプリの署名を検証 ⁃ Marketplaceの署名が付いている場合は、アプリの取得

元がMarketplaceであることを確認 ⁃ アプリ本体に含まれるApp Manifestを検証。構文エラー

やMini Manifestの記載内容との違いがある場合は終了 ⁃ App Manifestのアプリ種別を確認。certifiedが指定され

ている場合は終了。またprivilegedが指定されているのに未署名の場合も終了

⁃ アプリ本体とApp Manifestを/data/local/webapps/ {アプリディレクトリ}/に保存

⁃ アプリの管理に必要なメタ情報一式を/data/local/ webapps/webapps.jsonに保存

⁃ App Manifestに宣言されたPermissionをアプリに付与 インストール完了通知を表示 installed

Page 11: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

11

Mini Manifestについて

• パッケージ型アプリのインストールに必要な情報を記述したマニフェストファイル Apps.installPackageの第一引数に指定される package_pathに指定されたURLからアプリ本体が

ダウンロードされる 記載する内容はApp Manifestと似ているが、幾つか

の項目が異なる ⁃ インストール時に不要な情報は持たない

(permission, launch_path, type, cspなど)

⁃ Mini Manifest独自の項目を持つ (package_path, release_notes, size)

以下の項目はアプリ本体に含まれるApp Manifestと完全に一致していなければならない ⁃ name, version, developer, locales

{ "name": "My App", "package_path": "http://my.com/app.zip", "version": "1.0", "size": 123456, "release_notes": "First release", "developer": { "name": "Developer Name", "url": "http://my.com/" }, "locales": { "se_SE": { "name": "Min balla app" } }, "icons": { "256": "/icons/256.png" } }

Page 12: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

12

アプリの署名について

• Mozillaの署名ツールで署名する https://wiki.mozilla.org/Apps/PrivilegedApplication/SigningService

• アプリの/META-INFに署名ファイルが含まれる manifest.mf

⁃ アプリの各ファイルのSHA1とMD5ハッシュを計算し、 BASE64エンコードした値を列挙したもの

zigbert.sf ⁃ manifest.mfのSHA1とMD5ハッシュを計算し、

BASE64エンコードした値を記述したもの

zigbert.rsa ⁃ zigbert.sfをMarketplaceの秘密鍵で署名し、署名値と

公開鍵証明書(X509のDER)をCMS形式で格納したもの

• 署名検証は .rsa →.sf →.mf の順に行われる

Manifest-Version: 1.0 Name: index.html Digest-Algorithms: MD5 SHA1 MD5-Digest: 0uGKBwq2RXW8JYA2VGzYfw== SHA1-Digest: X3uavo5AlDGIM5rN1P7qhuUnf0w= :

Signature-Version: 1.0 MD5-Digest-Manifest: 8n4aIIP04d7gLQ8yUe8Rcg== SHA1-Digest-Manifest: MeExZFwgDjJaFSlciXbVldOxcUE=

/META-INF/manifest.mf

/META-INF/zigbert.sf

Certificate: Data: Version: 3 (0x2) Serial Number: 1048577 (0x100001) Signature Algorithm: sha384WithRSAEncryption Issuer: C=US, O=Mozilla Corporation, :

/META-INF/zigbert.rsa ※

※openssl pkcs7 -inform DER -in zigbert.rsa -print_certs –text で公開鍵証明書を出力したもの

Page 13: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

13

webapps.jsonについて

端末にインストールされたアプリを管理するためのJSONファイル※1

“{8750614d-a19a-44c3-aa02-2b084f8e0c7d}”: { ― アプリの格納ディレクトリ名

“origin”: “app://{8750614d-a19a-44c3-aa02-2b084f8e0c7d}”, ― アプリに割り当てられたドメイン名

“installOrigin”: “https://marketplace.firefox.com”, ― インストール元のオリジン

“installTime”: 132333986000, ― インストールされた時刻

“manifestURL”: “https://marketplace.firefox.com/mini.webapp”, ― Mini Manifestの取得元

“removable”: true, ― アンインストールの可否

“localId”: 1021, ― インストール順に割り当てられたアプリの通し番号

“etag”: “¥”6f996751558be05eaa8bec8db03edbe0¥“”, ― Mini Manifestのダウンロード時に取得したETag “appStatus”: 2, ― アプリの種別 (2=特権アプリ) “basePath”: “/data/local/webapps”, ― アプリのインストールディレクトリパス

“receipt”: null, ― 課金アプリの購入に関する情報

“name”: “My App”, ― アプリ名

“csp”: “”, ― 標準のCSP設定からの変更点

:

}

※1 Androidで言うところの/data/system/packages.list やpackages.xml のようなもの

Page 14: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

14

Permissionについて

• 端末の機能にアクセスするために必要な権限 電話帳へのアクセス、カメラや通話機能の使用など 使用する機能に対応するPermissionをApp Manifestに宣言する

• アプリの種類に応じて、使用できるPermissionと権限の付与のされ方が異なる 例えば、認定アプリからの電話帳アクセスは暗黙的に許可される

が、特権アプリが電話帳へアクセスする場合は、実行の都度、ユーザーにアクセス可否を確認するためのプロンプトが開かれる

Permissionとその保護レベルは以下のコードに定義されている gecko/dom/apps/src/PermissionsTable.jsm

• 付与されたPermissionは端末のSQLite DBで管理される /data/local/permissions.sqlite

/data/local/permissions.sqlite

Page 15: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

15

Firefox OS Simulatorによるインストール①

ホストPC Firefox OS端末

Firefox ブラウザ

Firefox OS Simulator

ADB Client

ADB Server

Gecko

ADB Device Daemon (adbd)

DeviceRoot Actor

Webapps Actor

Debugger Server tcp:6000

tcp:6000

アプリ本体の転送 (ADB protocol) アプリのインストール要求 (Mozilla debugging protocol)

Page 16: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

16

Firefox OS Simulatorによるインストール②

PCから端末へのポートフォワードを設定

アプリ本体を端末に転送

デバッガの接続完了を通知

デバッガの提供する機能一覧を要求

デバッガがアプリ管理機能(webappActor)を持っていることを通知

アプリのインストールを要求

インストール完了を通知

Firefox OS Simulator ADB Client ADB Server ADB Device

Daemon DeviceRoot

Actor Webapps

Actor Debugger

Server

ホストPC Firefox OS端末

adb forward tcp:6000 tcp:6000

adb push {application file path} /data/local/tmp

{“from” : “root”, “applicationType” : “browser”, …}

{“to”:”root”, “type” : “listTabs”}

{“from” : “root”, “webappActor” : “conn1.webapp3”, …}

{“to”:”conn1.webapp3”, “type” : “install”, “appId”: “{uuid}”, …}

{“from” : “conn1.webapp3”, “type”:“webappsEvent”, “appId”:”{uuid}”}

デバッガの接続確認画面を表示 (Systemアプリに画面表示を要求)

インストール処理 (アプリの署名検証は行わない)

Page 17: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

17

アプリの非公式インストールとその対策

Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

Page 18: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

18

非公式なインストールとは

Androidのroot化ツール(の一部)を用いてroot権限が取得できる ⁃ adbを用いてLinux KernelやAndroidの脆弱性を突くプログラムを実行する ⁃ ブートローダをアンロックし、リカバリツールでsuをインストールする

root権限でOSの制限を解除することで、禁止されたアプリをインストールできる ⁃ 特権アプリの署名検証を無効化し、Marketplace以外から取得する ⁃ 第三者が作成した認可アプリをインストールする

本資料は端末のroot化や非公式なアプリのインストールを推奨するものではありません。 故障や不具合などが生じても責任は負いませんので自己責任で実施してください

Page 19: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

19

本資料で説明する非公式インストールの手順

• 特権(Privileged)アプリをMarketplace以外のウェブサイトから入手する • 認定(Certified)アプリをFirefox OS SimulatorからPushでインストールする

これらの手順はエミュレータ以外での動作確認をしていないため、実端末では動作しない可能性があります

Page 20: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

20

特権アプリをウェブサイトからインストール

① 端末をroot化する ② 端末からomni.jaファイルを抜き出す

adb pull /system/b2g/omni.ja

③ omni.jaからアプリの署名検証に使用される JSファイル(Webapps.jsm)を抽出する unzip omni.ja modules/Webapps.jsm

④ 抽出したJSファイルをテキストエディタで開き、左記のとおりにコードを書き換える

⑤ 変更したJSファイルをomni.jaに保存する zip omni.ja modules/Webapps.jsm

⑥ 変更したomni.jaを端末に転送する adb shell mount –o rw,remount /system adb push omni.ja /system/b2g/omni.ja

⑦ ウェブサイトから特権アプリをインストールする (a) 変更後の署名検証エラーが起きても処理を続行するように変更 (b) Marketplace以外からのインストールでも続行するように変更 (c) ids.jsonがなくてもインストールを続行するように変更

(a)

(b)

(c)

Page 21: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

21

認定アプリをFirefox OS SimulatorからPush

① 基本的な手順は前ページと同じ ② omni.jaからRemote Debugger経由でアプリをイ

ンストールする際に使用されるJSファイル(dbg-webapps-actors.js)を抽出する unzip omni.ja chrome/chrome/content/dbg-webapps-actors.js

③ 抽出したJSファイルをテキストエディタで開き、左記のとおりにコードを書き換える

④ 変更したJSファイルをomni.jaに保存する zip omni.ja chrome/chrome/content/dbg-webapps-actors.js

⑤ 変更したomni.jaを端末に転送する ⑥ Firefox OS Simulatorで認定アプリをPushする

(a) アプリの種別がcertifiedでもインストール処理を継続するように変更

(a)

Page 22: Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた

22

非公式インストールを防ぐには

• 製品向けビルド時はadbのshell, pullコマンドを無効化する ⁃ Androidのroot化ツールを使用できなくするため ⁃ Webアプリの開発者はこれらのコマンドが無くても困らない

• systemとrecovery領域の改ざんを防ぐ ⁃ 商用機でのブートローダ―アンロックを禁止する ⁃ ハードウェアの機能(TrustZone等)を用いて改ざん検知を行う

⁃ 改ざんを検知した場合はバックアップデータから復元してデータを初期状態に戻す ⁃ もちろんバックアップデータ自体も改ざんから守る

• 他にも色々な対策が必要 ⁃ LSMでGeckoアップデート時を除くsystem領域のremountを防ぐなどなど