
A linux system call fuzzer using TriforceAFL
جديد: لمن يرغب في تجربة TriforceAFL وTLSF، أنشأ Richard Johnson ملف Dockerfile يقوم بتثبيتهما معًا (وحتى يبني نواة Linux لك). وهو متاح هنا https://hub.docker.com/r/moflow/afl-triforce/tags/.
هذه مجموعة ملفات تُستخدم لإجراء الفازينغ على استدعاءات نظام نواة Linux x86_64 باستخدام AFL وQEMU. لاستخدامها، ستحتاج إلى TriforceAFL من https://github.com/nccgroup/TriforceAFL وصورة نواة لاختبارها. تفترض البرامج النصية أن TriforceAFL موجود في $TAFL أو ../TriforceAFL/ (ملاحظة: بناء testAfl يتطلب وجود ../TriforceAFL/config.h).
للبناء:
make
للتشغيل، قم أولاً بتثبيت نواة في ./kern/bzImage واستخراج /proc/kallsyms إلى ./kern/kallsyms. اضبط متغير البيئة K=kern ليشير إلى النواة الخاصة بك. ثم شغّل:
make inputs
./runFuzz -M M0
لاحظ أن البرنامج النصي runFuzz يتوقع اسمًا رئيسيًا أو تابعًا، لأنه يعمل دائمًا في وضع رئيسي/تابع. راجع البرنامج النصي runFuzz لمزيد من معلومات الاستخدام.
لاحظ أيضًا أن هذا ينشئ فقط مجموعة صغيرة من المدخلات المثال. لاختبار عدد كبير من استدعاءات النظام المهمة، ستحتاج على الأرجح إلى توليد مثال واحد لكل استدعاء نظام، أو على الأقل مثال واحد لكل "شكل" من أشكال استدعاء النظام. يجب وضع هذه في inputs/. انظر gen2.py للحصول على مثال.
لإعادة إنتاج حالات الاختبار (مثل الأعطال) شغّل:
./runTest inputs/ex1
./runTest outputs/crashes/id*
يمكنك أيضًا تشغيل المُشغِّل خارج البيئة المُحاكاة باستخدام الخيار -t، مع تسجيل مفصّل مع -vv وبدون تنفيذ استدعاءات النظام فعليًا مع -x:
./driver -tvvx < inputs/ex1
strace ./driver -t < inputs/ex1
من المفيد أحيانًا أن تكون قادرًا على إقلاع النواة وتشغيل الاختبارات بشكل تفاعلي. للقيام بذلك، عدّل ملفات rootTemplate كما تراه مناسبًا (على سبيل المثال، لإضافة المزيد من أدوات الاختبار إلى نظام الملفات الجذر)، ثم شغّل:
./runCmd
يمكن استدعاء أوامر أخرى غير الصدفة عبر تمريرها كوسائط لسطر الأوامر إلى runCmd.
ملاحظة: عند الانتهاء من الصدفة، استخدم ^A-c للحصول على موجه QEMU واكتب quit.
يكون التصحيح أسهل عند استخدام نواة مبنية مع تفعيل رموز التصحيح.
استخدم runTest لبدء النواة وتشغيل اختبار عبر المُشغِّل، أو استخدم runCmd لتشغيل حالة اختبار يدويًا من الصدفة.
عدّل برنامج التشغيل النصي الخاص بك ليشمل الخيار -s عند بدء afl-qemu-system-trace.
سيؤدي ذلك إلى تفعيل دعم gdb على منفذ TCP 1234. استخدم getvmlinux لاستخراج صورة نواة vmlinux من النواة bzImage وشغّل gdb بعد إقلاع النظام:
cp kern/bzImage .
./getvmlinux
gdb ./vmlinux
target remote :1234
break somefunction
continue
يمكنك إرفاق المُنقِّح بعد أن يتسبب runTest في تعطل، أو قبل أن تقوم يدويًا بإطلاق الخلل في runCmd.
لاحظ أن مصادر Linux تُجمَّع مع تفعيل التحسين افتراضيًا. هذا قد يجعل التصحيح مربكًا وصعبًا.
يمكنك تعطيل التحسين بشكل فردي لكل ملف عن طريق تعديل ملف Makefile الخاص بمجلد Linux الفرعي الذي يوجد فيه الملف وإضافة CFLAGS_name.o = -O0 إلى Makefile. على سبيل المثال، تعديل kernel/Makefile وإضافة CFLAGS_sys_ni.o = -O0 سيعطل التحسين عند بناء kernel/sys_ni.o.
البرنامج النصي getSyms يستخدم runCmd لتنفيذ cat /proc/kallsyms واستخراجه إلى ملف محلي باسم kallsyms. يُستخدم هذا عادةً لتجهيز النواة للفازينغ:
K=yourKernDir ./getSyms للحصول على kallsymsmv kallsyms yourKernDir لتثبيتهملاحظة: عند القيام بالفازينغ على نواة Linux 2.* ستحتاج إلى تفعيل مؤقّت المعالج. عندما لا يكون المؤقّت مفعّلاً، لا يبدو أن كشف الذعر والتسجيل يعمل بشكل صحيح، وتؤدي حالات الذعر إلى تعليق. لتفعيل المؤقّت، استدعِ startForkserver(1) في driver.c بدلاً من startForkserver(0). لا يبدو أن هذه المشكلة تحدث في نوى Linux3.* وLinux4.*.