Учебное пособие по фаззингу (фаззингу)

⚡ Умное резюме

Фаззинг-тестирование вводит в программу недопустимые, неожиданные или случайные данные и отслеживает сбои, зависания и ошибки памяти, выявляя уязвимости безопасности, которые скриптовые функциональные тесты практически никогда не обнаруживают самостоятельно.

  • 🔘 Происхождение: Термин был придуман Бартоном Миллером в Университете Висконсина в Мэдисоне, а первые запуски фаззинга в 1989 году привели к сбою примерно трети протестированных утилит UNIX.
  • ☑️ Цикл из шести шагов: Определите цель, определите входные данные, сгенерируйте нечеткие данные, выполните операцию, отслеживайте поведение, а затем зарегистрируйте каждый обнаруженный дефект.
  • Стратегии трех поколений: Фаззеры, использующие мутации, искажают допустимые образцы, фаззеры, использующие генерацию, формируют входные данные на основе модели, а фаззеры, использующие протоколы, работают на основе спецификации.
  • 🧪 Отзывы о публикациях изменили эту область: Современные движки сохраняют все входные данные, поступающие в новый код, что позволяет обнаруживать гораздо более глубокие ошибки, чем при использовании чисто случайных данных.
  • 🇧🇷 Инструментарий значительно усовершенствовался: Peach Fuzzer и WebScarab находятся в архиве, в то время как AFL++, libFuzzer, OSS-Fuzz, boofuzz ​​и OWASP ZAP являются поддерживаемыми вариантами.
  • ⚙️ Известные ограничения: Фаззинг выявляет сбои, а не логические ошибки, поэтому он дополняет, а не заменяет анализ кода и тестирование на проникновение.

Учебное пособие по фаззингу (фаззингу)

Что такое фазз-тестирование?

Фазз-тестирование или фаззинг Фазз-тестирование — это метод тестирования программного обеспечения, заключающийся во введении в программную систему недопустимых или случайных данных, называемых FUZZ-тестированием, для выявления ошибок кодирования и уязвимостей безопасности. Цель фазз-тестирования — введение данных с использованием автоматизированных или полуавтоматизированных методов и проверка системы на наличие различных исключений, таких как сбои системы или ошибки встроенного кода.

Фаззинг-тестирование было первоначально разработано Бартоном Миллером в Университете Висконсина в Мэдисоне. Он придумал этот термин после того, как помехи в сети модема привели к сбоям в работе используемых им программ. Его студенты запустили первые фаззеры в 1989 году и обнаружили, что примерно треть целевых утилит UNIX выдавали сбои или зависали. Фаззинг-тестирование — это тестирование программного обеспечения техника, и это один из видов Тестирование безопасности.

На приведенной ниже диаграмме показан базовый цикл фаззинга, в котором сгенерированные данные передаются в тестируемое приложение, а затем наблюдается ответ.

Процесс фаззинг-тестирования: фаззер генерирует некорректные входные данные и передает их тестируемому приложению.

Зачем проводить фазз-тестирование?

Фаззинг заслуживает места в плане тестирования, потому что он исследует входные данные, для которых никто не подумал написать тестовый пример. Основные причины, по которым команды его внедряют, перечислены ниже.

  • Фаззинг-тестирование обычно выявляет наиболее серьезные уязвимости и дефекты безопасности, поскольку сбой является прямым доказательством необработанного пути ввода.
  • Фазз-тестирование дает более эффективный результат при использовании в сочетании с Цвет - Черный. Box Тестирование, бета-тестирование и другие методы отладки.
  • Фаззинг-тестирование используется для проверки уязвимости программного обеспечения и является очень экономичным методом тестирования, поскольку входные данные генерируются, а не пишутся вручную.
  • Фаззинг — это один из методов тестирования «чёрного ящика». Фаззинг также является одним из наиболее распространённых способов, используемых хакерами для поиска уязвимостей в системе, поэтому его запуск в первую очередь устраняет самый простой путь проникновения для злоумышленника.

Виды фазз-тестирования

Фаззеры обычно классифицируются по тому, насколько хорошо они знают атакуемую программу. Чем больше информации знает фаззер, тем глубже он может проникнуть в код.

Тип Что знает фаззер Типичное использование
Фаззинг черного ящика Ничего не известно о внутреннем устройстве; оно видит только входные и выходные сигналы. Quick Smoke запускает тестирование на основе бинарного файла или работающей конечной точки.
фаззинг белого ящика Полный исходный код, часто в сочетании с символическим выполнением для решения задач, требующих доступа к труднодоступным веткам. Углубленный анализ компонента, исходный код которого доступен.
Фаззинг серого ящика Отсутствует проверка исходного кода, но есть обратная связь во время выполнения, например, о том, до каких ветвей кода дошли входные данные. Это значение по умолчанию для современных движков, таких как AFL++ и libFuzzer.

Второе, более раннее разделение приводит к еще одному расколу. глупое размытие от умное фаззинг«Простой» фаззер переворачивает биты, не имея представления о формате входных данных, поэтому большая часть его данных отклоняется первым же встреченным парсером. «Умный» фаззер понимает контрольные суммы, поля длины и структуру сообщений, поэтому его входные данные проходят проверку и попадают в базовую логику. Фаззинг с учетом покрытия Это усовершенствованная версия «серого ящика», которая сделала фаззинг популярным: движок инструментирует бинарный файл, сохраняет любые входные данные, которые достигают новой ветви, и мутирует оставшиеся, так что корпус неуклонно развивается в сторону неисследованного кода, а не перезапускается со случайного шума.

Как проводить фазз-тестирование

Этапы фазз-тестирования включают в себя основные этапы тестирования:

Шаг 1) Определите целевую систему — Выберите исполняемый файл, библиотеку, службу или конечную точку протокола, которая будет атакована, и подтвердите, что вам разрешено ее тестировать.

Шаг 2) Определите входные данные — перечислить все точки входа, из которых целевое устройство считывает данные: файлы, аргументы командной строки, переменные среды, сетевые пакеты, поля форм и полезные нагрузки API.

Шаг 3) Создайте нечеткие данные — создавать некорректные входные данные путем модификации допустимых образцов, генерации их из модели формата или путем комбинирования обоих способов.

Шаг 4) Выполните тест, используя нечеткие данные. — Запустить целевую систему на основе сгенерированных входных данных, в идеале в цикле, который автоматически перезапускает процесс после каждой ошибки.

Шаг 5) Мониторинг поведения системы — Следите за сбоями, зависаниями, ошибками утверждения, чрезмерным использованием памяти и отчетами санитарной обработки, а не только проверяйте выводимые данные.

Шаг 6) Зарегистрируйте дефекты — Сохраните точные входные данные, которые вызвали каждую ошибку, сократите их до наименьшего воспроизводимого случая и сохраните в стеке. trace прилагается.

Примеры фаззеров

Фаззеры также классифицируются по способу формирования входных данных, и три подхода, описанные ниже, — это те, с которыми вы будете сталкиваться чаще всего.

  • Фаззеры на основе мутаций Изменяйте существующие образцы данных, чтобы создать новые тестовые данные. Это очень простой и понятный подход: он начинается с допустимых образцов протокола и продолжает изменять каждый байт или файл.
  • Фаззеры на основе поколений Определяют новые данные на основе входных данных модели. Они начинают генерировать входные данные с нуля в соответствии со спецификацией.
  • Фаззеры на основе протоколов Это зависит от детального знания формата тестируемого протокола, и это понимание исходит из спецификации. Процесс включает в себя запись массива спецификации в инструмент, а затем использование метода генерации тестов на основе моделей для проверки спецификации и добавления нерегулярностей в содержимое данных, последовательность и так далее. Это также известно как синтаксическое тестирование, грамматическое тестирование или тестирование на устойчивость. Фаззер может генерировать тестовые примеры на основе существующих или использовать допустимые или недопустимые входные данные.

Существует два ограничения фаззинга на основе протоколов:

  1. Тестирование не может продолжаться до тех пор, пока спецификация не станет зрелой.
  2. Многие полезные протоколы являются расширением опубликованных протоколов. Если фазз-тестирование основано на опубликованных спецификациях, Тестирование для новых протоколов будет ограничено.

Простейший метод фаззинга — это отправка случайных входных данных программному обеспечению либо в виде протокольных пакетов, либо в виде события. Этот метод передачи случайных входных данных очень эффективен для поиска ошибок во многих приложениях и сервисах. Существуют и другие методы, которые очень легко реализовать. Для их реализации достаточно изменить существующие входные данные, а изменить входные данные можно просто поменяв местами их биты.

Типы ошибок, обнаруженных с помощью Fuzz Testing

Поскольку фаззинг оценивает выполнение программы по тому, как она себя ведёт, а не по ожидаемому значению, выявляемые им дефекты группируются в три группы.

  • Сбои в утверждениях и утечки памяти: Эта методология широко используется в крупных приложениях, где ошибки влияют на безопасность памяти, что является серьезной уязвимостью. Buffer Здесь отображаются переполнения, использование освобожденной памяти и чтение за пределы допустимого диапазона.
  • Неверный ввод: В фаззинг-тестировании фаззеры используются для генерации недопустимых входных данных, которые затем используются для проверки процедур обработки ошибок, что важно для программного обеспечения, не контролирующего свои входные данные. Простой фаззинг можно рассматривать как способ автоматизации. отрицательный тест.
  • Ошибки корректности: Фаззинг также может использоваться для обнаружения некоторых типов ошибок «корректности», таких как поврежденная база данных или некачественные результаты поиска. Дифференциальный фаззинг, при котором один и тот же входной сигнал подается на две реализации и сравниваются ответы, является обычным способом обнаружения таких ошибок.

Инструменты нечеткого тестирования

Инструменты, используемые в веб-безопасности, могут широко применяться в фаззинг-тестировании, например: Burp Suite и Peach Fuzzer. Некоторые из перечисленных ниже классических названий в настоящее время находятся в архиве, поэтому их текущий статус указан рядом с каждой записью.

  • Персиковый фаззерPeach Fuzzer обеспечивает более надежное покрытие безопасности, чем сканер. Другие инструменты тестирования могут искать только известные угрозы, тогда как Peach Fuzzer позволяет пользователям находить как известные, так и неизвестные угрозы. Компания Peach Tech была приобретена GitLab, и Community Edition v3 больше не поддерживается; поддерживаемой версией является... GitLab Protocol Fuzzer Community Edition.
  • Спайк ПроксиSPIKE Proxy — это профессиональный инструмент для поиска уязвимостей на уровне приложений в веб-приложениях. Он охватывает основные функции, такие как: SQL Внедрение вредоносного ПО и межсайтовый скриптинг на полностью открытой платформе. Python инфраструктура, и она была доступна для Linux и WindowsОно не ремонтировалось много лет и включено сюда для исторического контекста.
  • ВебСкарабWebScarab написан на Java и, следовательно, является переносимым на многие платформы. Фреймворк WebScarab взаимодействует с использованием протоколов HTTP и HTTPS и работает как перехватывающий прокси: он позволяет оператору просматривать и изменять запросы, созданные браузером, до того, как их получит сервер, а также просматривать и обновлять ответы, сгенерированные сервером, до того, как их получит браузер. Любая обнаруженная WebScarab уязвимость добавляется в список зарегистрированных проблем. Репозиторий был заархивирован в апреле 2024 года и теперь доступен только для чтения.
  • OWASP WSFuzzerWSFuzzer — это программа, распространяемая по лицензии GPL и написанная на языке программирования. Python Эта система была ориентирована на веб-сервисы, а в последней версии — на протокол HTTP. SOAP сервисы были главной целью. Он поставлялся в составе WebScarab и был снят с производства вместе с ним; OWASP ZAP и его дополнение Fuzzer являются рекомендуемой заменой.
  • Сохраненные альтернативы: AFL++ и libFuzzer являются стандартными механизмами анализа покрытия кода для нативного кода. ОСС-Fuzz запускает их непрерывно и бесплатно для проектов с открытым исходным кодом, и буфузз рассматривает фаззинг сетевых протоколов в PythonБолее полный список собран в руководстве по... инструменты тестирования безопасности.

Фазз-тестирование: лучшие практики

Фаззер, направленный на цель и оставленный без присмотра, редко что-либо обнаруживает. Приведенные ниже методы позволяют отличить кампанию, которая приводит к появлению зарегистрированных дефектов, от кампании, которая только расходует процессорное время.

  • Начните с хорошего исходного корпуса. Собирайте реальные, допустимые входные данные, которые приложение уже принимает. Изменение подлинного файла достигает кода парсинга гораздо быстрее, чем изменение случайных байтов.
  • Сформируйте небольшую, быстросъемную упряжь. Точка входа должна выполнять только одно действие за один запуск, избегать сетевых запросов и записи на диск и быстро возвращать результат, поскольку пропускная способность измеряется количеством выполнений в секунду.
  • Включите дезинфицирующие средства. Скрытое повреждение памяти часто не приводит к сбою. AddressSanitizer и UndefinedBehaviorSanitizer преобразуют его в немедленную, диагностируемую ошибку.
  • Беги долго и беги непрерывно. Одно- или двухчасовой запуск выявляет поверхностные ошибки; для поиска глубоких путей обычно требуется много часов, поэтому фаззинг следует включать в ночную задачу CI, а не выполнять вручную.
  • Сведите к минимуму и устраните дублирование всех сбоев. Уменьшите размер некорректного входного сигнала до его наименьшей формы и сгруппируйте сбои по стеку. tracВ противном случае, одна ошибка может выражаться в виде сотен заявок.
  • Сохраните регрессионный корпус. Добавьте каждый воспроизводимый входной параметр в постоянный набор, который запускается при каждой сборке, чтобы исправленный дефект не мог незаметно вернуться.
  • Определите целевую аудиторию в соответствии с законом. Фаззинг работающего стороннего сервиса без письменного разрешения неотличим от атаки.

Преимущества нечеткого тестирования

При реалистичном подходе фаззинг обеспечивает преимущества, которые другим методам сложно обеспечить.

  • Фаззинг-тестирование повышает эффективность тестирования безопасности программного обеспечения.
  • Обнаруженные при фаззинге ошибки иногда бывают серьезными и часто совпадают с ошибками, используемыми злоумышленниками, включая сбои, утечки памяти и необработанные исключения.
  • Если тестировщики не смогли обнаружить какие-либо ошибки из-за нехватки времени и ресурсов, эти ошибки также выявляются в ходе фаззинг-тестирования.
  • Входные данные генерируются машиной, поэтому охват продолжает расти в течение ночи без дополнительных ручных усилий.

Недостатки фазз-тестирования

Те же самые свойства, которые делают фаззинг дешевым, также ограничивают то, что он может доказать.

  • Одного лишь фаззинг-тестирования недостаточно для получения полной картины общей угрозы безопасности или набора уязвимостей.
  • Фаззинг-тестирование менее эффективно при борьбе с угрозами безопасности, которые не приводят к сбоям программы, такими как некоторые вирусы, черви и трояны.
  • Фаззинг-тестирование способно выявлять только относительно простые ошибки или угрозы и не позволяет анализировать бизнес-логику.
  • Для эффективной работы требуется значительное машинное время.
  • Задание граничного условия с использованием случайных входных данных представляет собой очень сложную задачу, хотя в настоящее время тестировщики решают большую часть этой проблемы с помощью детерминированных алгоритмов, управляемых пользовательскими данными.

Фаззинг-тестирование против тестирования на проникновение

Оба метода направлены на выявление уязвимостей в системе безопасности, однако они отвечают на разные вопросы и редко взаимозаменяемы.

Критерии Fuzz-тестирование Тестирование на проникновение
Которую вел Автоматизированный механизм, генерирующий некорректные входные данные. Опытный тестировщик, рассуждающий о системе.
Ищет Сбои, зависания и ошибки безопасности памяти. Уязвимости, которыми можно воспользоваться, включая логические ошибки и ошибки конфигурации.
глубина Очень широкий охват входных данных, поверхностные рассуждения. Узкий охват, глубокая аргументация
Результат Воспроизведение входных данных и стека traces Отчет о результатах расследования с описанием путей эксплуатации уязвимостей и оценкой рисков.
Лучший момент Непрерывно, в конвейере сборки. Периодически, в отношении кандидата на релиз

На практике эти два подхода взаимно дополняют друг друга: фаззинг устраняет дешевые, автоматизируемые сбои, позволяя тестировщику потратить ограниченное количество времени на выявление недостатков, которые сможет обнаружить только человек.

Часто задаваемые вопросы (FAQ)

Начальный корпус — это набор допустимых входных данных, которые фаззер обрабатывает. Лучше всего подходят небольшие, разнообразные, реальные файлы, поскольку каждый из них уже проходит проверку парсером, что позволяет движку потратить свои ресурсы на более глубокий код, а не на первую проверку на допустимость.

Фазз-тестовая платформа — это небольшая функция, которая передает тестируемому коду один буфер фаззированных байтов. Она должна избегать операций с глобальным состоянием, записи в файлы и сетевых вызовов, чтобы движок мог запускать её тысячи раз в секунду.

Час-два выявляют поверхностные ошибки. Серьезные кампании длятся много часов или дней, потому что новые данные поступают порциями. Плато на кривой охвата, а не показания таймера, является честным сигналом того, что кампания перестала приносить результаты.

AddressSanitizer перехватывает переполнения буфера и использование памяти после освобождения, UndefinedBehaviorSanitizer перехватывает некорректное использование целых чисел и указателей, а MemorySanitizer перехватывает чтение неинициализированной памяти. Без них многие ошибки остаются незамеченными, и фаззер вообще не сообщает о сбоях.

Воспроизведите ошибку, сведите входные данные к наименьшему случаю сбоя, сгруппируйте их с ошибками, имеющими тот же стек вызовов. tracзатем подайте заявку через обычный интерфейс. процесс управления дефектами и добавить эти входные данные в корпус регрессионных моделей.

Их объединяет случайность, но не намерение. Обезьяна тестирование Фаззинг, в свою очередь, запускает произвольные действия пользователя в работающем интерфейсе, а фаззинг нацелен на конкретный парсер входных данных и измеряет покрытие кода, что позволяет ему направлять себя к коду, до которого предыдущие входные данные так и не дошли.

Языковые модели используются для разработки тестовых сценариев для нефаззинговых API, для синтеза начальных входных данных для экзотических форматов, а также для кластеризации и обобщения отчетов о сбоях. Система по-прежнему предоставляет обратную связь по покрытию кода; модель в основном исключает необходимость ручной настройки.

Второй пилот GitHub может сформировать точку входа libFuzzer, файл сборки и генератор начальных значений на основе существующей сигнатуры API. RevВнимательно изучите результат, поскольку жгут проводов, который незаметно подавляет ошибки, не сообщит о сбоях.

Подведем итог этой публикации следующим образом: