
Бинарный, покрытие-ориентированный фаззер для Windows, macOS, Linux и Android
Copyright 2020 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Jackalope — это настраиваемый распределённый фаззер с покрытием, способный работать с чёрными ящиками (black-box binaries).
Хотя существует множество хороших фаззеров с покрытием, работающих с целями, для которых доступен исходный код, относительно мало тех, что работают с чёрными ящиками, в частности в операционных системах Windows и macOS, а те, что существуют, в основном основаны на кодовых базах, которые не очень легко настраивать. Начальные цели Jackalope:
Jackalope можно использовать автономно, но он становится мощнее при использовании в качестве библиотеки, где пользователи могут подключать собственные компоненты, заменяющие поведение по умолчанию. По умолчанию Jackalope поставляется с:
Jackalope можно запускать параллельно
-nthreads-start_server) и подключив фаззеры на рабочих машинах к этому серверу (флаг командной строки -server). Затем сервер собирает и распределяет образцы, краши и покрытие между рабочими машинами.В настоящее время Jackalope не включает продвинутые стратегии мутации. Вместо этого он поставляется с набором универсальных мутаторов, которые будут работать для многих целей, однако пользователям рекомендуется писать собственные мутаторы и стратегии мутации в соответствии с целями, которые они хотят фаззить.
В настоящее время фаззинг чёрных ящиков поддерживается в операционных системах Windows, macOS, Linux и Android.
На Linux Jackalope также может работать с Sanitizer Coverage (требуется исходный код цели). Этот режим описан в отдельном документе.
Предварительное требование: Python 3
Откройте терминал и настройте среду сборки при необходимости. В Windows вместо открытия обычной командной строки вам нужно открыть командную строку Visual Studio для платформы, под которую вы собираете, или запустить vcvars64.bat / vcvars32.bat.
Перейдите в каталог, содержащий исходный код.
Выполните следующие команды:
cd Jackalope
git clone --recurse-submodules [email protected]:googleprojectzero/TinyInst.git
(alternately: git clone --recurse-submodules https://github.com/googleprojectzero/TinyInst.git)
mkdir build
cd build
cmake <generator arguments> ..
cmake --build . --config Release
Аргументы генератора зависят от вашей среды. На macOS вам следует использовать -G Xcode, тогда как, например, в Windows с Visual Studio 2019 и для 64-битной сборки вы бы использовали -G "Visual Studio 16 2019" -A x64. На Linux аргументы генератора не требуются. При кросс-компиляции для Android требуются дополнительные аргументы cmake, те же, что описаны в инструкциях по сборке TinyInst для Android. Если вы фаззите Android на виртуальной машине, поддерживающей разделяемую память через /dev/shm, -DANDROID_TARGET=VM включает доставку образцов через разделяемую память.
Для сборки под arm64e бинарники на macOS см. здесь.
Получаете ошибку No CMAKE_C_COMPILER could be found на macOS? Попробуйте обновить cmake. Также убедитесь, что Xcode установлен и вы запускали его хотя бы раз (при первом запуске он устанавливает некоторые компоненты).
Использование:
./fuzzer <fuzzer arguments> <instrumentation and other components arguments> -- <target command line>
Поддерживаются следующие аргументы командной строки:
-in — Входной каталог (каталог, содержащий начальный набор образцов). Если входной каталог — "-", фаззер пытается восстановить предыдущую сессию (то же самое, что использование флага -restore).
-out — Выходной каталог
-t — Таймаут образца в мс
-t1 — Таймаут инициализации цели (например, до достижения целевого метода, если он определён). По умолчанию равен таймауту образца.
-nthreads — Количество потоков фаззера. По умолчанию 1.
-delivery <file|shmem> — Используемый механизм доставки образцов. Если file, каждый образец выводится как файл, и "@@" в аргументах цели заменяется на путь к файлу. Если shmem, фаззер вместо этого создаёт разделяемую память и заменяет "@@" в аргументах цели на имя разделяемой памяти. В этом случае ответственность за открытие разделяемой памяти и извлечение образца лежит на цели. По умолчанию file.
-file_extension — При использовании доставки образцов через file добавляет указанное расширение к имени файла. Полезно, если цель ожидает, что входные файлы будут иметь определённое расширение.
-restore или -resume — Восстанавливает и возобновляет предыдущую сессию фаззинга. Как процесс фаззера, так и процесс сервера поддерживают восстановление.
-server — Указывает используемый сервер покрытия.
-start_server — Запустить процесс сервера вместо процесса фаззинга.
-crash_retry — Количество попыток воспроизвести краш. По умолчанию 10. Краши, которые не воспроизводятся в течение этого числа попыток или не воспроизводятся при запуске без инструментации, помечаются как нестабильные (flaky).
-coverage_retry — Количество попыток воспроизвести новое покрытие. Покрытие, которое не может быть надёжно воспроизведено в течение этого числа попыток, считается нестабильным. Образцы, содержащие только нестабильное покрытие, не сохраняются.
-clean_target_on_coverage — Перезапускать цель при воспроизведении покрытия. По умолчанию true.
-minimize_samples — Попытаться минимизировать новые образцы перед сохранением их в корпус. По умолчанию true.
-iterations_per_round — Количество раз, которое нужно мутировать и запустить образец из корпуса, прежде чем перейти к следующему образцу. По умолчанию 1000. Возможно, стоит уменьшить это значение для очень медленных целей.
-deterministic_mutations — Использовать детерминированные мутации в дополнение к недетерминированным. По умолчанию true, если не используется флаг -server.
-deterministic_only — Приоритизировать детерминированные мутации. Примечание: даже с этим флагом фаззер всё равно будет использовать недетерминированные мутации, но только после того, как все детерминированные мутации будут исчерпаны. Это может быть полезно при работе с -server, чтобы один клиентский экземпляр выполнял детерминированные мутации.