This post is also available in: English (英語)

概要

本稿では、BadPack Android マルウェアの最近のサンプルについて説明し、この脅威の改ざんされたヘッダーがマルウェア分析を妨害する仕組みについて説明します。また、さまざまな無料ツールの有効性についても検討し、BadPack Android Package Kit (APK) ファイルを分析するさいにそれらが利用できるかどうかを見ていきます。

近年のサイバーセキュリティ情勢では悪意のある Android アプリケーションが激増しています。この傾向の主たる要因の 1 つが、BadPack ファイルとしてバンドルされる APK サンプルです。

BadPack は、意図的に悪質な方法でパッケージ化された APK ファイルです。ほとんどの場合、それは「APK ファイルの圧縮ファイル形式に使われるヘッダー情報を攻撃者が悪意を持って変更した」ことを意味します。

こうしたヘッダー改ざんは BadPack の主な特徴の 1 つで、これらのサンプルはたいてい、Android のリバース エンジニアリング ツールを使っての解析がしづらくなります。BianLianCerberusTeaBot など Android ベース バンキング トロージャン (バンキング型トロイの木馬) の多くが BadPack を使います。

パロアルトネットワークスのお客様は、Advanced WildFireAdvanced DNS SecurityAdvanced URL Filtering などの Cloud-Delivered Security Services (クラウド配信型セキュリティ サービス) を有効にした次世代ファイアウォール (NGFW) により、BadPack の APK サンプルからより適切に保護されます。

弊社はこれらの調査結果を Google に報告済みです。Google の現在の検出結果によると、このマルウェアを含むアプリは Google Play には見つかっていません。Android ユーザーは、このマルウェアの既知のバージョンから Google Play プロテクトにより自動的に保護されています。Google Play プロテクトは、Google Play 開発者サービスを搭載した Android デバイスではデフォルトでオンになっています。Google Play プロテクトは、悪意のある動作を示すことがわかっているアプリについて、たとえそれが Google Play ストア以外のソースから提供されているものであっても、ユーザーに警告したり、アプリをブロックしたりすることができます。

侵害の懸念があり弊社にインシデントレスポンスに関するご相談をなさりたい場合は、こちらの問い合わせフォームからご連絡いただくか、infojapan@paloaltonetworks.com まで電子メールにてお問い合わせください (ご相談は弊社製品のお客さまには限定されません)。

関連する Unit 42 のトピック Android APK

背景

APK ファイルは Android オペレーティング システム (OS) で使われるアプリケーションで、この APK アプリケーションは ZIP アーカイブ形式のパッケージになっています。このパッケージには AndroidManifest.xml という名前のファイルが入っていますが、これが Android のマニフェスト ファイルで、このファイルにはアーカイブのコンテンツに関するデータと指示が保存されています。

この AndroidManifest.xml には、APK ベースのアプリケーション、とくに APK のマルウェア サンプルに関する貴重な情報が含まれています。BadPack APK ファイルは、攻撃者が ZIP ヘッダー データを改ざんすることで、コンテンツの分析を阻止しようとするものです。

BadPack APK ファイルから、Apktooljadx のような分析ツールを使ってコンテンツを抽出するのは難しいことが多いです。例えば Apktool は本稿後半で取り上げる BadPack APK サンプルの 1 つで AndroidManifest.xml の抽出に失敗したことが確認されています。

2023 年 6 月から 2024 年 6 月までの BadPack APK ファイルについて、Advanced WildFire の検出テレメトリーをレビューしたところ、一致するサンプルが約 9,200 件見つかりました。図 1 のグラフに月別の検出をリストしましたが、ここからはこの期間の BadPack の傾向がわかります。

画像 1 は、2023 年 6 月から 2024 年 6 月までの間に Advanced WildFire で観測された BadPack の数の棒グラフです。2024 年 5 月に飛び抜けて数が増えています。
図 1. Advanced WildFire による BadPack の検出数 (2023 年 6 月〜 2024 年 6 月)

Advanced WildFire が発見したサンプルの数からは、BadPack APK マルウェアが注目すべき脅威であることがわかります。この脅威に対抗するには BadPack をより深く理解する必要があります。

BadPack は通常の抽出技術を阻止します。そして APKアーカイブの最重要コンポーネントは Androidマニフェストなので、まずは APK アーカイブ内の AndroidManifest.xml の役割を理解するところから始める必要があります。

Android マニフェスト

Android マニフェスト ファイル AndroidManifest.xml は APK サンプル内に埋め込まれている重要な構成ファイルです。このマニフェストは、モバイル アプリケーションに関する重要な情報を Android デバイス オペレーティング システムに提供しています。

この情報には、ユーザーが開始するアクティビティとアプリケーションが実行するサービスを処理するパッケージ コンポーネントが含まれています。このマニフェストには、アプリケーションを正しく動作させるためにユーザーが許可すべき権限と、どのバージョンの Android でそのアプリケーションを稼働させるのかが含まれています。

Android マニフェストの抽出、読み取り、処理は、APK サンプルの静的分析の最初のステップです。このためマルウェアの作者らは、セキュリティ アナリストによるこれらの活動の防止を狙います。彼らは APK ファイルの ZIP アーカイブ形式で使われるヘッダーを改ざんすることでこれを実現しています。

ZIP ファイルの構造

ZIP 形式を使用すると、ユーザーはコンテンツを圧縮して単一のアーカイブ ファイルにまとめることができます。ZIP ファイルのレイアウトには主要ヘッダー タイプが 2 種類含まれていて、これらがアーカイブの構造と内容を指定しています。

  • ローカル ファイル ヘッダー
  • セントラル ディレクトリー ファイル ヘッダー

マルウェアの作者らがこれらヘッダー内のフィールドを変更することで、アナリストは APK ファイルのコンテンツを抽出できなくなります。その結果、その APK ファイルを Android デバイス上で実行することも可能になります。

ローカル ファイル ヘッダー

ローカル ファイル ヘッダーは、ZIP アーカイブに含まれる個々のファイルを表します。ZIP アーカイブには少なくとも 1 つのファイルが含まれ、ZIP アーカイブの最初のバイトは常にローカル ファイル ヘッダーで始まります。

この ZIP アーカイブに別のファイルが含まれる場合、このローカル ファイル ヘッダー構造が ZIP アーカイブの後ろの方に繰り返し現れることになります。これらのローカル ファイル ヘッダーは常に 4 バイトのシグネチャで始まります。このうち最初の 2 バイトは ASCII 文字で PK です。これは、ZIP アーカイブ形式の作成者、Phillip Katz の頭文字となっています。図 2 は、ローカル ファイル ヘッダーのレイアウトを示しています。

画像 2 は、ローカル ヘッダー ファイルのレイアウトです。
図 2. ローカル ファイル ヘッダー構造のレイアウト (出典: Florian Buchholz, The structure of a PKZip file)

図 3 は、ZIP アーカイブの先頭のバイトを示しています。

画像 3 は、ZIP アーカイブの 16 進ダンプです。
図 3. ZIP アーカイブを 16 進ダンプで表示したところ (出典: Florian Buchholz, The structure of a PKZip file)

これらのバイトの値は、ローカル ファイル ヘッダーの対応するフィールドにマッピングできます (図 4)。

画像 4 は、フィールド値が追加されたローカル ファイル ヘッダー構造の例です。これらには、シグネチャ、バージョン、フラグ、圧縮、変更時間などが含まれています。
図 4. ローカル ファイル ヘッダー構造に入力されたフィールドの値 (出典: Florian Buchholz, The structure of a PKZip file をもとに著者改変)

ローカル ファイル ヘッダーの圧縮メソッド フィールドはバイト オフセット 0x080x09 に存在します。このフィールドには、0x0000 以降のさまざまな値を含めることができます。0x0000 はファイルが圧縮されていないことを意味します。上の図 4 の例では 0x0800 という値が表示されています。この値は圧縮アルゴリズム DEFLATE を表していますが、これは ZIP アーカイブで最もよく使われる値です。

上の図 4 のバイト オフセット 0x12 から 0x15 までは圧縮サイズを示していて、ここでの 0x45 は 69 バイトに相当します。バイト オフセットで 0x16 から 0x19 までは非圧縮時のサイズを表していて、ここでの 0x4a は 74 バイトに相当します。圧縮された項目のファイル名は 0x66696c6531 ですが、これは ASCII テキストで file1 に翻訳されます。

図 4 では、この ZIP アーカイブのファイル ヘッダーは 0x37 で終わり、圧縮ファイルの内容は、0x38 から始まります。

セントラル ディレクトリー ファイル ヘッダー

セントラル ディレクトリー ファイル ヘッダーは、ディレクトリーを含む ZIP アーカイブに使われます。このヘッダーは ZIP アーカイブに含まれる特定ディレクトリー内の最後のローカル ファイル ヘッダーの終わりに続いて登場します。

APK ファイルの場合、最後のローカル ファイル ヘッダーとこのセントラル ディレクトリー ヘッダーの間にオプションの APK 署名ブロックが見つかることがあります。図 5 は、セントラル ディレクトリー ファイル ヘッダーのレイアウトを示しています。

画像 5 は、セントラル ディレクトリー ファイル ヘッダーのレイアウトの例です。この情報には、シグネチャ、バージョン、フラグ、圧縮、変更時間、変更日、ファイル名、拡張フィールドなどが含まれています。
図 5. セントラル ディレクトリー ファイル ヘッダーのレイアウト (出典: Florian Buchholz, The structure of a PKZip file)

図 3 と同じファイルを使ってバイト オフセット 0x09a2 までスクロールダウンすると、最初のセントラル ディレクトリー ファイル ヘッダーが見つかります。下の図 6 はこのヘッダーの内容を示したものです。

画像 6 は、セントラル ディレクトリー ファイル ヘッダー構造の値を 16 進ダンプで表した例です。
図 6. セントラル ディレクトリー ファイル ヘッダー構造の値を 16 進ダンプで表示したところ (出典: Florian Buchholz, The structure of a PKZip file)

図 7 にマッピングしたセントラル ディレクトリー ヘッダーの例からは、図 4 に示したローカル ファイル ヘッダーと同じ圧縮関連の値が見つかります。ただし、これらのフィールドのバイト オフセットは、図 4 に示したものとは異なります。

画像 7 は、フィールド値が追加されたセントラル ディレクトリー ファイル ヘッダー構造の例です。これらには、シグネチャ、バージョン、フラグ、圧縮、変更時間などが含まれています。
図 7. セントラル ディレクトリー ファイル ヘッダー構造に入力されたフィールドの値 (出典: Florian Buchholz, The structure of a PKZip file をもとに著者改変)

図 7 のセントラル ディレクトリー ヘッダーの場合、圧縮値のバイト オフセットは 0x0a から 0x0b までで、値は 0x0800 となっています。この値は、図 4 のすぐ後で説明した圧縮アルゴリズムと同じ DEFLATE になっています。

図 7 はバイト オフセット 0x14 から 0x17 までで圧縮サイズも示しています。その値は 0x45 で、これは 69 バイトに相当します。バイト オフセットで 0x18 から 0x1b までは非圧縮時のサイズを表していて、ここでの 0x4a は 74 バイトに相当します。これらは、図 4 のローカル ファイル ヘッダーと同じ値ですが、バイト オフセットが異なります。

圧縮された項目のファイル名は 0x66696c6531 ですが、これは ASCII テキストで file1 に翻訳されます。

図 7 では、セントラル ディレクトリーヘッダーは 0x5b で終わり、圧縮されたファイルの内容は 0x5c から始まります。

APK ファイルで使う ZIP アーカイブ形式では、ローカル ファイル ヘッダーとセントラル ディレクトリー ファイル ヘッダーの値は互いに一致している必要があります。つまり、圧縮メソッドや圧縮サイズ、非圧縮サイズなど、APK ファイル内の特定の項目の情報は、ローカル ファイル ヘッダーとセントラル ディレクトリー ファイル ヘッダーとの間で同じになります。このことは、私たちが 図 4 と図 7 の例で file1 という圧縮された項目の値を比較したさいに確認しています。

BadPack 技術とは、悪意のある APK ファイルについてこれらの値を変更し、ローカル ファイル ヘッダーとセントラル ディレクトリー ファイル ヘッダーの間に不一致を生じさせる、というものです。

BadPack 技術の分析

悪意のある BadPack サンプルでは、作者らが ZIP 構造ヘッダーを改ざんし、APK による AndroidManifest.xml の抽出・デコードができない状態にします。これにより、静的解析パイプライン下流でエラーの連鎖反応が起こります。その結果、ファイルを読み取って処理を完遂することができなくなります。

マルウェアの作者らは、次のいずれかの方法でこれらの値を操作できます。

  1. 正しい圧縮メソッドである STORE は指定するが、圧縮サイズが無効
  2. DEFLATE 以外の任意の圧縮メソッドの値を指定しているが、ペイロードの実際の圧縮メソッドが STORE
  3. ローカル ファイル ヘッダーのみに任意の圧縮メソッド値を指定するが、ペイロードの実際の圧縮メソッドが DEFLATE

通常、Apktool や jadx などの Android マルウェア静的分析ツールは、Android デバイス上の Android システム ランタイムよりも厳格です。対象 APK サンプルは ZIP ファイル形式の仕様に準拠している必要があります。したがって Apktool と jadx では APK ファイル内の ZIP 構造ヘッダーのローカル ファイル ヘッダーとセントラル ディレクトリー ファイル ヘッダーの両方を解析します。

ところが Android デバイスは、これらの分析ツールほど公式ファイル形式について厳格ではありません。このため、対象 APK ファイルに公式ファイル形式仕様に対する準拠が不完全な不正値が含まれていても実行できてしまうことがあります。これは、Android システム ランタイムがセントラル ディレクトリー ファイル ヘッダーのみを検査するためです。ローカル ファイル ヘッダーの値が一致しない場合、Android ランタイムは正しい実際の値を推定します。

まさにこの動作の違いにより、Apktool や jadx などの分析ツールは、Android デバイスに問題なくインストールされ、正常に実行される BadPack APK サンプルを分析できません。

つまり、APK 分析ツールを使う前にこれらの変更を元に戻し、元の ZIP 構造ヘッダー値を復元すれば、BadPack APK サンプルを正常に分析できます。

Android コードベースの実装をトレース

実装の本質部分のどこがマルウェア分析ツールと Android システム ランタイムとの間で動作の違いを生んでいるのかをたどって見ると、これが APK ファイルからコンテンツを抽出している Android フレームワークのコード部分であることがわかります。

このコードでは、あるメソッドが入力パラメーターを受け取っています。メソッドは本体となる一連の命令を持ち、それらの命令がこれらの入力パラメーターを変換して、なんらかの出力結果を値として返します。

メソッドの本体は料理のレシピによく似ています。プログラムが実行されると、関数はメソッド呼び出しのインスタンスとなり、メソッド内で定義されている入力パラメーターに従って入力引数を受け取ります。

ランタイムでは、この関数呼び出し時に path 引数として文字列「AndroidManifest.xml」を指定することで、このコードの実行パスがトリガーされます。以下の図 8 は、このルーチンの主要手順を読みやすく簡略化 (エラー処理の省略など) した概要です。

画像 8 は、Android ランタイムの APK 抽出のメイン ルーチンのスクリーンショットです。ここには合計 3 つのステップ (コメントとしてラベルが付けられている) が含まれています。
図 8. APK 抽出のための Android ランタイムのメイン ルーチン (出典: The Android Open Source Project)

図 8 のコード ロジックは次の手順から構成されていて、主な if 条件の行を強調表示してあります。

ステップ 1: AndroidManifest.xml のエントリーのセントラル ディレクトリーのファイル ヘッダーが取得されます。一部の値は操作されていますが、ヘッダー構造自体はそのまま残っているのでこれは成功します。

ステップ 2: このヘッダーの圧縮メソッド フィールドが数値として比較され、これが 8 (DEFLATE) と等しいかどうかが確認されます。もしそうなら、このヘッダーの Compressed Size (圧縮サイズ) フィールドがペイロード データの抽出に使われます。

ステップ 3: それ以外の場合、このペイロード データは単純に格納 (STORE) されているだけとみなされ、代わりにこのヘッダーの Uncompressed Size (非圧縮サイズ) フィールドが抽出に使われます。

前のセクションで示したコードが実際に Android デバイスへの APK サンプル ファイル抽出・インストールを処理しているかどうか確認するには、次の 2 部構成の実験を行えばよいでしょう。

パート 1:

  1. AndroidManifest.xml」のペイロード データが実際に DEFLATE アルゴリズムで圧縮されている APK ファイルを選ぶ
  2. ステップ 1 で説明した APK ファイルを Android デバイスにインストールする
  3. これが次の出力メッセージを表示して成功する

パート 2:

  1. 今度は APK ファイルの「AndroidManifest.xml」 エントリーについて、以下を行う
    1. セントラル ディレクトリー ファイル ヘッダーに移動する
    2. Compression method (圧縮メソッド) フィールドを探す
    3. 2 バイトのリトル エンディアンの整数値を次のように変更する0(STORE)
  2. これは次の出力メッセージを表示して失敗する。失敗の理由は「Corrupt XML binary file (破損 XML バイナリー ファイル)」エラーと報告される

BadPack 技術のマニフェスト

マルウェアの作者らは、次の 3 つの方法のいずれかで APK ファイルを操作できます。修復のための修正はで示しています。

方法 1: 正しい圧縮メソッドである STORE は指定するが、圧縮サイズが無効

これにより APK サンプルファイルを処理する分析ツールは機能しなくなります。ですが、Android デバイスのシステム ランタイムは Compression method (圧縮メソッド) STORE の場合、セントラル ディレクトリー ファイル ヘッダーからの Uncompressed Size (非圧縮サイズ) フィールドを使います。以下に例を示します。

SHA-256 ハッシュ:
0003445778b525bcb9d86b1651af6760da7a8f54a1d001c355a5d3ad915c94cb
ローカル ファイル ヘッダーのフィールド

Compression method (圧縮メソッド) = 0 (STORE)

Compressed size (圧縮サイズ) =14417 41192

Uncompressed size (非圧縮サイズ) = 41192

Data (データ) = \x00\x00\x08\x00 ...

セントラル ディレクトリー ファイル ヘッダーのフィールド

Compression method (圧縮メソッド) = 0 (STORE)

Compressed size (圧縮サイズ) =14417 41192

Uncompressed size (非圧縮サイズ) = 41192

方法 2: DEFLATE 以外の任意の圧縮メソッドの値を指定しているが、ペイロードの実際の圧縮メソッドが STORE

これにより APK サンプルファイルを処理する分析ツールは機能しなくなります。ですが、Android デバイスのシステム ランタイムは未知の圧縮メソッドを STORE として扱い、セントラル ディレクトリー ファイル ヘッダーから Uncompressed size (非圧縮サイズ) フィールドを読み取ります。以下に例を示します。

SHA-256 ハッシュ:
015bd2e799049f5e474b80cbbdcd592ce4e2dfbfae183bada86a9b6ec103e25e
ローカル ファイル ヘッダーのフィールド

Compression method (圧縮メソッド) = 27941 0 (STORE)

Compressed size (圧縮サイズ) =6042 17264

Uncompressed size (非圧縮サイズ) = 17264

Data (データ) = \x00\x00\x08\x00 ...

セントラル ディレクトリー ファイル ヘッダーのフィールド

Compression method (圧縮メソッド) = 38402 0 (STORE)

Compressed size (圧縮サイズ) = 6042 17264

Uncompressed size (非圧縮サイズ) = 17264

方法 3: ローカル ファイル ヘッダーのみに任意の圧縮メソッド値を指定するが、ペイロードの実際の圧縮メソッドが DEFLATE

これにより APK サンプルファイルを処理する分析ツールは機能しなくなります。ですが、Android デバイスのシステム ランタイムは正常な抽出の実行をセントラル ディレクトリー ファイル ヘッダーのフィールドのみに頼って行っています。この場合、圧縮メソッドは正しく DEFLATE と設定されます。

SHA-256 ハッシュ:
131135a7c911bd45db8801ca336fc051246280c90ae5dafc33e68499d8514761
ローカル ファイル ヘッダーのフィールド

Compression method (圧縮メソッド) = -2221 8 (DEFLATE)

Compressed size (圧縮サイズ) = 2254

Uncompressed size (非圧縮サイズ) = 8380

Data (データ) = \xad\x58\x39\x73 ...

セントラル ディレクトリー ファイル ヘッダーのフィールド

Compression method (圧縮メソッド) = 8 (DEFLATE)

Compressed size (圧縮サイズ) = 2254

Uncompressed size (非圧縮サイズ) = 8380

Android のマルウェア分析ツール

このセクションでは BadPack 手法が分析回避メカニズムとしてどのように機能するかについて説明します。そのさい中心的に取り上げるのは、ファイル抽出ツールと Android 静的分析ツールにおいて、それがどのように表示されるかです。この例では、SHA-256 ハッシュが 90c41e52f5ac57b8bd056313063acadc753d44fb97c45c2dc58d4972fe9f9f21 の APK マルウェアサンプルを使います。またこのサンプルには、前セクションで説明した BackPack テクニックのうち方法 2 を使います。

7-Zip

ファイル アーカイヴ ツールの 7-Zip は、APK サンプルから AndroidManifest.xml ファイルを抽出できません。抽出失敗の理由は「Headers Error (ヘッダー エラー)」とされます (下図 9)。

画像 9 は多数のコード行からなるスクリーンショットです。赤い矩形で強調表示されているのは、ZIP プログラムがバンドルされた APK サンプルをアンパックできなかったさいのエラー コードです。
図 9. 7-Zip は BadPack がバンドルされた APK サンプルをアンパックできない (コマンド出力は CodeSnap で作成)

Apktool

「Androidアプリケーションのリバース エンジニアリング用に設計された強力なツール」と宣伝されている Apktool は、リソースを逆コンパイルし、可能な限り作成されたときの状態に復元する機能があります。このツールでは、ユーザーがアプリケーションを変更してから再ビルドすることもできます。

下図 10 のエラー メッセージ「Invalid CEN header (bad compression method: 19466)(不正な CEN ヘッダー (不正な圧縮メソッド: 19466)」は、この APK サンプルが Apktool が認識しない非標準または独自の圧縮メソッドを使って圧縮されている可能性があることを示しています。

画像 10 は、多数のコード行からなるスクリーンショットです。赤い矩形で強調表示されているのは、APK サンプルの展開に失敗したことを示すコードです。
図 10. Apktool は APK サンプルの展開に失敗する (コマンド出力は CodeSnap で作成)

jadx

Android アプリケーション用のリバース エンジニアリング ツールとしては jadx も人気があります。APK マルウェア サンプルを jadx にロードしようとすると、図 11 に示すように、Apktool と同じエラー メッセージが生成されます。

画像 11 は多数のコード行からなるスクリーンショットです。赤い矩形で強調表示されている行は、jadex がサンプルを処理できなかったエラーを示しています。
図 11. jadx は同じ APK サンプルを処理できない (コマンド出力は CodeSnap で作成)

このエラー メッセージは、APK サンプルの指定された圧縮メソッドに問題があることを明確に示しています。これは、作者が意図的に圧縮メソッド フィールドの値を変更したために発生しています。

JAR

厳密に言えば、APK サンプルは Java ARchiver (JAR) ファイル形式の仕様の一種です。というのも、APK には標準の ZIP ファイル形式の要件に加えて追加で META-INF/MANIFEST.MF ファイルも含まれているからです。ただし Java 開発キット (JDK) の JAR ツールではこの AndroidManifest.xmlファイルを抽出できません。図 12 はそれを示しています。

画像 12 は、何行ものコードのスクリーンショットです。JAR が XML ファイルを抽出できなかったエラーを示す行が赤い矩形で強調表示されています。invalid compression method (圧縮メソッドが無効です)
図 12. JAR が AndroidManifest.xmlファイルを抽出できないことを示すエラー メッセージ (コマンド出力は CodeSnap で作成)

unzip

図 13 に示したエラー メッセージ「unsupported compression method 19466 (サポートされていない圧縮メソッド 19466)」は、unzip ツールを使って APK サンプルを展開しようとしたさい、指定された AndroidManifest.xmlファイル用の圧縮メソッドをサポートまたは認識していないことを示しています。このエラーは、アーカイブ内の特定のファイルが非標準または独自の圧縮メソッドを使って圧縮されている場合に発生することがあります。アーカイブ内のほかのすべてのファイルは、エラーなしで正常に抽出または展開されます。

画像 13 は、多数のコード行からなるスクリーンショットです。赤い矩形で強調表示されているのは、Unzip ツールが XML ファイルを解凍できなかったエラーを示す行です。Unsupported compression method 19466 (サポートされていない圧縮メソッド 19466)
図 13. unzip ツールでは AndroidManifest.xmlファイルを展開できない (コマンド出力は CodeSnap で作成)

apksigner

公式の Android SDK に同梱されている apksigner というツールは、APK ファイルに署名し、署名を検証するためによく使われています。ただし、BadPack がバンドルされた APK サンプルの署名の検証には失敗します。下の図 14 は難読化がされていたために AndroidManifest.xml ファイルを読み取れなかったことを示しています。

画像 14 は何行もあるコードのスクリーンショットです。赤い矩形で強調表示されているのは、apksigner が XML ファイルを読み取ることができなかったエラーを示す行です。Data of entry AndroidManifest.xml malformed (AndroidManifest.xml エントリーのデータが不正)
図 14. apksigner は AndroidManifest.xml の読み取りに失敗する (コマンド出力は CodeSnap で作成)

apkInspector

このトピックを調査中、私たちはこの AndroidManifest.xmlファイルを抽出できるオープンソース ツールを見つけました。

2023 年 12 月 31 日に最初に公開された apkInspector というオープンソース ツールで、これは生の APK ファイルの低レベルの ZIP 構造に関し、詳細な情報を提供してくれます。元の AndroidManifest.xml ファイルはバイナリー形式で人間による判読ができませんが、このツールでは APK コンテンツを抽出して AndroidManifest.xmlファイルをデコードすることも可能です。これを私たちのサンプル APK サンプルで実行したところ、実際に AndroidManifest.xmlファイルの抽出・デコードの両方が可能であることが確認されました。

下の図 15 は apkInspector が AndroidManifest.xml の抽出に成功したことを示しています。抽出に成功する理由は、このツールが改ざんされた DEFLATESTORE 圧縮メソッドを扱う能力を備えているためで、抽出用の Python コード を見るとそれがわかります。

画像 15 は、何行ものコードのスクリーンショットです。赤い矩形で強調表示されている行は、バイナリーの XML ファイルが正常に抽出された場所を示しています。「Extraction successful (抽出成功)」
図 15. apkInspector がバイナリーの AndroidManifest.xml を 17,244 バイト抽出 (コマンド出力は CodeSnap で作成)

結論

Android デバイス数の増加は、同プラットフォームへのマルウェア攻撃への対抗上、大きな課題を抱える標的の増加をもたらすことになります。BadPack を使う APK ファイルの存在は APK マルウェア サンプルの高度化を反映しています。これはセキュリティ アナリストにとって大きな課題となるだけでなく、これらの脅威を特定・緩和するための革新的技術やツールを継続的に開発する必要性を強調するものとなっています。

宣伝している機能と一致しない異常な権限を要求する Android アプリケーションには疑いを抱くべきです。例えば、Android の懐中電灯アプリがデバイスの電話帳にアクセスする権限を要求してくるようなケースです。サードパーティ ストアが提供するアプリをデバイスにインストールすることもも避けるようお勧めします。

パロアルトネットワークスのお客様は、Advanced WildFireAdvanced DNS SecurityAdvanced URL Filtering などの Cloud-Delivered Security Services (クラウド配信型セキュリティ サービス) を有効にした次世代ファイアウォール (NGFW) により、BadPack の APK サンプルからより適切に保護されます。

侵害の懸念があり弊社にインシデントレスポンスに関するご相談をなさりたい場合は、こちらの問い合わせフォームからご連絡いただくか、infojapan@paloaltonetworks.com まで電子メールにてご連絡いただくか、下記の電話番号までお問い合わせください(ご相談は弊社製品のお客様には限定されません)。

  • 北米フリーダイヤル: 866.486.4842 (866.4.UNIT42)
  • EMEA: +31.20.299.3130
  • APAC: +65.6983.8730
  • 日本: (+81) 50-1790-0200

弊社はこれらの調査結果を Google に報告済みです。Google の現在の検出結果によると、このマルウェアを含むアプリは Google Play には見つかっていません。Android ユーザーは、このマルウェアの既知のバージョンから Google Play プロテクトにより自動的に保護されています。Google Play プロテクトは、Google Play 開発者サービスを搭載した Android デバイスではデフォルトでオンになっています。Google Play プロテクトは、悪意のある動作を示すことがわかっているアプリについて、たとえそれが Google Play ストア以外のソースから提供されているものであっても、ユーザーに警告したり、アプリをブロックしたりすることができます。

パロアルトネットワークスは、これらの調査結果を Cyber Threat Alliance (CTA: サイバー脅威アライアンス) のメンバーと共有しました。CTA のメンバーはこのインテリジェンスを使って、お客さまに保護を迅速に提供し、悪意のあるサイバー攻撃者を体系的に阻害できます。詳細は Cyber Threat Alliance にてご確認ください。

IoC (侵害指標)

BadPack マルウェア サンプルの SHA256 ハッシュ:

  • 0003445778b525bcb9d86b1651af6760da7a8f54a1d001c355a5d3ad915c94cb
  • 015bd2e799049f5e474b80cbbdcd592ce4e2dfbfae183bada86a9b6ec103e25e
  • 131135a7c911bd45db8801ca336fc051246280c90ae5dafc33e68499d8514761
  • 90c41e52f5ac57b8bd056313063acadc753d44fb97c45c2dc58d4972fe9f9f21

追加リソース

2024-07-17 18:30 JST 英語版更新日 2024-07-16 06:40 PDT の内容を反映して図 4 の内容を修正 

Enlarged Image