Androidセキュリティ勉強会「WebViewの脆弱性」

いい加減なレジュメ

誰かへんなとこ指摘してくれるとうれしいなって...

自己紹介
  • goroh_kun
  • 本名とは関係ない
  • root化手法で名前知られているかも
  • sutegoma2のメンバーになった
  • 最近セキュリティの会社に就職した(かけもち?)
  • Androidセキュリティ部
  • JSSEC 脆弱性WGリーダ
  • 日本で販売されているAndroid端末のほぼすべてのroot取得方法、NANDアンロック方法を解析報告
WebViewの脆弱性の概要
  • JVNのWebViewに関する一覧を表示
    • 中身を見ても何が原因か書いていない→よくわからない
  • 出てきているのは氷山の一角
    • きりがないのでわざわざ報告しない
  • 大本のつくりをなんとかするしかない→Androidのつくりがそもそもいけてない
  • JPCERTに報告しても、そもそも修正が終わらないとデータベースに乗らない→来ても修正こないしそもそも報告なければ乗らない
  • 知らず知らずWebViewで脆弱性作りこんでいるかも
  • ここで会場に質問
    • eclipseAndroidつくったことあるひと→ほとんど
    • WebViewつかったことあるひと→10名くらい?
  • 今日話すことはほとんどはすでにネットワークで公開され、気をつけましょうといわれていることです
  • この記事は必読
なにがそもそも問題か?
  • JVNに書かれている内容→よくわからない
    • よっぽど迂闊な人じゃないと、こういうことにならないんじゃないの?
      • →そんなことはない。誰でもこの脆弱性をつくりこんでしまいそう
      • むしろWebViewを使ってサーバと連携するアプリを作ってると脆弱性作りこんでしまうかも
今日覚えてほしいキーワード
  • WebViewキャッシュ
  • addJavascriptInterface
  • fileスキーマ
WebViewキャッシュ
  • →ブラウザでブラウズするときにフォームのデータなどを保存するデータベース
  • 一般の人はパスワードを保存しますか?と聞かれるはいを押してしまう
  • 聞かれないでも勝手に保存するものもある(履歴、クッキー)
WebViewキャッシュのAndroidでの問題点
  • WebViewキャッシュの保存場所が一意に決まってしまうため攻撃しやすい
    • /data/data/${PackageName}/databases/webview.db
    • ファイルのパスがアプリケーションのパッケージ名から推測できてしまう
ここでデモ
  • Galaxy Nexus(Jelly Bean:4.1)でrootedな端末でデモをしてた
  • /data/data/com.google.android.browser
    • ここにwebview.dbがある
  • 持ち主はアプリのユーザ
  • 権限は660になっている
  • catするとパスワードだとかなんかアクセスしたURLだとかユーザ名っぽいのとか見える
  • どうもyahooにテストでつくったアカウントの情報(フォームの内容)が見れてるっぽい
  • データベース自体はsqliteというデータベースファイルでありバイナリだがパスワードやID部分は特に暗号化されておらず、WebView上で目視できる
  • WebViewキャッシュ自体は他アプリからの読み出しに関してはパーミッションで保護されているがWebView自身からの攻撃は保護できない
  • fileスキーマ
    • WebViewにURLを指定するときfile://が利用できる端末ローカルのファイルが見れる
    • WebViewとして表示できなかったとしてもjavascriptつかってサーバにあげれるんじゃね?
  • どういう問題?
    • 端末借りてブラウザつかってWebViewキャッシュで目grepしてパスワードとかをさがせちゃう
    • 標準ブラウザの問題点と組み合わせるとサーバにWebViewキャッシュをアップロード
    • 家電屋さんでログインするひとがいたりすると...
    • goroh_kun曰く「0dayの話じゃない。既知の話だw」
    • sutegoma2の人達にちょっと端末を貸すと目grepでパスワード&ID入手されるw
  • JPCERTのいう内部データというのは、アカウント情報も含んでいたということである...
  • file:///data/data/com.android.browser/databases/webview.db
    • WebViewのキャッシュの場所が固定されているのが問題だがそれだけじゃない
Android標準ブラウザの問題
  • ファイルのダウンロードが自動開始問題
    • リンクした瞬間ブラウザからファイルをダウンロードさせることが出来る
    • ダウンロード時にユーザに確認はなし(最近のPC向けだと確認される)
  • ダウンロードされるファイルの場所が大体決まっている
    • ファイル名はそのまま
  • ダウンロードの大体終わるタイミングを推測してダウンロード墨のファイルに自動遷移させることが可能
    • javascriptでdocument.locationを変更するだけ
    • ダウンロード済のファイルでもJavascriptが有効
    • ユーザへの確認はなし
    • file://sdcard/Download/hogehoge.htmlからjavascirptを実行すれば端末内のfileスキームでアクセスできるファイルはすべて読める→webview.dbをアップロードできちゃう...
    • 読み取ったファイルはPOSTなりGETなりでサーバにアップロード可能
  • アンドロイドのこういった仕様の積み重ねでワンクリックでユーザに許諾なしにwebviewキャッシュアップロードできちゃう
対策
  • fileスキームが必要?いらないならつかえないように
  • fileスキームを使う場合は必ずパスをチェックしよう
  • 相対パスを利用した抜け穴を作らないためにも利用するAPIには注意
  • 詳細はAndroidセキュアコーディングガイドラインなどをみてください(のっているかなぁ...)
    • 要望次第では別途機会を設けます。最近セキュリティの会社に入ったのでw
  • Javascriptを必要ないなら有効にしない
  • WebViewキャッシュは...
    • こまめに削除するとか...
    • 要らないサイトにアクセスしないとか...
    • 標準ブラウザを使わないとか...
デモ
  • サーバ側はgoogleAPPEngineでpython
  • ランダムな名前のファイルをpushして自動的に画面遷移させて実行
  • htmlの中でframeを定義してそのパスをwebview.dbにしてた
  • http://webview-vul1.appspot.net
addJavasciptInterfaceの話
  • http://codezine.jp/article/detail/6618 をそのままみてね
  • リフレクションがjavascriptからつかえちゃう
  • 上の記事では開発者がきをつければいいんじゃない?って書いてあるんだけど、実はシェルが使えちゃう
  • 信用の置けるサイトを開く以外で利用したら何が起こるかわからない
  • httpでドメインしばりしてもXSSでとばされちゃうから駄目
  • Contextを持たせると脆弱性につながるとサイトでは説明
    • が、現状Contextがリフレクションでとれちゃう
    • リフレクションが使えるということはクラスのstaticなメンバーは誰からも参照できる
JniUtil.java
package android.webkit;

import android.app.ActivityManager;
import android.content.Context;
import android.net.Uri;
import android.provider.Settings;
import android.util.Log;

import java.io.InputStream;

class JniUtil {

    static {
        System.loadLibrary("webcore");
        System.loadLibrary("chromium_net");
    }
    private static final String LOGTAG = "webkit";
    private JniUtil() {} // Utility class, do not instantiate.

    // Used by the Chromium HTTP stack.
    private static String sDatabaseDirectory;
    private static String sCacheDirectory;
    private static Boolean sUseChromiumHttpStack;
    private static Context sContext;
  • WebViewの初期化時必ずセットできる素敵な仕様になっている
  • WebViewのコンストラクタ内で見れる
    • →WebViewを使ってるアプリは絶対使える!
    • 任意のURLを開けるアプリはContextをとれる!
      • つまり、setJavascriptInterface使うオブジェクトで外部サイトにアクセスできればすべてContextが取得できる
      • Java.lang.Runtimeもとれる!
      • execつかえる!
      • loadもつかえる!
      • 任意のJNIライブラリをWebViewに実装したアプリのユーザ権限で実行できる。
      • アプリそのものに規制・改造することも可能
      • Contextを使わなくても "ls -l" "am Intent" 等を仕込むのは可能(execshell)

onCreate()とWebView使ってればアウト
  • アンチウィルスソフトとかで探せない
対策
  • addJavascriptinterfaceつかわない!
  • 安心できるサイトしかアクセスしないから大丈夫?
    • →偽装IPや偽装DNS
  • https使えば?
    • →ちゃんと証明所の確認はしないと駄目だけどね...
本来はどうするべき
  • Googleさんに早くなおしてもらえるように、理想的な動きはどうあるべきか話し合って提案していきましょう
  • そもそもWebVIewからリフレクションで何でもできちゃうのがおかしい。なんとかしてほしい
    • みんなで圧力かけたいな...
  • iosでもにたような問題があるが、微妙にGUIDがランダムなのでとりにくい
    • javaみたく任意のメソッドよべない
    • execできない
      • このあたりで担保してるらしい...
最後に宣伝
  • イエラセキュリティでアプリ診断してます
  • WebViewを使ったアプリ優先でキャンペーン価格で診断している
質疑応答
  • そもそもWebView使う、使わないの判断基準がまずあるのでは? fileスキーマーやjavascript以前にWebViewの正しい使い方は?
    • →OAuthとかで連携させればデータ抜かれてもパスワード・IDは抜かれないのでいいかも
      • Androidはどうしようもないけど言えばどうにかなるかもしれない!
  • jpcertの熊谷さんが質問
    • JNIutilについては知らなかったがどっかで話してもよい?
      • →いいよ
  • SharedPreferenceは?
    • →同じく危険
      • JNIライブラリ使えばメモリ書き換えてパッチとか当てられるかも
      • ワンクリックでコインを増やせたりできる
      • Contextをstaticで見れるやつを探したらJNIutilみつけたが他にもありそう
      • そもそもクラスローダよべるのが問題
  • 他のアプリのキャッシュは?
    • →読めない
    • ブラウザの場合が一番ひどい
    • そのアプリケーションで動いたものが動く
    • グリーさんのはIDパスワードが入ってた
    • パーミッション変えるアタックしたらできるかもね...
  • PhoneGapとか使っても良いのか?
    • オフレコの話が少々
    • メーカーさんのアプリだとwebviewつかっているのがあってシステムで動いてる...
    • 基本的にクラスローダーを呼び出されるのが問題
    • 古いAPIは捨ててセキュアにしていくのがいいかも
  • Greeさんどうやって直したのか?
    • ustで配信してしまってるが本来は公表しちゃいけないっぽいので省略
  • サーバに置いてあるコンテンツは実行できないという認識ですがあってます?
    • →あってます。XSSというやつです。なのでデモは一度DLさせてfile:/// で実行してます