erid 2SDnje4KwUm
erid 2SDnjdR8BoP
Незаменимый фаззинг
Незаменимый фаззинг
19.04.2023

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

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

Сергей Полунин

Руководитель группы защиты инфраструктурных ИТ компании «Газинформсервис»

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

Процедура фаззинг-тестирования направлена на две цели:

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

Евгений Малкин

Руководитель направления безопасной разработки центра компетенций информационной безопасности компании «Гарда Технологии»

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

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

Три ящика

Выделяются три метода фаззинг-тестирования: белый ящик, черный ящик и серый ящик. Они отличаются доступными ресурсами тестируемого объекта.

Ангелина Разорёнова

Старший аналитик по информационной безопасности Лиги Цифровой Экономики

Метод белого ящика (White box) использует все доступные ресурсы, в том числе исходный код. Метод черного ящика (Black-box) — только вводимые данные и полученные результаты. Наиболее эффективным можно считать метод серого ящика (Gray-box), в котором помимо информации, выявленной методом черного ящика, используются итоги анализа доступного двоичного кода с помощью RCE.

Говоря об эффективном использовании фаззинга, эксперты отмечают, что при выборе вида постановка корректной задачи. Например, фаззить API web-приложения с целью поиска SQL-инъекции через whitebox фаззинг не имеет смысла, так как этот процесс займет много времени на написание кода и оберток для проверки теории. Легче и быстрее «прогнать» blackbox фаззинг с предопределенными словарями на работающем приложении для проверки на SQL-уязвимость. Но, в случае если была реализована библиотека, которая производит санитайзинг вводных данных перед отправкой в базу, то будет целесообразно проверить с помощью фаззинга кода.

Дмитрий Тишкин

Руководитель команды Application Security R-Vision

Если рассматривать black-box фаззинг, то он эффективен при поиске стандартных уязвимостей, особенно server side уязвимостей (уязвимости со стороны сервера), а также для проверки поведения приложения при вводе нестандартных символов и для проведения негативного тестирования.

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

Фаззинг на уровне кода подходит для проверки различных парсеров, санитайзеров, валидаторов на предмет их корректности. Также он позволяет найти такие ошибки, как:

  • попадание в некорректные условия;
  • бесконечные циклы;
  • обход регулярных выражений;
  • обход корректности валидированных значений;
  • переполнение буфера.

Кроме того, фаззеры разделают по цели, например, source-based, когда есть исходники проекта или binary-based, когда нет исходников проекта. Еще фаззинг можно разделить на два виду по наличию обратной реакции от тестируемого приложения – есть обратная реакция (feedback driven) или ее нет (not feedback driven). Ну и по операциям над входными данными. Генерационные, мутационные и комбинированные.

Эффективный фаззинг

Все виды фаззинга эффективны, если применять их правильно. Каждый вид решает конкретные задачи. Также эксперты отмечают, что эффективность фаззинга высока при непрерывном тестировании. Поэтому рекомендуется интегрировать фаззинг в конвейеры CI/CD. Это обеспечивает короткие циклы обратной связи и позволяет разработчикам устранять уязвимости в системе безопасности до того, как они станут проблемой.

Александр Дроздов

Инженер по SDL и информационной безопасности технологий Axiom JDK

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

Наиболее эффективный фаззинг:

  • использует отклик от тестируемой программы (критерий 1), благодаря этому мутирование образцов входных будет выполняться не "вслепую", а с учетом результатов обработки предыдущих образцов, это в свою очередь позволит достигнуть большего покрытия по строкам кода;
  • выполняется при использовании санитайзеров ошибок, что позволит обнаружить ошибки, которые не приводят к аварийному завершению работы программы, но могут быть источником серьезной проблемы вплоть до уязвимости безопасности;
  • выполняется с большой скоростью, это значительно повышает шансы что-то найти;
  • при генерации входных данных учитывает формат входных данных, это сокращает количество «холостых» итераций фаззинга (когда входные данные не проходят первый этап проверки);
  • опирается на информацию о покрытии только интересующего нас кода.

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

Плюсы и минусы

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

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

Подводные камни фаззинга варьируются в зависимости от языка программирования, на котором написан тестируемый код.

Александр Дроздов

Инженер по SDL и информационной безопасности технологий Axiom JDK

При работе с кодом на языке C/C++ могут возникать проблемы на этапе компиляции с инструментированием из-за несовместимости существующей билд системы с иструментирующим компилятором. При компоновке (линковке) в объектных/исполняемых файлах могут появляться неопределенные (undefined) символы по разным причинам – использование неподходящего набора утилит для компиляции, использование map файлов для компоновки в билд системе, установка разных уровней видимости в программном коде. Работа санитайзеров ошибок может мешать корректной работе тестируемого кода. Более общие примеры – проблемы со стабильностью из-за источников энтропии в тестируемом коде, сложности при попытке отделить тестируемый код от всего проекта при сильной связности компонентов.

Дмитрий Тишкин

Руководитель команды Application Security R-Vision

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

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

В каких случаях фаззинг не эффективен

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

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

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

Денис Исангулов

Руководитель отдела тестирования NGR Softlab

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

Использование только фаззинг-тестирования может привести к пропуску реальных ошибок или ложным срабатываниям. Нет универсального метода. Каждый подход имеет свои преимущества в зависимости от конкретных целей тестирования программы.

Вывод

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

Эксперты уверены в том, что главные правила эффективного фаззинга – это непрерывность, корректно задаче подобранный метод фаззинга и комбинирование с другими видами тестирования.


Комментарии 0