
Лёгкий фаззинг снимка памяти с использованием KVM
Лёгкий фаззинг снапшота памяти с помощью KVM
Snapchange предоставляет возможность загружать необработанный дамп памяти и состояние регистров в виртуальную машину KVM (ВМ) для выполнения. В определённый момент выполнения эту ВМ можно сбросить в исходное состояние, сбросив грязные страницы, обнаруженные KVM, или страницы, вручную помеченные как грязные фаззером.
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
Краткое описание терминов для этого README:
Гипервизор начинает с отображения файла физической памяти для каждого запрошенного ядра. Таким образом, каждое ядро имеет свою собственную уникальную копию памяти. Затем гипервизор создаёт гостевую KVM и предоставляет гостю эту резервную память. Состояние регистров этого гостя затем инициализируется переданным состоянием регистров, и запускается выполнение гостя. Гипервизор ожидает выхода гостя. Каждый выход обрабатывается гипервизором, и некоторые из них передаются фаззеру для специфичных для цели мутаций, изменений или интроспекции. Если обработчик выхода указывает, что гостя следует сбросить, гипервизор выходит из цикла выполнения и возвращает гостя в исходное состояние снапшота, после чего перезапускает цикл заново.
Покрытие гостя формируется с помощью точек останова покрытия. Гипервизору можно передать отдельный файл со списком адресов для точек останова. Если какой-либо из этих адресов будет достигнут, адрес будет добавлен в базу данных покрытия, а инструкция для этого адреса будет восстановлена. Таким образом, точка останова больше не будет срабатывать.
Snapchange использует проектные каталоги, специфичные для цели, для конфигурации. В этом каталоге размещаются входные и выходные файлы и каталоги. Следующие расширения файлов/каталоги используются в качестве входных данных:
.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.