[セキュリティブログ] Android マルウェアはどのように製作されるのか?
Android マルウェアはどのように製作されるのか?
マルウェア製作者はリパック (repackaging) という技法を利用して、人気アプリにマルウェアを挿入/アプリ名を変更した後、再び Android Market に登録します。

[図 1] 正常/悪性アプリ
[図 1] では左側が正常アプリで右側が悪性アプリです。違いは、著作権 (Copyright) 部分とスタートボタン有無のみであるため、外観だけで判別する事は難しいです。悪性アプリを実行しても、正常アプリと同じように機能が実行されるため、注意深くみていかないと判別する事は困難です。
このようにリパック方法を利用した Android マルウェアは、2011 年初頭に発見されてから時間の経過と共に増加しており、Google Android Market、サードパーティのマーケット、ブラックマーケット、P2P など多様な経路を介して配布されています。
1) リパックとは?
大部分のプログラミング言語は、コンパイルプロセスを経て人間が認識できるソースコードから機械が読取り可能なバイナリファイルに変更されます。Android では、ここでプログラムを紐付けるパッケージングとコードサイン作業が追加されます。図で示したものが [図 2]にあります。

[図 2] Android アプリ製作プロセス
リパックする時のプロセスは、アプリの製作プロセスの逆になります。アプリを元の形態であるソースコードに変換した後、ソースコードを挿入してアプリを再度製作する一連のプロセスを意味します。

[図 3]Androidアプリのリパックプロセス
[図 3]のように APK ファイルの圧縮を解除してでてきたバイナリ形態のファイルをデコンパイルすると、ソースコードに変換されます。結果物として産出されたソースコードをハッカーや開発者が修正して再度、コンパイルとパッケージング作業を行うと、APK ファイルが生成されます。最後に開発者認証書としてコードサインをすれば、実行可能なアプリの完成となります。
開発者認証書は、圧縮ファイル形式になっている APK ファイルを圧縮解除するアンパッキング(unpacking) プロセスでは抽出できないため、新しい認証書にコードサインをする必要があります。

[図 4] リパック アプリ
[図 4]は、リパック方法を活用してボタンをタップした時に出力されるメッセージを「Nice to see you」から「I am happy」に変更した例です。JAVA 言語についてある程度の理解があり、いくつかの関連ツールを使いこなせれば誰でも簡単にアプリを修正できます。リパック方法はマルウェア製作だけではなく、Android アプリの韓国語化、クラッキング、機能追加•修正などの多用途に利用されます。
リパックする際、一番の核になるのはコンパイル作業です。これは、ハイレベルの技術力を必要とする困難な作業で、デコンパイルしても本来のソースコードに完全に戻すことはほぼできないため、大部分の言語にはデコンパイルが要求されるリパック方法は利用されません。
けれども、Android で主に使用される開発言語である Java は、JAD、apktool など公開されている多様なツールを活用して、バイナリファイルでソースコードにデコンパイルでき、結果物として産出されるソースコードも本来のものと類似した形態を有しています。このような背景も、Android でリパック方法を活用したマルウェアが流行する理由の一つと言えます。
2) ウイルス vs. リパック
リパックは正常プログラムにマルウェアを挿入する、という点でウイルスやパッチド(patched) マルウェアと類似していますが、具現方法や内部動作において大きな違いがあります。パソコンから発見される一般的なウイルスは、マシン語形態のマルウェアを正常ファイルのある一つの部分に挿入して、ウイルスコードが呼出されるようプログラムコードのスタートアドレスを修正する動作をします。つまり、マルウェア製作者は、実行ファイルの構造とマシン語に対するハイレベルな知識を保有している必要があります。
その反面、Android はパソコンと同様バイナリ形態のファイルを直接修正する事が困難です。Android アプリはパッケージ形態なので、すべてのパッケージに開発者のコードサインが必要になります。パッケージ内部のファイルの一部を修正すると、コードサインが無効になるためアプリの再インストールが出来なくなります。もちろん、既存のウイルスが Android で使えないわけではありませんが、マルウェア製作者がリパックという手軽な方法を使わずに、面倒な方法を選択するケースは少ないと思われます。
3) リパックを防ぐには?
開発者の立場でアプリがリパックされることを防ぐ方法はないのでしょうか?アプリ自らがリパックされることを完全に防御する事は、現時点では不可能です。けれども、次のような方法でリパックすることを困難にしたり、遅らせることはできます。
A. コードを難読化する
ProGuard のようなツールを活用して、コードを最大限難読化する方法です。こうすると、デコンパイルをしてもクラスや関数名などが意味ない文字に変更されるため、ハッカーがアプリを把握しにくくなります。ProGuard とは、最適化、難読化などに使用されるツールです。
B. Android NDK を利用した開発をする
前述したとおり、JAVA で開発されたプログラムは、デコンパイルし易いです。その為、セキュリティが必要な重要なコードは、NDK (Native Development Kit) を利用して C 言語で開発するようにします。
4) リパックされたアプリによるマルウェア感染被害を減らすには?
一般ユーザーはどうすれば、リパックされた悪性アプリから避けることができるでしょうか?
A. サードパーティマーケット、ブラックマーケットの利用を控える
マルウェア製作者は、登録検査がゆるいマーケットを利用する確率が高いです。アプリをダウンロードする時は、信頼できるマーケットを利用するよう心がけましょう。
B. アプリ情報を確認する
マルウェア製作者がアプリをリパックしてマーケットに登録する際、他の事はできてもアプリ名と開発者情報を正常アプリと同一にすることはできません。マーケットから有名なアプリをダウンロードする際、アプリ名および製作者情報が本物と一致しない場合、リパックを疑う必要があります。
C. アプリインストール時に権限要請を確認する
Android でアプリインストール時、そのアプリに必要な権限情報をユーザーに確認するようになっています。もしインストールしようとするアプリが過度な権限を求める場合、インストールを中断してアプリを確認する必要があります。
D. セキュリティ製品インストール
多くの Android セキュリティ製品がリリースされています。これらをインストールして、周期的にセキュリティスキャンを行うことを推奨します。