
معترض استدعاءات النظام في مساحة النواة ومُعطِّل عشوائي
KRF هي أداة Kernelspace Randomized Faulter.
تدعم حالياً نواتي لينكس وفري بي إس دي.
حقن الأعطال هي تقنية اختبار برمجيات تتضمن إحداث فشل ("أعطال") في الدوال التي يستدعيها برنامج. إذا فشل المُستدعَى في إجراء التحقق المناسب من الأخطاء ومعالجتها، فقد تؤدي هذه الأعطال إلى سلوك تطبيق غير موثوق أو ثغرات قابلة للاستغلال.
على عكس العديد من أنظمة حقن الأعطال في فضاء المستخدم، يعمل KRF في فضاء النواة عبر وحدة محملة. هذا يتمتع بعدة مزايا:
LD_PRELOAD للحقن.syscall(3) أو التجميع المضمن.dlsym.هناك أيضاً عدة عيوب:
cr0 يدوياً. ربما هناك طريقة مستقلة عن البنية للقيام بذلك في لينكس، في مكان ما.يعيد KRF كتابة جدول استدعاءات النظام في لينكس أو فري بي إس دي: عندما يتم تكوينه عبر krfctl، يستبدل KRF استدعاءات النظام القابلة للفشل بأغلفة رفيعة.
ثم يقوم كل غلاف بإجراء فحص لمعرفة ما إذا كان يجب إفشال الاستدعاء باستخدام نظام استهداف قابل للتكوين قادر على استهداف personality(2) محدد، PID، UID، و/أو GID. إذا كانت العملية لا ينبغي إفشالها، يتم استدعاء استدعاء النظام الأصلي.
أخيراً، يتم إفشال الاستدعاء المستهدف عبر دالة فشل عشوائية. على سبيل المثال، قد يتلقى استدعاء read(2) واحداً من EBADF، EINTR، EIO، وهكذا.
يمكنك قراءة المزيد عن تنفيذ KRF في مقالنا على المدونة.
ملاحظة: إذا كان لديك Vagrant، فقط استخدم ملف Vagrantfile وانتقل إلى خطوات البناء.
يجب أن يعمل KRF على أي نواة لينكس حديثة نسبياً (4.15+) مع تمكين CONFIG_KALLSYMS=1.
هذا يتضمن النواة الافتراضية على أوبونتو 18.04 وربما العديد من التوزيعات الحديثة الأخرى.
ملاحظة: تجاهل هذا إذا كنت تستخدم Vagrant.
بصرف النظر عن مجموعة أدوات C (GCC ربما ضروري للينكس)، فإن التبعيات الوحيدة لـ KRF يجب أن تكون libelf، رؤوس النواة، وروبي (>=2.4، لتوليد الكود).
GNU Make مطلوب على جميع المنصات؛ فري بي إس دي بالإضافة يتطلب BSD Make.
للأنظمة التي تحتوي على apt:
sudo apt install gcc make libelf-dev ruby linux-headers-$(uname -r)
git clone https://github.com/trailofbits/krf && cd krf
make -j$(nproc)
sudo make install # تثبيت الوحدة في /lib/modules والأدوات في /usr/local/bin
sudo make insmod # تحميل الوحدة
أو، إذا كنت تستخدم Vagrant:
git clone https://github.com/trailofbits/krf && cd krf
vagrant up linux && vagrant ssh linux
# داخل الجهاز الافتراضي
cd /vagrant
make -j$(nproc)
sudo make install # تثبيت الوحدة في /lib/modules والأدوات في /usr/local/bin
sudo make insmod # تحميل الوحدة
أو، لفري بي إس دي:
git clone https://github.com/trailofbits/krf && cd krf
cd vagrant up freebsd && vagrant ssh freebsd
# داخل الجهاز الافتراضي
cd /vagrant
gmake # ليس make!
gmake install-module # تثبيت الوحدة في /boot/modules/
sudo gmake install-utils # تثبيت الأدوات في /usr/local/bin
gmake insmod # تحميل الوحدة
يتكون KRF من ثلاثة مكونات:
krfx)krfexec)krfctl)krfmesg)لتحميل وحدة النواة، قم بتشغيل make insmod. لإلغاء تحميلها، قم بتشغيل make rmmod.
للاستخدام الأول، قد يكون من المفيد تشغيل sudo krfmesg على طرفية منفصلة لرؤية الرسائل المسجلة من krfx.
يبدأ KRF في حالة محايدة: لن يتم اعتراض أو إفشال أي استدعاءات نظام حتى يحدد المستخدم سلوكاً عبر krfctl:
# لا أعطال مستحثة، حتى مع تحميل KRF
ls
# أخبر krf بإفشال استدعاءات read(2) و write(2)
# لاحظ أن krfctl يتطلب صلاحيات الجذر
sudo krfctl -F 'read,write'
# أخبر krf بإفشال أي برنامج يبدأ بواسطة
# krfexec، مما يعني personality بقيمة 28
sudo krfctl -T personality=28
# قد يفشل!
krfexec ls
# أخبر krf بالإفشال باحتمال 1/100 (أو 1%)
# لاحظ أن هذه القيمة ممثلة كمقلوب
# لذا مثلاً 1 يعني أن كل استدعاءات النظام القابلة للفشل ستفشل
# و 500 يعني أن في المتوسط كل 500 استدعاء نظام سيفشل (1/500 أو 0.2%)
sudo krfctl -p 100
# أخبر krf بإفشال ملف تعريف `io` (وبالتالي استدعاءات النظام المتعلقة بالإدخال/الإخراج)
sudo krfctl -P io
# krfexec سيمرر الخيارات بشكل صحيح أيضاً
krfexec echo -n 'no newline'
# امسح مواصفات الفشل
sudo krfctl -c
# امسح مواصفات الاستهداف
sudo krfctl -C
# لا أعطال مستحثة، حيث لا يتم إفشال أي استدعاءات نظام
krfexec firefox
ملاحظة: يجب على معظم المستخدمين استخدام krfctl بدلاً من التعامل مع هذه الملفات يدوياً.
في فري بي إس دي، يمكن الوصول إلى هذه القيم نفسها عبر sysctl krf.whatever بدلاً من procfs.
/proc/krf/rng_stateيسمح هذا الملف للمستخدم بقراءة وتعديل الحالة الداخلية لمولد الأرقام العشوائية الزائفة (PRNG) لـ KRF.
على سبيل المثال، كل مما يلي سيحدث الحالة بشكل صحيح:
echo "1234" | sudo tee /proc/krf/rng_state
echo "0777" | sudo tee /proc/krf/rng_state
echo "0xFF" | sudo tee /proc/krf/rng_state
الحالة هي عدد صحيح غير موقع 32 بت؛ محاولة تغييرها إلى ما بعد ذلك ستفشل.
/proc/krf/targetingيسمح هذا الملف للمستخدم بتعيين القيم التي يستخدمها KRF لاستهداف استدعاءات النظام.
ملاحظة: يستخدم KRF personality افتراضياً غير مستخدم حالياً بواسطة نواة لينكس بشكل افتراضي. إذا قمت بتغيير هذا، يجب أن تكون حريصاً على تجنب جعله شيئاً تهتم به لينكس. man 2 personality يحتوي على التفاصيل.
echo "0 28" | sudo tee /proc/krf/targeting
يتم ترميز personality بقيمة 28 بشكل ثابت في krfexec، ويجب تعيينها لكي يتم إفشال الأشياء المنفذة بواسطة krfexec.
/proc/krf/probabilityيسمح هذا الملف للمستخدم بقراءة وكتابة احتمالية إحداث فشل لاستدعاء نظام معين (قابل للفشل).
يتم تمثيل الاحتمال كمقلوب، مثلاً 1000 يعني أنه، في المتوسط، 0.1% من استدعاءات النظام القابلة للفشل سيتم إفشالها.
echo "100000" | sudo tee /proc/krf/probability
/proc/krf/controlيتحكم هذا الملف في استدعاءات النظام التي يقوم KRF بإفشالها.
ملاحظة: يجب على معظم المستخدمين استخدام krfctl بدلاً من التفاعل مع هذا الملف مباشرة — فالأول سيقوم بترجمة اسم استدعاء النظام إلى رقمه تلقائياً وسيوفر رسائل خطأ أوضح عند حدوث أخطاء.
# استبدال استدعاء النظام في الفتحة 0 (عادة SYS_read) بغلافه المعيب
echo "0" | sudo tee /proc/krf/control
تمرير أي رقم أكبر من KRF_NR_SYSCALLS سيجعل KRF يمسح جدول استدعاءات النظام بالكامل، معيداً إياه إلى الحالة المحايدة. نظراً لأن KRF_NR_SYSCALLS ليس بالضرورة قابلاً للتنبؤ للإصدارات العشوائية من نواة لينكس، فإن اختيار رقم كبير (مثل 65535) يعتبر جيداً.
تمرير رقم استدعاء نظام صحيح يفتقر إلى غلاف حقن فشل سيجعل write(2) للملف يفشل بـ EOPNOTSUPP.
/proc/krf/log_faultsيتحكم هذا الملف في ما إذا كان KRF يصدر سجلات نواة على استدعاءات النظام المعيبة. بشكل افتراضي، لا يتم إصدار أي رسائل تسجيل.
ملاحظة: يجب على معظم المستخدمين استخدام krfctl بدلاً من التفاعل مع هذا الملف مباشرة.
# تمكين تسجيل الأعطال
echo "1" | sudo tee /proc/krf/log_faults
# تعطيل تسجيل الأعطال
echo "0" | sudo tee /proc/krf/log_faults
# قراءة حالة التسجيل
cat /proc/krf/log_faults
ENOMEM).
personality(2).جزيل الشكر لـ Andrew Reiter على المنفذ الأولي لـ KRF إلى فري بي إس دي. تم تنفيذ عمل Andrew نيابة عن مجموعة الأبحاث التطبيقية في Veracode.
KRF مرخص تحت شروط GNU GPLv3.
انظر ملف LICENSE للحصول على الشروط الدقيقة.