カカオトークの偽セキュリティプラグイン

本記事はVirus Bulletinに掲載されたものです。

Android/FakeKakaoはカカオトークのセキュリティプラグインになりすまして、ユーザーにインストールを促すトロイの木馬です。インストールされると、受信するSMSメッセージ、送信されるSMSメッセージの監視を行い、SMSスパムを送信し、機密情報を収集し、リモートサーバーと通信を行います。さらに、アンチデバッグ、アンチエミュレート機能を取り入れ、セキュリティソフトウェアを無効化します。

他のマルウェアと違い、このトロイの木馬のDEX(Dalvik Executable)は主にローダーとして使用され、そのペイロードがネイティブライブラリへ移されます。今回の記事では、このマルウェアの動作を解説するとともに、デバッグして解析を行う方法を紹介しましょう。

アプリケーションローダー

このローダーはMainActivity、ActionReciever、MoriService という3つのコンポーネントを登録します。MainActivityは被害者をだますために精巧なユーザーインターフェイスを起動させるものです(図1: コメントはオンライン上で翻訳したもの)。ActionRequiredはandroid.intent.action.USER_PRESENTというブロードキャストを受信するために使用されます。このブロードキャストは端末が起動するとシステムにより送信されるものです。

このブロードキャストをできるだけ早く受け取れるよう、マルウェアはレシーバーのインテントフィルタのプライオリティ値を0x7FFFFFFFに設定します。ブロードキャストを受信すると、MoriServiceがバックグラウンドで起動します。このサービスの呼び出しメソッドはlibEglsv1.soというネイティブライブラリにあります。libEglsv1.soはAPK(_Android_ package file)がインストールされる際、マルウェアによりドロップされます。アプリケーションをスムーズに実行するため、このマルウェアは以下のパーミッションをリクエストします。

  • READ_SMS
  • READ_CONTACTS
  • READ_PHONE_STATE
  • SEND_SMS
  • WRITE_EXTERNAL_STORAGE
  • INTERNET
  • RECEIVE_SMS

アンチデバッグとJNI初期化

起動されたサービスはドロップされたライブラリをマルウェアのプロセスアドレス空間にロードします。ライブラリが初期化されると、デバッグされているかどうか、エミュレータで実行されているかどうかをマルウェアがチェックします。以下のうちのいずれかが検出されると、今後のためにanti-debug/emuというフラグを設定します。

  • strace
  • ltrace
  • android_server
  • gdbserver
  • gdb
  • tcpdump
  • ro.kernel.qemu
  • /system/bin/qemu-props
  • /system/bin/qemud

初期化後、RegisterNatives()/を呼び出して6つのネイティブメソッドの登録が行われます(図2)。その後、マルウェアはSetJNIEvn()メソッドを呼び出し、他のネイティブメソッドを呼び出すために用意されているJNI(Java Native Interface)の環境変数を初期化します。ですが、もしanti-debugging/emuフラグが設定されている場合には、他のネイティブメソッドは何もしません。

C&Cサーバーとの通信

このマルウェアは感染させた端末の個人情報フォームを収集し、AES-192アルゴリズムを使用してその情報を暗号化します。このアルゴリズムはこのライブラリの暗号化、復号ルーチンのほとんどで使用されています。収集した情報を送信する前に、このマルウェアはインストールされたAPKファイルに入っている暗号化されたconfig.js ファイルからC&Cサーバーのリストを回収します。サーバーリストの入ったこの構成ファイルを復号するためには、AES-192アルゴリズムを使用するだけでなく、uncompress() APIを呼び出して解凍を行う必要もあります。図3は復号されたサーバーリストです。このファイルには2つのサーバーエントリーがあることがわかります。1つ目は内部テストに使用されるもので、2つ目のエントリーが本物のC&Cサーバーです。

回収された情報は2つに分けられます。これをID部分、MD部分と呼ぶこととします。ID部分には次の情報が含まれます。

  • id IMEI番号
  • token 製品の銘柄および型
  • target ビルドバージョン
  • rd /system/bin/suあるいは/system/xbin/suのフラグの存在
  • fo 感染させた電話の番号

MD部分には次の情報が含まれます。

  • md idと同じ
  • fo 感染させた電話の番号
  • ds 連絡先の名前と番号

このマルウェアはまずID部分をC&Cサーバーに送信し、感染させた端末を登録します。サーバーのレスポンスデータが「0」の場合、MD部分を送信します。サーバーのレスポンスデータが「1」の場合、MD部分は送信されません。図4はこうした通信の例です。

次に、C&Cサーバーにフィルタールールをリクエストします。このルールは受信するテキストメッセージとSMSデータベースのフィルタリングに適用されます。メッセージ(内容はさまざま)のスクリーニングには以下のキーワードが使用されます。

  • plist メッセージの電話番号の照合
  • klist メッセージコンテンツの照合
  • blist メッセージのニックネームの照合
  • allmsgs スパムメッセージのコンテンツ
  • snumber マルウェアが指定する特定の電話番号
  • smsg snumberに送られるメッセージ
  • allmsg 別のスパムメッセージのコンテンツ
  • checkedフラグ、スパムメッセージの送信あるいは未送信
  • unlockフラグ、連絡先の保存あるいは未保存

図5aと5bはフィルタールールの一例です。

このマルウェアはサービスの起動時間をすべて記録します。サービスが次に起動する際には、回収した情報を再送信し、新たなフィルタールールをリクエストします。間隔は30分以上となります。

SMSの監視

受信するテキストメッセージを監視するため、このマルウェアはまずregisterReceiver()を呼び出し、新たなブロードキャストレシーバーを登録します。そしてそのレシーバーのインテントフィルタのプライオリティを0X7FFFFFFFに設定し、他のレシーバーよりも優先度を高くします。その結果、最初にメッセージを処理することが可能になります。

メッセージが入ってくると、ルールを使用してそれをフィルターにかけます。例えば電話番号の照合、メッセージコンテンツの検索などを行います。そしてabortBroadcast()を呼び出し、興味のあるメッセージに関しては他の優先度の低いレシーバーへの引き渡しをストップします。

SMSデータベースの変更を監視するため、このマルウェアはregisterContentObserver()を呼び出してコンテンツのオブザーバーを登録します。データベースが変更されると、受信するメッセージの時と同様の方法で各メッセージをチェックします。マッチしたメッセージがレシーバーから来ていても、オブザーバーから来ていても、それは暗号化されてリモートサーバーへ送信されます。レシーバーあるいはオブザーバーが作動すると、このマルウェアは回収した情報を再送信し、フィルタールールのアップデートをリクエストします。

SMSの送信

スパムメッセージの送信はフィルタールール内の「checked」「allmsgs」「allmsg」というキーワードの値に基づいて行われます。「checked」がゼロでなく、「allmsgs」あるいは「allmsg」がEmptyでない場合、連絡先リストの各アドレスにスパムメッセージが送信されます。スパムメッセージ送信の間隔は40秒です。感染させた電話番号がEmptyの場合、キーワード「smsg」のコンテンツがキーワード「snumber」の示す特定の番号に送信されます。どちらの場合にも、証拠を消すためにローカルのデータベースからは送信記録が削除されます。

自己防衛

ここでは、マルウェアは/system/app/フォルダにFOTAKill.apkのドロップを試みます。FOTAKillはサードパーティーのアプリケーションであり、サービスのアップデートを行うFOTA(Firmware Over-The-Air)を止めるのに使用できます。FOTAKillを使用する目的はおそらく、rootアクセスなどの入手した特権がアップデートにより削除されることを食い止めるためでしょう。このファイルをドロップするため、マルウェアはAPI関数getuid()を呼び出してユーザーID(UID)を確認します。UIDがrootモードになっている場合には、端末にインストールされているすべてのAPKを記録している/data/system/packages.listを読み込みます。このリストに以下のセキュリティ関連の文字列が含まれていると、「pm disable」コマンドを使用して、それを閉じます。

  • com.avira.android
  • com.antivirus
  • com.kms
  • com.wsandroid.suite
  • com.qihoo360.mobilesafe
  • com.ijinchan.duba
  • com.tencent.qqpimsecure
  • com.anguanjia.safe
  • com.lbe.security
  • com.netqin.mobileguard
  • com.avast.android.mobilesecurity
  • com.estsoft.alyac
  • com.lookout
  • com.zoner.android.antivirus
  • com.symantec.mobilesecurity
  • com.drweb
  • com.drweb.pro.market
  • com.symantec.mobilesecurity
  • com.symantec.monitor

解析方法

お分かりのように、Androidプラットフォームでネイティブコードを使用することのデメリットの1つは、アプリケーションをより複雑にしてしまうことです。ですが、このマルウェアはこの特徴を利用して、リバースエンジニアリングから自身を保護しています。ネイティブライブラリのデバッグには、一般的にリモートサーバー上の対象プロセスにデバッガーをアタッチする方法が用いられます。しかし今回の場合には、私たちが止まりたいアドレスをアプリケーションが超えてしまっているため、このプロセスにアタッチするチャンスがないかもしれません。従って、目的とするアドレスに最初のブレークポイントを設定する方法を知る必要があります。最も簡単で効果的な方法は、無限ループを実行するシングル命令を使用することです。ブレークポイントを設定する必要のあるアドレスで、無条件ジャンプを使用して元の命令と差し替えることができます。ネイティブライブラリはARMアーキテクチャ(現在、AndroidはARM、ATOM、MIPSをサポートしている)に基づいているため、修正されたARM命令およびTHUMB命令は次のようになります。

修正されたネイティブライブラリをAPKに入れ直す代わりに、リモートサーバー上のライブラリを差し替えることができます。こうすることで、マルウェアによるAPKのインテグリティチェックを迂回します。通常、Androidエミュレータを使用すると、ライブラリは/data/data/app_name/lib/ folder of the /data/app-lib/app_name/フォルダに入っています。

静的解析の際には、IDAのパワフルなコメント機能のおかげで、usercallというコーリングコンベンション(呼出規約)を使用することが可能です。このARM ELFファイルの一般的な形式は以下のようになっています。

int__usercall FunctionNameR01R0, char* P2R1, int P3R2);

関数へのリファレンスが多いのであれば、関数パラメータへコメントを追加すると解析の際に役立つでしょう。

結論

ネイティブライブラリの使用、アンチデバッグ、リバースエンジニアリングを複雑にする暗号化された文字列、FOTAKillアプリケーションのドロップ、こうしたことを見ると、このマルウェアはまだ開発途中であり、近いうちにより多くの機能が追加されることになるでしょう。