
مختبر عشوائي لمحرك جافا سكريبت
مُختبر اختراق (Fuzzer) موجه بالتغطية (coverage-guided) لمفسري اللغات الديناميكية، يعتمد على لغة وسيطة مخصصة (FuzzIL) يمكن تحويرها وترجمتها إلى جافاسكريبت.
الخطوات الأساسية لاستخدام هذا المُختبر هي:
swift build [-c release].swift run [-c release] FuzzilliCli --profile=<profile> [other cli options] /path/to/jsshell. راجع أيضًا swift run FuzzilliCli --help.إنشاء وتشغيل فيوزيلي ومحركات جافاسكريبت المدعومة داخل Docker وعلى Google Compute Engine مدعوم أيضًا.
اطلع على main.swift لترى مثالاً على استخدام مكتبة فيوزيلي وتجربة خيارات التكوين المختلفة. بعد ذلك، ألق نظرة على Fuzzer.swift للاطلاع على منطق الاختبار عالي المستوى. من هناك، تعمق في أي جزء يبدو مثيرًا للاهتمام.
التصحيحات والإضافات والمساهمات الأخرى لهذا المشروع مرحب بها جدًا! ومع ذلك، يُرجى مراجعة ملاحظات المساهمين بسرعة. يتبع فيوزيلي تقريبًا دليل أسلوب كود جوجل لـ Swift.
سيكون موضع تقدير كبير إذا أمكنك إرسال ملاحظة قصيرة (قد تتضمن رقم CVE) إلى [email protected] أو فتح طلب سحب (pull request) لأي ثغرة تم العثور عليها بمساعدة هذا المشروع ليتم تضمينها في قسم عرض الثغرات. بخلاف ذلك، يمكنك بالطبع المطالبة بأي مكافأة للثغرات، أرصدة CVE، إلخ للثغرات :)
عند اختبار الأخطاء الأساسية للمفسر، مثل مترجمات JIT، تصبح الصحة الدلالية للبرامج المُنشأة مصدر قلق. وهذا على عكس معظم السيناريوهات الأخرى، مثل اختبار واجهات برمجة التطبيقات في وقت التشغيل، حيث يمكن بسهولة تجاوز مشكلة الصحة الدلالية عن طريق تغليف الكود المُنشأ في بنيات try-catch. هناك احتمالات مختلفة لتحقيق معدل مقبول من العينات الصحيحة دلالياً، أحدها هو النهج التحويري (mutational approach) حيث تكون جميع العينات في المجموعة (corpus) صالحة دلاليًا أيضًا. في هذه الحالة، كل تحوير له فرصة صغيرة فقط لتحويل عينة صالحة إلى عينة غير صالحة.
لتنفيذ مُختبر اختراق جافاسكريبت قائم على التحوير، يجب تعريف التحويرات على كود جافاسكريبت. بدلاً من تحوير شجرة البنية المجردة (AST) أو العناصر النحوية الأخرى للبرنامج، يتم تعريف لغة وسيطة مخصصة (IL) يمكن من خلالها إجراء تحويرات على تدفق التحكم والبيانات بشكل أكثر مباشرة. يتم بعد ذلك ترجمة هذه اللغة الوسيطة إلى جافاسكريبت للتنفيذ. تبدو اللغة الوسيطة تقريبًا كما يلي:
v0 <− LoadInteger '0'
v1 <− LoadInteger '10'
v2 <− LoadInteger '1'
v3 <− LoadInteger '0'
BeginFor v0, '<', v1, '+', v2 −> v4
v6 <− BinaryOperation v3, '+', v4
Reassign v3, v6
EndFor
v7 <− LoadString 'Result: '
v8 <− BinaryOperation v7, '+', v3
v9 <− LoadGlobal 'console'
v10 <− CallMethod v9, 'log', [v8]
والتي يمكن، على سبيل المثال، ترجمتها بسهولة إلى كود جافاسكريبت التالي:
const v0 = 0;
const v1 = 10;
const v2 = 1;
let v3 = 0;
for (let v4 = v0; v4 < v1; v4 = v4 + v2) {
const v6 = v3 + v4;
v3 = v6;
}
const v7 = "Result: ";
const v8 = v7 + v3;
const v9 = console;
const v10 = v9.log(v8);
أو إلى كود جافاسكريبت التالي عن طريق تضمين التعبيرات الوسيطة (inlining):
let v3 = 0;
for (let v4 = 0; v4 < 10; v4++) {
v3 = v3 + v4;
}
console.log("Result: " + v3);
تمتلك FuzzIL عددًا من الخصائص:
Reassign.يمكن بعد ذلك إجراء عدد من التحويرات على هذه البرامج:
يمكن العثور على مناقشة أكثر شمولاً لكيفية عمل فيوزيلي هنا.
المُختبر مُنفذ بلغة Swift، مع بعض الأجزاء (مثل قياسات التغطية، تفاعلات المقابس، إلخ) منفذة بلغة C.
يتكون مثيل المُختبر (منفذ في Fuzzer.swift) من المكونات المركزية التالية:
علاوة على ذلك، تتوفر عدد من الوحدات اختياريًا: