Набор примеров фаззинга на Linux, в которых демонстрируется часть функционала Crusher:
- python - фаззинг через файл;
- jasper - фаззинг через файл с использованием DSE (динамическое символьное выполнение);
- faad - фаззинг через аргументы командной строки;
- OpenSSL - фаззинг OpenSSL-сервера: Peach Pit + ISP_PRELOAD;
- stm32 - фаззинг ПО устройства ARM (на основе частичной эмуляции с Lua-Qemu);
- firmware_x86_32 - фаззинг ПО устройства x86 (32-бит) (на основе частичной эмуляции с Lua-Qemu);
- firmware_x86_64 - фаззинг ПО устройства x86 (64-бит) (на основе частичной эмуляции с Lua-Qemu);
- fullsystem_emulation - фаззинг с полносистемной эмуляцией х86 (64-бит) (на основе частичной эмуляции с Lua-Qemu);
- qiling - фаззинг с частичной эмуляцией с помощью Qiling;
- unicorn - фаззинг с помощью эмулятора Unicorn;
- partial_emulation - пример частичной эмуляции с помощью модуля DualEmu, комбинирующего фаззинг с помощью unicornafl и DSE с Angr;
- java - фаззинг Keycloak;
- python_fuzz - фаззинг библиотеки на языке python;
- c# - фаззинг dll библиотек, написанных на C#, через файл и stdin;
- nginx_docker - фаззинг сервера Nginx в Docker-режиме;
- OpenSSL_mod_client - фаззинг OpenSSL-сервера методом модифицированного клиента;
- arm_rootfs_gzip - фаззинг gzip из Ubuntu20 (ARM) с применением Qemu (user-mode);
- pytorch - фаззинг python-модуля pytorch;
- kern_netfilter - фаззинг компонента ядра с использованием снимков памяти (снапшотов).
Далее приведена последовательность действий по фаззингу, мониторингу и воспроизведению аварийных завершений (крешей) для следующих примеров: python, jasper и faad.
Для остальных примеров подробные инструкции можно найти в файлах README.md в соответствующих директориях.
В директории примера есть скрипт fuzz.sh для запуска фаззинга.
Данному скрипту нужно передать 2 опции:
-f </path/to/crusher/bin_x86-64/fuzz_manager>- путь до исполняемого файлаfuzz_manager;-c <num>- число ядер для фаззинга.
Результаты будут записываться в папку out.
Пример запуска фаззинга приложения:
./fuzz.sh -f /path/to/crusher/bin_x86-64/fuzz_manager -c 4Для мониторинга фаззинга нужно запустить в другом терминале UI (User Interface - пользовательский интерфейс) через исполняемый файл ./bin_86-64/ui (из релиза Crusher), который принимает в качестве аргумента путь до соответствующей директории с результатами фаззинга.
Например, для мониторинга фаззинга приложения выполните команду (укажите актуальные пути):
/path/to/crusher/bin_x86-64/ui -o /path/to/outВ каждом примере фаззинг приводит к нахождению аварийных завершений (крешей).
В правом верхнем углу окна пользовательского интерфейса можно наблюдать окно Stats. В нём обратите внимание на поле unique_crashes.
Как только будет найдено аварийное завершение, значение поля unique_crashes станет ненулевым. Пока значение поля нулевое - не останавливайте фаззинг.
Желательно дождаться, когда значение поля будет больше 1. После этого можно остановить фаззинг:
- в терминале с
UI(пользовательский интерфейс) - для выхода изUIнажмите кнопкуq; - в терминале с запущенным фаззингом завершите фаззинг по комбинации клавиш
Ctrl+C.
- Для получения списка найденных файлов-крешей (кроме случая фаззинга аргументов командной строки) выполните команду (укажите актуальный путь до out-директории):
find out -name id_crash_*- В скрипте
fuzz.shпосле символов--прописана команда запуска приложения. Например, дляpythonона выглядит так:
./python-2.5 __DATA__Далее возможны 2 случая:
а) в случае фаззинга файла (как в примере python) - выполните вышеуказанную команду, заменив последовательность символов __DATA__ на один из путей к креш-файлу, полученных в пункте 1), например:
./python-2.5 out/FUZZ-MASTER_0/crashes/id_crash_0б) в случае фаззинга argv (аргументов командной строки, как в примере faad) - выполните вышеуказанную команду, заменив последовательность символов __DATA__ на $(cat out/EAT_OUT/results/crashes/000000/replay/data),
где out/EAT_OUT/results/crashes/000000/replay/data - пример пути к креш-файлу. Входные данные для воспроизведения находятся в out/EAT_OUT/results/crashes//replay/data, где ID - номер креша.
Пример команды:
LD_PRELOAD=./libfaad.so.2 ./faad $(cat out/EAT_OUT/results/crashes/000000/replay/data)Обратите внимание, что для faad указывается через LD_PRELOAD библиотека, от которой он зависит и которой может не быть в системе.
Во время фаззинга это обеспечивается путём выставления в скрипте fuzz.sh переменной окружения ISP_PRELOAD, которая обеспечивает использование этой библиотеки только в процессе faad,
а не для всех процессов фаззинга (fuzz_manager, fuzz, eat и др.).
- Наблюдаем аварийное завершение: сообщение в терминале, содержащее
Segmentation faultилиAborted. Если соответствующих сообщений не было выведено, то нужно повторить пункты 1)-3) на другом файле.