
إطار تحليل ثابت يحدد أهداف الدوال القابلة للفحص بالتشويش في الكود المصدري والملفات التنفيذية، وينتج قوالب أدوات ربط، ويتكامل مع AFL++ وlibFuzzer لاكتشاف الثغرات آليًا.
إطار عمل لأتمتة اكتشاف الأهداف القابلة للتفحص باستخدام التحليل الثابت

غالبًا ما يستخدم باحثو الثغرات الأمنية الذين يجرون تقييمات أمنية للبرمجيات قدرات التفحص الموجّه بالتغطية عبر أدوات قوية مثل AFL++ و libFuzzer. هذا مهم لأنه يؤتمت عملية صيد الأخطاء ويكشف عن الظروف القابلة للاستغلال في الأهداف بسرعة. ومع ذلك، عند مواجهة قواعد بيانات كبيرة ومعقدة أو ملفات ثنائية مغلقة المصدر، يضطر الباحثون إلى تكريس الوقت يدويًا لمراجعة وهندسة عكسية لتحديد الوظائف التي يمكن أن يكون فيها الاستكشاف القائم على التفحص مفيدًا.
Fuzzable هو إطار عمل يدمج مع شفرة المصدر C/C++ والملفات الثنائية لمساعدة باحثي الثغرات الأمنية في تحديد وظائف الهدف القابلة للتفحص. يتم ذلك من خلال تطبيق عدة استدلالات قائمة على التحليل الثابت لتحديد السلوكيات الخطرة في البرنامج والوظائف التي تنفذها. يمكن للباحثين بعد ذلك استخدام الإطار لإنشاء قوالب أساسية للتفحص، والتي يمكن استخدامها لاصطياد الثغرات، أو دمجها كجزء من خط أنابيب تفحص مستمر، مثل مشروع Google oss-fuzz.
بالإضافة إلى التشغيل كأداة مستقلة، تم دمج Fuzzable أيضًا كملحق لمفكك Binary Ninja، مع دعم لواجهات خلفية تفكيك أخرى قيد التطوير.
اطلع على مقال المدونة الأصلي الذي يشرح الأداة هنا، والذي يسلط الضوء على المواصفات الفنية لاستدلالات التحليل الثابت وكيف نشأت هذه الأداة. تم عرض هذه الأداة أيضًا في Black Hat Arsenal USA 2022.
قد تتطلب بعض الأهداف الثنائية بعض التنظيف (أي مطابقة التوقيعات، أو تحديد الوظائف من التضمين)، وبالتالي يستخدم fuzzable بشكل أساسي Binary Ninja كواجهة خلفية للتفكيك لقدرتها على حل هذه المشكلات بفعالية. لذلك، يمكن استخدامه كأداة مستقلة وملحق.
نظرًا لأن Binary Ninja ليس في متناول الجميع وقد يكون هناك طلب لاستخدامه في التقييمات الأمنية وربما التوسع في السحابة، يتم أيضًا دعم واجهة خلفية بديلة angr. أتوقع دمج مفككات أخرى في المستقبل أيضًا (الأولوية: Ghidra).
إذا كان لديك Binary Ninja التجاري، فتأكد من تثبيت API للاستخدام المستقل بدون واجهة رسومية:
$ python3 /Applications/Binary\ Ninja.app/Contents/Resources/scripts/install_api.py
التثبيت باستخدام pip:
$ pip install fuzzable
نستخدم poetry لإدارة التبعيات والبناء. للقيام ببناء يدوي، استنسخ المستودع مع الوحدات الخارجية:
$ git clone --recursive https://github.com/ex0dus-0x/fuzzable
للتثبيت يدويًا:
$ cd fuzzable/
# بدون poetry
$ pip install .
# مع poetry
$ poetry install
# مع poetry لبيئة افتراضية تطويرية
$ poetry shell
يمكنك الآن تحليل الملفات الثنائية و/أو شفرة المصدر باستخدام الأداة!
# تحليل مكتبة كائن مشترك ثنائية واحدة
$ fuzzable analyze examples/binaries/libbasic.so
# تحليل ملف مصدر C واحد
$ fuzzable analyze examples/source/libbasic.c
# تحليل مساحة عمل تحتوي على عدة ملفات C/C++ ورؤوس
$ fuzzable analyze examples/source/source_bundle/
يمكن تثبيت fuzzable بسهولة من خلال سوق ملحقات Binary Ninja بالانتقال إلى Binary Ninja > Manage Plugins والبحث عنه. إليك مثال على تشغيل ملحق fuzzable، بدقة تحديد الأهداف للتفحص والتقييم الإضافي للثغرات:

يأتي fuzzable مع خيارات متنوعة للمساعدة في ضبط تحليلك بشكل أفضل. سيتم دعم المزيد في الخطط المستقبلية وأي طلبات ميزات.
لتحديد قابلية التفحص، يستخدم fuzzable عدة استدلالات لتحديد الأهداف الأكثر قابلية للاستهداف للتحليل الديناميكي. يتم ترجيح هذه الاستدلالات بشكل مختلف باستخدام مكتبة scikit-criteria، التي تستخدم تحليل القرار متعدد المعايير لتحديد أفضل المرشحين. يمكن رؤية هذه المقاييس وأوزانها هنا:
| الاستدلال | الوصف | الوزن |
|---|---|---|
| اسم مناسب للتفحص | اسم الرمز يشير إلى سلوك يستوعب إدخال ملف/مخزن مؤقت | 0.3 |
| مصارف خطرة | وسائط تتدفق إلى استدعاءات خطرة (مثل memcpy) | 0.3 |
| حلقات طبيعية | عدد الحلقات المكتشفة باستخدام حدود الهيمنة | 0.05 |
| التعقيد الدوري | تعقيد وظيفة الهدف بناءً على الحواف + العقد | 0.05 |
| عمق التغطية | عدد المستدعين الذين تعبرهم الهدف | 0.3 |
كما ذكرنا، اطلع على مقال المدونة الفني للحصول على نظرة أعمق حول سبب وكيفية استخدام هذه المقاييس.
استُوحي العديد من المقاييس بشكل كبير من عمل فينسينزو إيوزو الأصلي في التفحص صفر المعرفة.
كل هدف تريد تحليله متنوع، ولن يتمكن fuzzable من مراعاة كل سلوك حالات الحافة في هدف البرنامج. وبالتالي، قد يكون من المهم أثناء التحليل ضبط هذه الأوزان بشكل مناسب لمعرفة ما إذا كانت النتائج المختلفة أكثر منطقية لحالة الاستخدام الخاصة بك. لضبط هذه الأوزان في CLI، ما عليك سوى تحديد وسيطة --score-weights:
$ fuzzable analyze <TARGET> --score-weights=0.2,0.2,0.2,0.2,0.2
بشكل افتراضي، سيقوم fuzzable بتصفية وظائف الهدف بناءً على المعايير التالية:
static وغير مكشوفة من خلال الرؤوس.لرؤية الاستدعاءات التي تمت تصفيتها بواسطة fuzzable، قم بتعيين العلم --list_ignored:
$ fuzzable analyze --list-ignored <TARGET>
في Binary Ninja، يمكنك تفعيل هذا الإعداد في Settings > Fuzzable > List Ignored Calls.
في حال قيام fuzzable بتصفية استدعاءات مهمة يجب تحليلها بشكل خاطئ، يُوصى باستخدام وسائط --include-* لتضمينها أثناء التشغيل:
# تضمين جميع الاستدعاءات غير ذات المستوى الأعلى التي تمت تصفيتها
$ fuzzable analyze --include-nontop <TARGET>
# تضمين رموز محددة تمت تصفيتها
$ fuzzable analyze --include-sym <SYM> <TARGET>
في Binary Ninja، يتم دعم ذلك من خلال Settings > Fuzzable > Include non-top level calls و Symbols to Exclude.
الآن بعد أن وجدت مرشحيك المثاليين للتفحص، سيساعدك fuzzable أيضًا في توليد أطر تفحص جاهزة (تقريبًا) للتهيئة والترجمة للاستخدام مع مُفحص قائم على الملفات (مثل AFL++، Honggfuzz) أو مُفحص في الذاكرة (libFuzzer). للقيام بذلك في CLI:
# generate harness from a candidate
$ fuzzable create-harness target --symbol-name=some_unsafe_call
# make minimal and necessary modifications to the harness
$ vim target_some_unsafe_call_harness.cpp
# example compilation for AFL-QEMU, which is specified in the comments of the generated harness
$ clang target_some_unsafe_call_harness.cpp -no-pie -o target_some_unsafe_call_harness -ldl
# create your base seeds, ideally should be more well-formed for input
$ mkdir in/
$ echo "seed" >> in/seed
# start black box fuzzing
$ afl-fuzz -Q -m none -i in/ -o out/ -- ./target_some_unsafe_call_harness
إذا كان هذا الهدف قاعدة شفرة مصدر، فسيتم استخدام القالب العام للمصدر.
إذا كان الهدف ثنائيًا، فسيتم استخدام القالب العام للصندوق الأسود، والذي يمكن استخدامه بشكل مثالي مع وضع محاكاة التفحص مثل AFL-QEMU. سيتم أيضًا إنشاء نسخة من الثنائي ككائن مشترك إذا لم يتم تصدير الرمز مباشرة ليتم فتحه باستخدام dlopen عبر LIEF.
في الوقت الحالي، هذه الميزة بدائية جدًا، حيث ستقوم ببساطة بإنشاء إطار C++ مستقل مملوء بالمعلمات المناسبة، ولن تولد تلقائيًا الكود المطلوب لأي سلوكيات وقت التشغيل (أي إنشاء وتحرير الهياكل). ومع ذلك، فإن القوالب التي تم إنشاؤها لـ fuzzable يجب أن تبقيك على المسار الصحيح بسرعة. إليك بعض الميزات الطموحة التي أود تنفيذها في المستقبل:
يدعم fuzzable توليد التقارير بتنسيقات متنوعة. التنسيقات المدعومة حاليًا هي JSON و CSV و Markdown. يمكن أن يكون ذلك مفيدًا إذا كنت تستخدم هذا كجزء من الأتمتة حيث ترغب في استيعاب المخرجات بتنسيق قابل للتسلسل.
في CLI، ما عليك سوى تمرير وسيطة --export مع اسم ملف بالامتداد المناسب:
$ fuzzable analyze --export=report.json <TARGET>
في Binary Ninja، انتقل إلى Plugins > Fuzzable > Export Fuzzability Report > ... واختر التنسيق الذي تريد التصدير إليه والمسار الذي تريد الكتابة إليه.
سيتم تطوير هذه الأداة باستمرار، وأي مساعدة من المطورين الخارجيين موضع تقدير!
Fuzzable مرخص بموجب رخصة MIT.