読者です 読者をやめる 読者になる 読者になる

Log.i53

Themidaのアンパックを目指すブログ改め使い物になるえんじにゃを目指すブログ

Apache Cordova Vulnerabilityの記事を読んだ

Android 翻訳

 セキュキャン2015応募用紙の選択問題14を素で解きたい人生だった・・・がやはり無理だったのでいろいろ調べました・・・!選択問題14はAndroidアプリのWebViewオブジェクトにおけるXAS(Cross-Application Scripting)脆弱性について取り上げたもののようです。以下の記事を参考にすれば、おそらく解答文を構築することができるはずです。

元記事

securityintelligence.com

前書き

 IBM Security X-Force ResearchチームはApache Cordova(以前はPhoneGapと呼ばれていた)プラットフォーム上で構築される多くのAndroidアプリケーションに影響を与える深刻な脆弱性を発見しました。AppBrainによると、この脆弱性はAdnroidアプリの約5.8%に影響を与えます。5.8%というと低い割合のように聞こえるかもしれませんが、いくつかの広く利用されているAndroidアプリケーションは、Cordovaの上に構築されているのです。実際に研究者が"bank"というキーワードを含む248のアプリケーションを分析したところ、25のアプリ - 約10% - がCordovaを使用して構築されていることがわかりました。これは、攻撃者がユーザの銀行情報を盗んで、口座から資金を引き出して別のアカウントに転送するなどのトランザクションが実行可能になることを意味しています。

 これらのAndroid Cordovaベースのアプリケーションを使用する何百万人ものユーザは、ログイン資格情報のような機密情報が危険にさらされています。攻撃者は、これらのアプリケーションから機密情報を窃取すると、それらを偽装してアカウントにアクセスして本人に代わって購入を行うことさえ出来ます。IBMのCyber Security Intelligence Indexによって攻撃やセキュリティインシデントの成功の95%はヒューマンエラーによって引き起こされていることが判明しており、ハッカーたちは積極的に活用するためにこのような脆弱性を模索し続けています。

 この脆弱性を発表する前に、IBM Securityのチームはその責任ある情報開示の方針に基づき、Cordovaチームにまず非公開でセキュリティ上の脆弱性を報告しました。その結果がpatches are available in the latest Cordova version 3.5.1となっています。IBMのチームの分析では、攻撃者がこの脆弱性を悪用することは非常に容易であることを示しています。特定の状況下では、Cordovaベースのアプリケーションに関連付けられているCookieなどの機密情報を盗むために、悪質なWebサイトへのナイーブなモバイルブラウジング(より成功しやすいドライブバイ・エクスプロイテーションとして知られている)によって、リモートで悪用される可能性もあります。

 Apache Cordovaの脆弱性Cross-Application Scriptingにより、例えば、Cordovaベースのアプリケーションのコンテキスト内で悪意あるJavaScript(JS)コードの実行を可能にします。また、我々がCordova内で検出したその他の脆弱性に起因して、そのようなコードが盗みだした情報を秘密裏に攻撃者に届けることを可能にしています。 従って、我々は全ての開発者が最新のCordovaバージョン(3.5.1)にアップグレードして、我々のホワイトペーパーで詳述されている緩和策を適用することを強くお勧めします。IBM WorklightにはApache Cordovaが使用されているため、これにも同様の影響を与えます。我々IBMは、我々のクライアントのセキュリティ向上への取り組みに努めています。

テクニカルディテール

Androidアプリケーションセキュリティの基礎

 Androidアプリケーションはサンドボックス環境で実行されます。このサンドボックスにより、あるアプリが適切な権限なしに他のアプリの持つ機密情報にアクセス出来ないように、データの機密性と安全性が保証されます。例えば、Android公式のブラウザアプリケーションはCookieやキャッシュ、閲覧履歴などの機密情報を保持していますが、これらの情報にサードパーティ製のアプリがアクセスすることはできません。サンドボックスは、パッケージごとにLinuxのユーザIDを割り当てるなど、いくつかの技術に依存しています。従って、あるアプリが保有するファイルのようなリソースに別のアプリからアクセスすることはデフォルトでは不可能となっています。

 サンドボックス機構はセキュリティの観点で素晴らしい技術ですが、アプリどうしの相互運用性を低下させることにも繋がります。ブラウザの例に戻れば、ユーザがGoogle Playのウェブサイトを閲覧した時に、ブラウザがGoogle Playのアプリケーションを呼び出したいと考えるでしょう。この種の相互運用性をサポートするために、Androidは高レベルなアプリ間の通信メカニズムを提供しています。この通信は、通常ペイロードとターゲットアプリケーションのコンポーネントの両方を保持した、Intentと呼ばれる特別なメッセージを利用して行われます。Intentはターゲットアプリケーションのコンポーネントを指定して明示的に送信するか、またはターゲットを未指定にして暗黙的に送信することができます。暗黙的に送信された場合、そのURIスキームやアクション、カテゴリのようなIntentの持つパラメータに従って、Androidが通信先アプリケーションを自動的に導出します。

アプリ間通信における攻撃的側面

 Intentを受信するためのゲートが開いているApplicationコンポーネントは、その攻撃敵側面を増加させます。次の図に示されるように、このようなコンポーネントマルウェアによって局所的に攻撃することができます:
f:id:i53:20150624004505p:plain

 さらに深刻なのが、特定の状況下において、エクスプロイトコードを含む悪質なWebサイトに対して単純なクリックで誘導することで同様にリモートで攻撃可能であるということです:
f:id:i53:20150624004710p:plain

組み込みブラウザ(WebView)とCross-Application Scripting(XAS)

 Androidフレームワークによって提供されるWebViewオブジェクトは、開発者が自身のアプリ内にブラウザを埋め込むことを可能にします。この機能は、モバイル用アプリを開発する上では素晴らしい技術ですし、Apache Cordovaの基礎ともなっています。
 
 WebViewオブジェクトに読み込まれるWebページはWebView.loadUri APIによって制御されます。例えば、GoogleのWebサイトを開くために開発者は次のコードを記述することができます:

String url = "http://www.google.com";
WebView webView = ...
webView.loadUrl(url);

 しかし、攻撃者がこのURLを制御することは可能でしょうか? 次のコードを考えてみましょう:

String url = getIntent().getStringExtra("url");
WebView webView = ...
webView.loadUrl(url);

 攻撃者によって制御可能なデータが"url"パラメータに設定されたIntentが発行されたときに、このコードはCross-Application Scriptingの脆弱性となりえます。なぜなら、攻撃者が"url"パラメータを制御できるがために、WebViewオブジェクトに悪意あるJSコードを読み込ませることが可能となるからです。

XASエクスプロイテーションの防止

 ただ、バッファオーバーフロー脆弱性と同様に、これらは実行環境(この場合、WebViewオブジェクト)に手を加えることで、エクスプロイト成功の確率やその影響を低減させることができます。
 
 まず、JavaScriptはWebSettings.setJavaScriptEnabled(true)を明示的に呼び出さない限りはフェトルトでは無効になっています。JavaScriptが利用できなければ、攻撃者はおそらくフィッシング攻撃を行う以外には何もできなくなります。
 
 次に、WebViewオブジェクト内で実行されているコードには、任意のドメインに属するコードはその特定のドメインのDOMのみにしかアクセスすることができないという、著名なSame-Origin Policyが適用されています。これは、"javascript"URIスキームペイロードの魅力を大きく減少させます。攻撃者は、既にいくつかの他のURLがプリロードされた後でWebViewのURLを強制的に変更させることができる場合(2011年にこの挙動を悪用するAndroidブラウザ内のXAS脆弱性してCVE2011-2357を開示している)や、JavaScriptから任意のネイティブコードへのブリッジがある場合にのみ興味を持っているためです。
 
 攻撃者にはファイルのURIスキームを悪用することもできます。過去(Android 4.0以下)で、ファイルURIによってロードされたJavaScriptコードはローカルファイルを含む任意のOriginへのユニバーサルアクセス権限を持っていました。これは脆弱なアプリに関連した機密ファイルの自明な窃盗を可能にするので、明らかに悪いことです。Googleはこの脅威を把握し、上記のエクスプロイテーションを防ぐためにJelly Bean(Android 4.1)においては新たな機構が提供されました。これはファイルURIからロードされたJSコードの機能を制限するAPIのセット(WebSettings.setAllowUniversalAccessFromFileURLsとWebSettings.setAllowFileAccessFromFileURLs)になっています。この設定は両方ともデフォルトでは無効となっており、それぞれ他のファイルへのアクセスと任意のoriginへのアクセスを防止しています。

CordovaのXAS脆弱性

 攻撃者は、2つの異なる方法でCordovaのWebViewのURLに影響を与えることが出来ます。
 
 では、1つ目の問題を見てみましょう:

public void loadUrl(String url) {
  if (url.equals("about:blank") || url.startsWith("javascript:")) {
    this.loadUrlNow(url);
  } else {
    String initUrl = this.getProperty("url", null);
    // アプリの最初のページなら引数で渡されたURLをセットする
    if (initUrl == null) {
      this.loadUrlIntoView(url);
    }
    // それ以外の場合、Activityのエクストラバンドルに指定されたURLをセットする
    else {
      this.loadUrlIntoView(initUrl);
    }
  }
}

 まず、CordovaWebView.loadUrl(String url)とCordovaWebView.loadUrl(String url, int time)は"url"引数の代わりにIntentの"url"パラメータを消費しています。最初のメソッドでは、引数のURIスキームがJavaScriptではなく、URIが"about:blank"でない場合にのみ実行されます。したがって、Intentの"url"パラメータが攻撃者による影響を受けた場合、WebViewのURLを制御されてしまいます。

 2つ目の問題は、"errorurl"というIntentの追加パラメータに関連するもので、これが元のURLのロード中にエラーが発生した場合にのみ利用されているという事実にも関わらず、1つ目の問題と非常に類似しています。その詳細については、当社のホワイトペーパーに記載されています。

理論的脆弱性から実行可能なエクスプロイトへの転換

 前述した防御機構が有効になっている場合にはXASの脆弱性を悪用することは困難です。残念ながら、Cordovaベースのアプリであるという性質上、そのケースにはあてはまりません。WebViewのセットアップ(CordovaWebView.setup)を担当している次のコードを見てみましょう:

private void setup() {
  ...
  WebSettings settings = this.getSettings();
  settings.setJavaScriptEnabled(true);
  ...
  if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
    Level16Apis.enableUniversalAccess(settings);
  }
 
  @TargetApi(16)
  private static class Level16Apis {
    static void enableUniversalAccess(WebSettings settings) {
      settings.setAllowUniversalAccessFromFileURLs(true);
    }
  }

 CordovaはJavaScriptのブリッジ機構を使用して、Cordova上に実装されたアプリのネイティブ機能へのアクセスを可能にしているため、JavaScriptが有効にされていることは明らかです。また、外の世界と通信できるようにするためにローカルファイルが許可されているため、ファイルURIからのユニバーサルアクセスが有効となっています。JavaScriptが有効になっており、ユニバーサルアクセスが許可されているという事実は、ローカルまたはリモート(ドライブバイ)の両方でエクスプロイトを構築する機会をマルウェアに与えています。本稿では、リモートによる攻撃を示します。ローカルの攻撃についてはアドバイザリに記載されています。

Cordovaのリモートによる攻撃

 特定の状況下において(完全な詳細については当社のホワイトペーパーを参照してください)、Cordovaの脆弱性はナイーブなWebサイト上での簡単なクリックによってリモートからのエクスプロイトを可能にします。クリック以降、エクスプロイテーションは完全に自動化されてしまいます。攻撃者の目的は、脆弱性のあるCordovaベースのアプリケーションに関連付けられている重要なファイルを盗み出すことです。CordovaではJavaScriptとファイルURIからのユニバーサルアクセスが許可されているという事実から、この攻撃ではにおいて我々は"file://"URIスキームを悪用します。

 攻撃の概要は以下のとおりです:

  1. 騙されやすい被害者が悪意あるウェブサイトを参照する
  2. ドライブ・バイ・ダウンロード: 悪意あるウェブサイトは被害者のSDカードに自動的にHTMLファイルをダウンロードする.攻撃のアイデアは、ブラウザにダウンロードしたものがHTMLファイルであると示さないことで被害者を騙すことである.一部のブラウザは,任意のバイナリメタタイプのContent-Typeヘッダを含めることによってこれを行うことができる.
  3. 脆弱性の悪用: 悪意あるウェブサイトはCordovaベースのアプリのWebViewオブジェクト内でダウンロードされたファイルをロードさせる.これはブラウザにIntentオブジェクトを生成させる、Intent URIスキームを使用することで行われる.このIntentはファイルURIスキーム(例えば,file:///sdcard/Downloads/exploit.html)を使用してダウンロードされた攻撃者のHTMLファイルを参照することに寄ってCordovaの脆弱性のいずれかをトリガします。
  4. データの窃取: ロードされた攻撃者のJavaScriptコードはCordovaベースのアプリケーション下の任意のファイルのリードアクセス権限を持っている.読み取られたデータは当社のアドバイザリに記載されたその他の脆弱性を利用して攻撃者に送信される.

攻撃の概要図を以下に示します:
f:id:i53:20150624021732p:plain

XAS脆弱性に対する一般的な対策

 アプリの大多数において、Cross-Application Scriptingの問題を回避することは比較的容易です。開発者が上記の脆弱性を理解していれば、WebViewオブジェクトのURLをユーザのデータが完全に制御することは決して可能となりません。また、Androidマニフェストファイル内でエクスポートされたActivityは正当な理由がない限りnonexportedに設定するべきです。さらに、必要な場合を除いてJavaScriptを有効にしないこと、また、ファイルURIからのユニバーサルアクセスを許可しないことをお勧めします。

クレジット

Roee Hay (@roeehay), IBM Security Systems
David Kaplan (@DepletionMode), IBM Security Systems