
فازينغ خفيف الوزن للقطة من الذاكرة باستخدام KVM
Fuzzing خفيف الوزن للقطة ذاكرة باستخدام KVM
يوفر Snapchange القدرة على تحميل تفريغ ذاكرة خام (raw memory dump) وحالة السجلات في جهاز افتراضي (VM) يعمل بنظام KVM للتنفيذ. عند نقطة معينة في التنفيذ، يمكن إعادة تعيين هذا الجهاز الافتراضي إلى حالته الأولية عن طريق إعادة تعيين الصفحات المتسخة (dirty pages) التي يعثر عليها KVM أو الصفحات التي تم توسيخها يدويًا بواسطة أداة Fuzzer.
LibTIFF مع ASANFFmpeg مع محوّل مخصص$ cp -r -L fuzzer_template your_new_fuzzer
your_new_fuzzer/create_snapshot.sh لالتقاط لقطة من هدفكsrc/fuzzer.rs لحقن البيانات المعدّلة في الجهاز الضيف#[derive(Default)]
pub struct TemplateFuzzer;
impl Fuzzer for TemplateFuzzer {
// The type of Input being fuzzed. Used to know how to generate and mutate useful inputs.
type Input = Vec<u8>;
// The starting address of the snapshot
const START_ADDRESS: u64 = 0x402363;
// The maximum length of mutated input to generate
const MAX_INPUT_LENGTH: usize = 100;
fn set_input(&mut self, input: &Self::Input, fuzzvm: &mut FuzzVm<Self>) -> Result<()> {
// Write the mutated input into the data buffer in the guest VM
fuzzvm.write_bytes_dirty(VirtAddr(0x402004), CR3, &input)?;
Ok(())
}
fn reset_breakpoints(&self) -> Option<&[BreakpointLookup]> {
Some(&[
// Reset when the VM hits example1!main+0x123
BreakpointLookup::SymbolOffset("example1!main", 0x123)
])
}
}
$ cargo run -r -- fuzz -c 16
استخدام سريع للمصطلحات الواردة في هذا الملف:
يبدأ الـ Hypervisor بتعيين ملف الذاكرة الفعلية لكل نواة مطلوبة. وبهذه الطريقة، تمتلك كل نواة نسختها الفريدة من الذاكرة. ثم يقوم الـ Hypervisor بإنشاء جهاز KVM الضيف ويمنحه هذه الذاكرة الداعمة (backing memory). بعد ذلك، تتم تهيئة حالة سجلات هذا الضيف باستخدام حالة السجلات المعطاة، ويُطلق تنفيذ الضيف. ينتظر الـ Hypervisor حتى يخرج الضيف (guest exit). يتم التعامل مع كل خروج من قِبل الـ Hypervisor، ويتم تمرير بعضها إلى أداة الـ Fuzzer لإجراء تغييرات أو تعديل أو فحص داخلي خاص بالهدف. إذا أشار معالج الخروج إلى أنه يجب إعادة تعيين الضيف، يخرج الـ Hypervisor من حلقة التشغيل، ويعيد الضيف إلى حالة اللقطة الأصلية، ثم يعيد تشغيل حلقة التشغيل من جديد.
يتم توليد تغطية الضيف باستخدام نقاط توقف التغطية (coverage breakpoints). يمكن تقديم ملف منفصل يحتوي على قائمة عناوين لوضع نقاط توقف عندها إلى الـ Hypervisor. إذا تم الوصول إلى أي من هذه العناوين، سيُضاف العنوان إلى قاعدة بيانات التغطية، وتُستعاد التعليمات الخاصة بذلك العنوان. وبهذه الطريقة، لن يتم تفعيل نقطة التوقف مرة أخرى.
يستفيد Snapchange من أدلة مشاريع مخصصة للهدف (target specific) من أجل الإعدادات (configuration). هذا الدليل هو المكان الذي توضع فيه ملفات وأدلة الإدخال والإخراج. تُستخدم امتدادات/أدلة الملفات التالية كمدخلات:
.physmem - الملف الذي يحتوي على ملف الذاكرة الفعلية الخام.regs - ملف سجلات JSON يحتوي على حالة السجلات.qemuregs - مخرجات info registers من qemuيمكن العثور على القائمة الكاملة للملفات واستخداماتها في دليل المشروع هنا
يمكن العثور على مثال كامل لتتبع التصحيح خطوة بخطوة هنا.
ITERATION 604 0x00007ffff7ecb0d5 0x11115000 | libc-2.31.so!__GI___getpid+0x5 (0x7ffff7ecb0d5)
syscall
[0f, 05]
ITERATION 605 0xffffffff83a00000 0x11115000 | entry_SYSCALL_64+0x0 (0xffffffff83a00000)
swapgs
[0f, 01, f8]
ITERATION 606 0xffffffff83a00003 0x11115000 | entry_SYSCALL_64+0x3 (0xffffffff83a00003)
mov qword ptr gs:[0xa014], rsp
[None:0x0+0xa014=0xa014]]
RSP:0x7fffffffeb78 -> example1!main+0x19 (0x55555555514e)-> 0xff8458b48f44589
[65, 48, 89, 24, 25, 14, a0, 00, 00]
ITERATION 607 0xffffffff83a0000c 0x11115000 | entry_SYSCALL_64+0xc (0xffffffff83a0000c)
nop
[66, 90]
ITERATION 608 0xffffffff83a0000e 0x11115000 | entry_SYSCALL_64+0xe (0xffffffff83a0000e)
mov rsp, cr3
RSP:0x7fffffffeb78 -> example1!main+0x19 (0x55555555514e) -> 0xff8458b48f44589
CR3:0x11115000
[0f, 20, dc]
فيما يلي معلومات حول الحصول على لقطة عبر VirtualBox أو QEMU:
تتضمن الأمثلة سكربت make_example.sh (مثل المثال 1) ينشئ لقطة كاملة من الصفر. يمكن استخدام هذه الأمثلة كقالب لأهداف أخرى للحصول على لقطات قابلة لإعادة الإنتاج.
make all
cargo doc --open
يوفر ملف HACKING بعض المواقع عالية المستوى في قاعدة الشيفرة للبدء في فهم النظام.
انظر CONTRIBUTING لمزيد من المعلومات.
هذا المشروع مرخّص بموجب رخصة Apache-2.0.