firefox os パッケージ型アプリ インストールの仕組みを調べてみた
DESCRIPTION
2013年9月30日に開催される「Geckoと仲良くなりたい人主催 FxOS Gecko勉強会」の発表資料です。TRANSCRIPT
Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた
Geckoと仲良くなりたい人主催 FxOS Gecko勉強会 2013.9.30 @ Mozilla Japan オフィス
2
本日お話する内容
• パッケージアプリとは
• パッケージ型アプリのインストール処理
• アプリの非公式インストールとその対策
3
自己紹介
本発表は私の個人的な調査に基づくものです。 内容に誤りがあるかもしれませんがご了承ください
名前 西村 宗晃 (にしむねあ) ・https://www.facebook.com/muneaki.nishimura 職業 セキュリティエンジニア ・セキュア開発のコンサルティング ・Android端末~アプリの開発支援
4
パッケージ型アプリとは
Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた
5
Firefox OSのアプリ
• HTML, JS, CSSといったWebの技術で開発 • アプリを構成するファイルの格納場所によって2種類に分類
⁃ ホスト型アプリ ファイルはWebサーバ上に置き、通常は端末からHTTP(S)でアクセスして実行する
⁃ パッケージ型アプリ ファイルはZIPファイルに圧縮し、端末上にダウンロードして実行する
• 全てのアプリにはApp Manifestファイルが必要 ⁃ アプリのインストールや動作に必要な情報(アプリ名等)を定義したファイル
ホスト型アプリの場合はサーバ上に格納 パッケージ型アプリの場合はZIPファイルの中に格納
6
パッケージ型アプリの種類
Web (未信頼アプリ)
Privileged (特権アプリ)
Certified (認定アプリ)
• 通信事業者や端末メーカーによって認定されたアプリ → プリインストールアプリ
• ほぼ全てのWeb APIが利用できる
• Marketplaceによる審査を経て承認されたアプリ → Marketplaceの署名が付いたアプリ
• 限られたWeb APIしか利用できない
• 上記以外の通常アプリ • ほとんどのWeb APIが利用できない
※ 主に端末設定や課金、ハードウェア制御に関するWeb APIが利用できない
※
7
インストール方法 Certified Privileged Web
Marketplaceから入手 × その他のウェブサイトから入手 (Apps.installPackageを使用) × × Firefox OS SimulatorからPush ×
商用端末へのインストール可否
※1 開発用ビルド(MOZ_OFFICIAL_BRANDING=false)の場合はインストール可 ※2 配布元のURLが検証されるのでMarketplaceの署名付きアプリであってもインストール不可
※1
※2
8
パッケージ型アプリのインストール処理
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を記録
↓ ↓次ページに続く↓ ↓
⁃ インストールがキャンセルされた場合は終了
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
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" } }
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 で公開鍵証明書を出力したもの
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 のようなもの
14
Permissionについて
• 端末の機能にアクセスするために必要な権限 電話帳へのアクセス、カメラや通話機能の使用など 使用する機能に対応するPermissionをApp Manifestに宣言する
• アプリの種類に応じて、使用できるPermissionと権限の付与のされ方が異なる 例えば、認定アプリからの電話帳アクセスは暗黙的に許可される
が、特権アプリが電話帳へアクセスする場合は、実行の都度、ユーザーにアクセス可否を確認するためのプロンプトが開かれる
Permissionとその保護レベルは以下のコードに定義されている gecko/dom/apps/src/PermissionsTable.jsm
• 付与されたPermissionは端末のSQLite DBで管理される /data/local/permissions.sqlite
/data/local/permissions.sqlite
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)
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アプリに画面表示を要求)
インストール処理 (アプリの署名検証は行わない)
17
アプリの非公式インストールとその対策
Firefox OS パッケージ型アプリ インストールの仕組みを調べてみた
18
非公式なインストールとは
Androidのroot化ツール(の一部)を用いてroot権限が取得できる ⁃ adbを用いてLinux KernelやAndroidの脆弱性を突くプログラムを実行する ⁃ ブートローダをアンロックし、リカバリツールでsuをインストールする
root権限でOSの制限を解除することで、禁止されたアプリをインストールできる ⁃ 特権アプリの署名検証を無効化し、Marketplace以外から取得する ⁃ 第三者が作成した認可アプリをインストールする
本資料は端末のroot化や非公式なアプリのインストールを推奨するものではありません。 故障や不具合などが生じても責任は負いませんので自己責任で実施してください
19
本資料で説明する非公式インストールの手順
• 特権(Privileged)アプリをMarketplace以外のウェブサイトから入手する • 認定(Certified)アプリをFirefox OS SimulatorからPushでインストールする
これらの手順はエミュレータ以外での動作確認をしていないため、実端末では動作しない可能性があります
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)
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)
22
非公式インストールを防ぐには
• 製品向けビルド時はadbのshell, pullコマンドを無効化する ⁃ Androidのroot化ツールを使用できなくするため ⁃ Webアプリの開発者はこれらのコマンドが無くても困らない
• systemとrecovery領域の改ざんを防ぐ ⁃ 商用機でのブートローダ―アンロックを禁止する ⁃ ハードウェアの機能(TrustZone等)を用いて改ざん検知を行う
⁃ 改ざんを検知した場合はバックアップデータから復元してデータを初期状態に戻す ⁃ もちろんバックアップデータ自体も改ざんから守る
• 他にも色々な対策が必要 ⁃ LSMでGeckoアップデート時を除くsystem領域のremountを防ぐなどなど