
Фреймворк статического анализа, который выявляет цели для фаззинга в исходном коде и бинарных файлах, генерирует шаблоны обёрток и интегрируется с AFL++ и libFuzzer для автоматического обнаружения уязвимостей.
Фреймворк для автоматизации Fuzzable поиска целей с помощью статического анализа

Исследователи уязвимостей, проводящие оценку безопасности программного обеспечения, часто используют возможности фаззинга с покрытием кода с помощью мощных инструментов, таких как AFL++ и libFuzzer. Это важно, поскольку автоматизирует процесс поиска ошибок и быстро выявляет эксплуатируемые условия в целях. Однако при работе с большими и сложными кодовыми базами или закрытыми бинарными файлами исследователям приходится тратить время на ручной аудит и реверс-инжиниринг, чтобы определить функции, в которых может быть полезен фаззинг.
Fuzzable — это фреймворк, который интегрируется как с исходным кодом C/C++, так и с бинарными файлами, помогая исследователям уязвимостей выявлять функции-цели, пригодные для фаззинга. Это достигается применением нескольких эвристик на основе статического анализа, которые выявляют рискованное поведение в программном обеспечении и функции, его выполняющие. Затем исследователи могут использовать фреймворк для генерации базовых шаблонов обвязок, которые можно применять для поиска уязвимостей или интегрировать в конвейер непрерывного фаззинга, такой как проект Google oss-fuzz.
Помимо использования в качестве отдельного инструмента, Fuzzable также интегрирован в виде плагина для дизассемблера Binary Ninja; в настоящее время разрабатывается поддержка других бэкендов дизассемблирования.
Ознакомьтесь с оригинальной статьёй в блоге, подробно описывающей инструмент здесь; в ней освещены технические характеристики эвристик статического анализа и история создания этого инструмента. Этот инструмент также был представлен на Black Hat Arsenal USA 2022.
Некоторые бинарные цели могут требовать очистки (например, сопоставления сигнатур или идентификации функций после инлайнинга), поэтому fuzzable в первую очередь использует Binary Ninja в качестве бэкенда дизассемблирования из-за его способности эффективно решать эти задачи. Таким образом, его можно использовать как отдельный инструмент, так и плагин.
Поскольку Binary Ninja доступен не всем и может потребоваться для оценки безопасности и масштабирования в облаке, также поддерживается запасной бэкенд angr. В будущем планируется добавление других дизассемблеров (в первую очередь Ghidra).
Если у вас есть Binary Ninja Commercial, обязательно установите API для автономного использования:
$ python3 /Applications/Binary\ Ninja.app/Contents/Resources/scripts/install_api.py
Установка с помощью pip:
$ pip install fuzzable
Для управления зависимостями и сборки мы используем poetry. Чтобы выполнить ручную сборку, клонируйте репозиторий вместе со сторонними модулями:
$ git clone --recursive https://github.com/ex0dus-0x/fuzzable
Для ручной установки:
$ cd fuzzable/
# без poetry
$ pip install .
# с poetry
$ poetry install
# с poetry для виртуального окружения разработки
$ poetry shell
Теперь вы можете анализировать бинарные файлы и/или исходный код с помощью инструмента!
# анализ одной библиотеки в виде shared object
$ fuzzable analyze examples/binaries/libbasic.so
# анализ одного файла исходного кода на C
$ fuzzable analyze examples/source/libbasic.c
# анализ рабочей области с несколькими файлами C/C++ и заголовками
$ fuzzable analyze examples/source/source_bundle/
fuzzable можно легко установить через маркетплейс плагинов Binary Ninja, перейдя в Binary Ninja > Manage Plugins и выполнив поиск. Вот пример работы плагина fuzzable,
точно определяющего цели для фаззинга и дальнейшей оценки уязвимостей:

fuzzable предоставляет различные опции для более точной настройки анализа. В будущих планах и по запросам будет добавлена дополнительная поддержка.
Для определения пригодности к фаззингу fuzzable использует несколько эвристик, которые определяют наиболее жизнеспособные цели для динамического анализа. Все эти эвристики взвешены по-разному с помощью библиотеки scikit-criteria, которая использует многокритериальный анализ решений для выбора наилучших кандидатов. Эти метрики и их веса представлены ниже:
| Эвристика | Описание | Вес |
|---|---|---|
| Имя, дружественное к фаззингу | Имя символа указывает на поведение, принимающее файловый/буферный ввод | 0.3 |
| Опасные стоки | Аргументы, попадающие в опасные вызовы (например, memcpy) | 0.3 |
| Естественные циклы | Количество циклов, обнаруженных с помощью границы доминирования | 0.05 |
| Цикломатическая сложность | Сложность функции-цели на основе рёбер и узлов | 0.05 |
| Глубина покрытия | Количество вызываемых функций, в которые углубляется цель | 0.3 |
Как упоминалось, ознакомьтесь с технической статьёй в блоге для более глубокого понимания того, почему и как используются эти метрики.
Многие метрики были вдохновлены оригинальной работой Винченцо Иоццо по фаззингу с нулевым знанием.
Каждая анализируемая цель уникальна, и fuzzable не сможет учесть все граничные случаи поведения программы. Поэтому во время анализа может быть важно настроить эти веса соответствующим образом, чтобы увидеть, не дают ли другие результаты больше смысла для вашего сценария. Чтобы настроить веса в CLI, просто укажите аргумент --score-weights:
$ fuzzable analyze <ЦЕЛЬ> --score-weights=0.2,0.2,0.2,0.2,0.2
По умолчанию fuzzable фильтрует функции-цели по следующим критериям:
static и не доступные через заголовки.Чтобы увидеть вызовы, отфильтрованные fuzzable, установите флаг --list_ignored:
$ fuzzable analyze --list-ignored <ЦЕЛЬ>