
kfd، اختصار لوصف ملف kernel، هو مشروع لقراءة وكتابة ذاكرة kernel على أجهزة Apple.
إخلاء مسؤولية سريع: لا أنوي إضافة إزاحات (offsets) لأجهزة أخرى أو إصدارات iOS أخرى.
kfd، اختصارًا لـ kernel file descriptor (واصف ملفات النواة)، هو مشروع لقراءة وكتابة ذاكرة النواة على أجهزة Apple. يعتمد على ثغرات متنوعة يمكن استغلالها للحصول على PTEs معلّقة (dangling PTEs)، والتي سيُشار إليها باسم بدائية PUAF، اختصارًا لـ "physical use-after-free". بعد ذلك، يعيد تخصيص كائنات نواة معينة داخل تلك الصفحات الفيزيائية ويتلاعب بها مباشرةً من مساحة المستخدم عبر الـ PTEs المعلّقة لتحقيق بدائية KRKW، اختصارًا لـ "kernel read/write". كود الاستغلال موجود بالكامل في مكتبة، libkfd، لكن المشروع يحتوي أيضًا على أغلفة تنفيذية بسيطة لكل من iOS وmacOS. الواجهة العامة لـ libkfd صغيرة وبديهية إلى حد كبير:
enum puaf_method {
puaf_physpuppet,
puaf_smith,
puaf_landa,
};
enum kread_method {
kread_kqueue_workloop_ctl,
kread_sem_open,
};
enum kwrite_method {
kwrite_dup,
kwrite_sem_open,
};
u64 kopen(u64 puaf_pages, u64 puaf_method, u64 kread_method, u64 kwrite_method);
void kread(u64 kfd, u64 kaddr, void* uaddr, u64 size);
void kwrite(u64 kfd, void* uaddr, u64 kaddr, u64 size);
void kclose(u64 kfd);
kopen() تفتح مفهوميًا "واصف ملفات النواة" (kernel file descriptor). وتقبل الوسائط الأربعة التالية:
puaf_pages: العدد المستهدف من الصفحات الفيزيائية ذات الـ PTEs المعلّقة.puaf_method: الطريقة المستخدمة للحصول على بدائية PUAF، مع الخيارات التالية:
puaf_physpuppet:
puaf_smith:
puaf_landa:
kread_method: الطريقة المستخدمة للحصول على بدائية kread() الأولية.kwrite_method: الطريقة المستخدمة للحصول على بدائية kwrite() الأولية.إذا نجح الاستغلال، تُرجع kopen() واصف ملفات غير شفاف (opaque) بحجم 64 بت. عمليًا، هو مجرد مؤشر من مساحة المستخدم إلى بنية تحتاجها libkfd. ومع ذلك، وبما أنه لا ينبغي الوصول إلى تلك البنية خارج المكتبة، يتم إرجاعها كعدد صحيح غير شفاف. إذا لم ينجح الاستغلال، ستطبع المكتبة رسالة خطأ، وتنتظر لمدة 30 ثانية، ثم تخرج برمز حالة 1. تنتظر لمدة 30 ثانية لأن النواة قد تتعرض لانهيار (panic) عند الخروج مع بعض طرق PUAF التي تتطلب بعض التنظيف بعد KRKW (مثل puaf_smith).
kread() وkwrite() هما المعادلان في مساحة المستخدم لـ copyout() وcopyin()، على الترتيب. يُرجى ملاحظة أن خيارات kread_method وkwrite_method موصوفة في مقال تحليلي منفصل. بالإضافة إلى ذلك، يمكن استخدام البدائيات الأولية التي تمنحها تلك الطرق لبناء بدائية KRKW أفضل. أخيرًا، تقوم kclose() ببساطة بإغلاق واصف ملفات النواة. جميعها تأخذ العدد الصحيح غير الشفاف الذي تُرجعه kopen() كوسيطتها الأولى.
في Xcode، افتح المجلد الجذر للمشروع ووصّل جهاز iOS الخاص بك.
في الطرفية (Terminal)، انتقل إلى المجلد الجذر للمشروع.
اختياريًا، لزيادة حدود واصفات الملفات على المستوى العام وعلى مستوى العملية الواحدة، مما سيحسّن معدل النجاح خاصةً عند التشغيل عدة مرات متتالية، أدخل الأمر make s واكتب كلمة مرور sudo.
make b.make r.make br.قدّم هذا README نظرة عامة عالية المستوى لمشروع kfd. بمجرد تحقيق بدائية PUAF، يصبح باقي الاستغلال عامًا. لذلك، جمعت الجزء المشترك من الاستغلالات في مقال تحليلي مخصص:
بالإضافة إلى ذلك، قسّمت الجزء الخاص بكل ثغرة من أجزاء الاستغلالات المستخدمة لتحقيق بدائية PUAF إلى مقالات تحليلية منفصلة، مذكورة أدناه بترتيب زمني للاكتشاف:
ومع ذلك، يُرجى ملاحظة أن هذه المقالات كُتبت لجمهور على دراية مسبقة بنظام الذاكرة الافتراضية XNU.