threat-research

FunkyBot: 日本を狙う新しいAndroidマルウェアファミリー

FortiGuard Labsは昨年、日本人ユーザーを標的とするマルウェア攻撃を発見しました。この攻撃は、ある物流企業になりすまし、FakeSpyと呼ばれるAndroidマルウェアを展開していました。

FortiGuard Labsは、この攻撃者や彼らが作成したフィッシングサイトを監視してきましたが、先日この攻撃者が新しいAndroidペイロードを展開し始めていることを確認しました。

それまでの攻撃と同様、このペイロードもパッカーとペイロードで構成されています。ところが、これらはどちらも以前の攻撃で使用されたものとは異なっていることが明らかになりました。

本ブログでは、今回FortiGuard Labsが発見し、新しいマルウェアファミリーによるものだと考える攻撃で使われているパッキングメカニズムとそのペイロードについて詳しく分析します。この新しいマルウェアファミリーは、これまでに使用されてきた有名なFakeSpyマルウェアファミリーに代わるものとして、同じ攻撃者が開発した可能性があります。図7に示す、ペイロードの永続化メカニズムから見つかったログ記録の文字列にちなみ、我々は今回新たに発見されたマルウェアファミリーを「FunkyBot」と呼ぶことにしました。

ここからは、次のサンプルを分析していきます。

152be211ecd21c8abfd7c687a5ca8a17906f589c59055516e5482ff3fcf42dbf


パッカー

パッカーは2つのパートで構成されています。

  • classes.dexファイル内のJavaコード
  • libcsn.soファイル内のネイティブコード

Java関数

分析したサンプルに含まれるパッカーのコードは難読化されていましたが、調査の結果幸運にも難読化されていないバージョンを発見することができたため、それを使用することにしました。
使用したのは、次のサンプルのパッカーです。

b4f3b7850c4332bcf85bbd64ebd6d837a3de64a03c1150cdd27e41599d2852b6

まず注目すべきは、_attachBaseContext(Context base)という関数です。この関数は、APK形式のアセットフォルダーに格納されている構成ファイルにアクセスします。今回の例では、「_dcfg_.data」というJSONファイルがこれに該当します。このファイルが、以下のパラメーターを読み込みます。

  • size」:パッカーが生成しなければならない「.dex」ペイロード数を特定する
  • payloadType」:暗号化されたペイロードデータの場所を特定する
  • isTestIn」:テスト用フラグ
  • type」:使用された暗号の種類を特定する

分析したサンプルから、次の2つの構成が見つかりました。

{"size":2,"payloadType":0,"isTestIn":"0","type":3}
{"size":2,"payloadType":1,"isTestIn":"0","type":3}

このパッカーは、適切なペイロードを生成するために、実行中のAndroidバージョンを確認します。さらに、マルウェアの分析者を混乱させるためか、偽のdexファイルをいくつか作成します。

図1:偽のdexファイルの生成

図1:偽のdexファイルの生成

次に、「payloadType」の値を確認します。この値が1であれば、別のフォルダにアセットデータをコピーします。1でない場合は、メモリに読み込まれたclasses.dexファイルを使用するため、何も移動させることなく次のプロセスに進みます。

図2:dex暗号化ファイルの抽出

図2:dex暗号化ファイルの抽出

 


JNI関数

JNIToolsクラスは、libcsn.so内の一連のネイティブ関数を宣言します。

図3:JNIToolsのネイティブ関数宣言

図3:JNIToolsのネイティブ関数宣言

ライブラリが読み込まれると、JNI_OnLoadというネイティブ関数を実行し、JNIToolsで宣言されたネイティブ関数を登録することで、通常のJava_<className>_<FunctionName>とは異なる方法で呼び出せるようにします。これは、リバースエンジニアリングを妨害する目的だと考えられます。

構成変数「type」の値が0でない場合(つまり、ペイロードを復号する必要がある場合)、このコードは/data/data/<appname>/app_csn0/にアクセスし、ここに「.unzip」というフォルダを作成します。フォルダ名の先頭に「.(ドット)」を加えることで不可視化し、通常のIsコマンドで表示されることを回避しています。

復号ルーチンは、暗号化されたペイロードデータから生成されたファイルで実行されます。このデータは、「payloadType」の値に基づき、以下のいずれかのソースから取得されます。

  • 0:実行済みコードがすべて含まれる「classes.dex」ファイル
  • 1:アセットファイル(今回の例では「assets/csn-enc.data」)

最初のケースでは、パッカーは/proc/<pid>/mapsファイルにアクセスし、classes.dexファイルが読み込まれたメモリを特定して、そのメモリから暗号化データの冒頭部分と一致する具体的な文字群を探します。今回の例では、「csn_」がこれに該当します。一致する文字群が見つかると、その箇所以降のコピーを開始します。

図4:「csn_」の検索

図4:「csn_」の検索

構成変数「type」の値によって、暗号化ルーチンは異なります。このコードは、以下の値に対応しています。

  • 0:暗号化しない
  • 2または3:「`0x51` (81)」という値を使ったXORベースの復号

図5:復号スイッチ

図5:復号スイッチ

本ブログで取り上げているサンプルの場合、「type」の値はすべて3でした。これは、以下の復号関数に該当します。

図6:復号「type」=3

図6:復号「type」=3

その後、これらのルーチンが、ClassLoaderに読み込まれる「classes.dex」ペイロードファイルを生成します。


「FunkyBot」のペイロード

分析したサンプルのペイロードは、マルウェアがなりすましている元々の正規のアプリケーションのコピーと、悪意のあるコードの2つの.dexファイルで構成されていました。

このペイロードは、Javaのリフレクションを使って、メソッド「runCode」のクラス「com.wfk.injectplugin.EntryPoint」が呼び出されると開始します。このメソッドは、「KeepAliceMain.start()」を開始します。

図7:エントリポイント

図7:エントリポイント


KeepAliceMain

これは、マルウェアが永続化メカニズムとして使用しているクラスです。Githubから取得可能なオープンソースのライブラリを使い、デバイス上でサービスを有効な状態に保ちます。また、このインスタンスでは使われていませんが、マルウェアがデバイスの音声をミュートすることを許可しています。

このクラスは、マルウェアがリモートサーバーとのgRPC接続を確立するために使うメインサービスを定期的に実行します。


GRPCクライアント

コマンドと通信アドレス

サーバーアドレスは、classes.dexファイルにハードコーディングされておらず、実行中に読み取られます。このコードは、GprcsUtils.Regist_Server(String str)関数を実行し、UrlTool.loadIPAddrFromIns()を呼び出してC2のURLを抽出します。

図8:Instagramから読み込まれたIP

図8:Instagramから読み込まれたIP

このマルウェアは、AnubisによるTelegramやTwitterアカウントのなりすましと同様の手法で、ソーシャルメディアを使ってC2を取得します。まず、写真のないInstagramアカウントのウェブページをダウンロードし、このアカウントの自己紹介欄を抽出してBase64でデコードします。

図9:偽のInstagramアカウント

図9:偽のInstagramアカウント

最後に、DESを使って生成された文字列を復号します。シードとしてd2a57dc1d883fd21fb9951699df71cc7の値を使い(「app」という文字列に該当するMD5のハッシュ値でした)、鍵を生成します。図8のString変数str3以下をご覧ください。

その結果、149.28.24.166:11257というURLが生成され、偽アカウントがInstagramに報告されました。


SMSサービス

サーバー接続が始まると、マルウェアは以下のデバイス情報を収集してサーバーに送信するプロセスに入ります。

  • IMEI
  • IMSI
  • 電話番号
  • 電話帳

特に、Anubis、Cerberus、Hydraなどの大型のマルウェアファミリーと比べると、抽出される情報量は比較的限られています。ただし、これまでの攻撃と同様、精力的に拡散させる手法を備えています。

デバイスの連絡先情報をすべてC2に送信後、電話やメッセージ本文に関するC2の応答を待ち、SMSを生成します。この戦術は、FakeSpyやMoqHaoなどの複数の攻撃が、ワームのようにマルウェアを拡散させるために使用していた方法です。このサンプルでも使われていると考えるのが妥当でしょう。

興味深いことに、このマルウェアはある特定の日系通信プロバイダーを探して、SIMカードのプロバイダーを確認していることがわかりました。これは、デバイスのIMSI(移動加入者識別番号)をチェックすることで実行されています。IMSIは、プロバイダーIDとデバイスIDの2つのパートで構成されています。

このマルウェアは、プロバイダーIDがリスト内のいずれかの値と一致しているかどうか確認します。リスト内の値は、どれも前述のプロバイダーに該当するものでした。

図10:特定のプロバイダーのサービスを利用していえるデバイスであるかを確認している様子

図10:特定のプロバイダーのサービスを利用していえるデバイスであるかを確認している様子

当初この関数には、このプロバイダーのサービス利用者に何らかの標的型行動を仕掛ける目的があるのではないかと疑いました。ところが、is<Provider>()関数からtrueが戻された場合、マルウェアは単純に、送信可能なSMSメッセージ数を増やすプロセスに進みます。

さらに調査したところ、このプロバイダーは利用者間でSMSメッセージの無料送信を認めているため、この振る舞いは、攻撃が疑われる前に感染デバイス1台で生成可能なトラフィック量を増やすための行動に過ぎない可能性があるという結論に達しました。

最後に、このマルウェアは自らをデフォルトのSMSハンドラーアプリケーションに設定し、これを利用して受信したすべてのメッセージをC2にアップロード可能であることがわかりました。現在、大多数の銀行がSMSを使って二要素認証を行っていることを考えると、これは非常に危険なことだといえます。


まとめ

FortiGuard Labsは、主に日本のサービスプロバイダーを標的とする攻撃をモニタリングすることで、私たちの知る限り新しいマルウェアファミリーである今回の攻撃とその内容を特定することができました。

分析中、開発が完了しておらず、このブログに記載される機能の一部が欠けているサンプルも発見しました。つまり、今回発見されたマルウェアファミリーは、現在テスト段階にある開発途上のマルウェアであることが推測できます。

現時点では、このマルウェアファミリーの機能は限られていますが、数週間の間にサンプルが大幅に進化していることを考えると、このマルウェアファミリーを侮るべきではありません。

FortiGuard Labsは引き続き、この攻撃の進化を監視します。

-=FortiGuard Lion Team=-


ソリューション

Fortinetのお客様は、以下のシグネチャによってこのマルウェアから保護されています。

  • パッカー:Android/Agent.DDQ!tr
  • ペイロード:Android/Funky.A!tr and Android/Funky.B!tr

謝辞

本ブログの執筆に必要な調査にご協力いただいた、Evgeny Ananin氏に感謝いたします。

IoCリスト

パッカー:

b4f3b7850c4332bcf85bbd64ebd6d837a3de64a03c1150cdd27e41599d2852b6
152be211ecd21c8abfd7c687a5ca8a17906f589c59055516e5482ff3fcf42dbf

ペイロード:

02036825d69208612fd281b3d4fd9be06fc315addeac1fe8872eb2cc9f6f1fcd
beb6cb245f6597b6d2b9e9232774329b94f2eada5980a3cb28f9100cc161f4a4

C&Cサーバ:

149[.]28[.]24[.]166[:]11257
108[.]61[.]187[.]156[:]11257