
اغص في خط CFF وتعرّف بالصدفة على ثغرة bof في تحليل cff من أحد الـ jailbreaks. فقط للمتعة
اغوص في خط CFF وبالمصادفة تعلّم عن ثغرة bof في تحليل cff من بعض أدوات jailbreak. فقط للمتعة
إذن.... ما هو CFF بحق الجحيم؟ من معرفتي إنه تنسيق ملف، لكن دعنا نحاول فهم ما تقوله ويكيبيديا: "يعمل CFF كحاوية لتخزين خطوط متعددة معًا في وحدة واحدة تُعرف باسم FontSet." (https://docs.fileformat.com/font/cff/) إذن ببساطة يمكننا تخزين الخطوط معًا. رائع، وماذا الآن؟ حسنًا، بما أنه تنسيق ملف، فلا بد أن له مواصفة، ونعم لديه واحدة، ولا، ليست لطيفة لأنها 60 صفحة ولست مستعدًا لتعلم تنسيقه. لكن يمكننا استخدام الاستغلال من مستودع star-master على GitHub (الكود المصدري من jailbreak 2.0 على ما أعتقد) لتعلم تنسيقه.
إذن... نبدأ باستخدام سكربت cff.py المقدم من المؤلف، ونفتح أيضًا ملف out.cff (ملف .cff بسيط قياسي) في محرر hxd.
يمكننا أن نرى أنه عندما نمرر الملف إلى المحلل نحصل على التالي

إذن لقد أحرزنا بعض التقدم حيث يمكننا بالفعل الوصول إلى تعريف لـ cff، إذ يمكننا أن نستنتج أن لدينا بعض البيانات الوصفية حول ترويسته التي تشير إلى إصدارات tff على ما أظن، وحجم الترويسة، وabsoffsize أياً كان ذلك.
إذن حتى الآن |الإصدار الرئيسي (1 بايت)|الإصدار الثانوي (1 بايت)|حجم الترويسة (1 بايت) | ترويسة absoffsize (1 بايت) |
ثم نذهب أبعد من ذلك ولدينا دالة تجلب الخطوط المستخدمة في ملف .cff هذا. كما نرى

إذن من أين نعرف أن الغرض منه هو قراءة الخطوط المستخدمة؟ حسنًا، عند تشغيل الأداة حصلنا على النتيجة التالية في cmd

والتي نرى أنها البايتات التالية بعد البيانات الوصفية للملف

سنعود لاحقًا إلى تحليل هذه الدالة، لكن في الوقت الحالي يمكننا استنتاج أن تنسيق الملف هو |الإصدار الرئيسي (1 بايت)|الإصدار الثانوي (1 بايت)|حجم الترويسة (1 بايت) | ترويسة absoffsize (1 بايت) | ABCDEF+الخطوط في الحزمة|
علاوة على ذلك، نرى أننا نبحث عن ما يسمى string في السكربت:

لماذا ذلك؟ لأنني أفترض أنهم يريدون جمع معلومات حول الخط المستخدم في الحزمة. من الوثائق، يقولون: "جميع السلاسل النصية، باستثناء سلاسل FontName وCIDFontName التي تظهر في Name INDEX، المستخدمة من قِبل خطوط مختلفة داخل FontSet، تُجمع معًا في بنية INDEX ويُشار إليها برقم غير موقّع من 2 بايت يسمى معرّف السلسلة أو SID. هذه السلاسل، المعروفة باسم السلاسل القياسية، تصف جميع الأسماء المستخدمة في مجموعات الأحرف ISOAdobe وExpert". على أي حال، هناك شيء مثير للاهتمام نلاحظه هنا، وهو أننا تخطينا حوالي 41 بايت للوصول إلى السلسلة النصية.


بعد ذلك نحصل على معلومات حول الخطوط الموجودة في ملف .cff

كيف بحق الجحيم نفعل ذلك؟ حسنًا، نجمع ما يسمى بيانات top dict. ما هذا بحق الجحيم؟ حسنًا، من ما استطعت فهمه من الوثائق، هو عبارة عن dict بلغة بايثون يحتوي على معلومات معينة، مشفرة بطريقة معينة.

بالمصادفة، إذا اتبعنا خوارزمية فك التشفير:

نقوم بعملية dereference على نوع بيانات strings للحصول على معلومات حول الخط، لذا نستنتج أن topdicts تحتوي ببساطة على بعض الفهارس التي تُستخدم لاحقًا في نوع بيانات strings للحصول على معلومات حول الخط.
إذن حتى الآن، يظل تعريف الملف قائمًا،
|الإصدار الرئيسي (1 بايت)|الإصدار الثانوي (1 بايت)|حجم الترويسة (1 بايت) | ترويسة absoffsize (1 بايت) | ABCDEF+الخطوط في الحزمة|41 بايت معروفة|25 بايت من المعلومات حول الخط|
رائع، إذن ماذا يحدث بعد ذلك؟ حسنًا، إذا فحصنا سكربت المحلل، نرى أنه يحصل على charstring_off وprivate_off، وسيذهب إلى موضع charstring_off ويقرأ المزيد من الأشياء

لكن كيف يساعدنا ذلك في فهم الصورة الأكبر؟ لذلك سأنهي هذا فجأة. في الأساس، أجريت مقارنة diff بين ملفين، أحدهما cff عادي والآخر cff تالف.

على اليسار ملف .cff التالف وعلى اليمين ملف .cff عادي. إذا فحصنا نتيجة التشغيل

في المرة الأولى عند تشغيل التحليل، نرى أن كل شيء مثل count وoffsize وoffbase هو ببساطة بعض الإزاحات حتى بعض المحددات. أي محددات؟ تحديدًا اسم الخط. كما ترى ('offbase', 8L) إزاحة من بداية الملف حتى أول ظهور لسلسلة الخط الموجودة في ملف cff

كما يمكن رؤيته أيضًا في "الجولة الثانية من التحليل"

نرى عند الإزاحة 0x6c في عارض hex أن \x0e\0xe\0xe\x0e هي بداية بياناتنا الخبيثة
إذن كاستنتاج، التنسيق العام لملف .cff
|الإصدار الرئيسي (1 بايت)|الإصدار الثانوي (1 بايت)|حجم الترويسة (1 بايت) | ترويسة absoffsize (1 بايت) | ABCDEF+الخطوط في الحزمة|41 بايت معروفة|25 بايت من المعلومات حول الخط|
وتنسيق الملف المخصص (مع محتوى المستخدم)
|الإصدار الرئيسي (1 بايت)|الإصدار الثانوي (1 بايت)|حجم الترويسة (1 بايت) | ترويسة absoffsize (1 بايت) | ABCDEF+الخطوط في الحزمة|41 بايت غير معروفة|25 بايت من المعلومات حول الخط| 4 بايت (count) | 4 بايت (offsize) | 9 بايت متبقية للتوثيق| محتوى المستخدم|