Фазинг

редактировать

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

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

СОДЕРЖАНИЕ

  • 1 История
  • 2 Раннее случайное тестирование
  • 3 Типы
    • 3.1 Повторное использование существующих исходных данных
    • 3.2 Знание структуры ввода
    • 3.3 Знание структуры программы
  • 4 использования
    • 4.1 Выявление ошибок
    • 4.2 Проверка отчетов статического анализа
    • 4.3 Безопасность браузера
  • 5 Цепочка инструментов
    • 5.1 Автоматическая сортировка ошибок
    • 5.2 Автоматическая минимизация ввода
  • 6 См. Также
  • 7 ссылки
  • 8 Дальнейшее чтение
  • 9 Внешние ссылки

История

Термин «пуха» берет свое начало от проекта класса осенью 1988 года в аспирантуре классе Advanced операционных систем (CS736), преподавал профессор Бартон Миллер из Университета штата Висконсин, результаты которого впоследствии были опубликованы в 1990 году Для тестирования пуха UNIX утилита означает для автоматической генерации случайного ввода и параметров командной строки для утилиты. Проект был разработан для проверки надежности программ командной строки UNIX путем быстрого выполнения большого количества случайных входных данных, пока они не вылетели. Команде Миллера удалось вывести из строя от 25 до 33 процентов тестируемых утилит. Затем они отладили каждый сбой, чтобы определить причину, и классифицировали каждый обнаруженный сбой. Чтобы другие исследователи могли проводить аналогичные эксперименты с другим программным обеспечением, исходный код инструментов, процедуры тестирования и необработанные данные о результатах были обнародованы. Этот ранний фаззинг теперь будет называться черным ящиком, неструктурированным (тупым) фаззингом поколений.

В этой нечеткой статье 1990 года также отмечалось отношение надежности к безопасности: «Во-вторых, одна из обнаруженных нами ошибок была вызвана той же самой практикой программирования, которая предоставила одну из дыр в безопасности Интернет-червю (ошибка« получает палец »). Мы обнаружили дополнительные ошибки, которые могут указывать на будущие бреши в безопасности ». (Имеется в виду червь Морриса, ноябрь 1988 г.)

Первоначальный проект Fuzz внес свой вклад в 1995, 2000, 2006 и последний раз в 2020 году:

  • 1995: «Пересмотренный вопрос» состоял из четырех частей. (1) Воспроизведено исходное исследование командной строки, включая более широкий спектр систем UNIX и больше утилит. Исследование показало, что надежность даже ухудшилась. Это было первое исследование, в которое были включены утилиты GNU и Linux с открытым исходным кодом, которые, что интересно, были значительно более надежными, чем утилит из коммерческих систем UNIX. (2) Введено нечеткое тестирование графических (оконных) приложений под X-Windows. В этом исследовании использовались как неструктурированные, так и структурированные (допустимые последовательности событий мыши и клавиатуры) входные данные. Им удалось вывести из строя 25% приложений X-Windows. Кроме того, они протестировали сервер X-Windows и показали, что он устойчив к сбоям. (3) Введено нечеткое тестирование сетевых сервисов, опять же на основе структурированных тестовых входных данных. Ни одна из этих служб не вышла из строя. (4) Введено случайное тестирование возвращаемых значений вызовов системной библиотеки, в частности случайное возвращение нуля из семейства функций malloc. Почти половина стандартных программ UNIX не могла должным образом проверить такие возвращаемые значения.
  • 2000: Прикладное нечеткое тестирование к недавно выпущенной операционной системе Windows NT, тестирование приложений, работающих в оконной системе Win32. Им удалось вывести из строя 21% приложений и зависнуть еще 24% протестированных. И снова приложения тестировались как с неструктурированным, так и с структурированным вводом (допустимые события клавиатуры и мыши), что привело к сбою почти половины тестируемых приложений. Они определили причины сбоев и пришли к выводу, что они аналогичны предыдущим исследованиям.
  • 2006: Прикладное тестирование фаззинга в Mac OS X как для командной строки, так и для оконных приложений. Они протестировали 135 служебных программ командной строки, что привело к аварийному завершению работы 7% из протестированных. Кроме того, они протестировали 30 приложений, работающих под оконной системой MacOS Aqua, потеряв 73% из протестированных.
  • 2020: Совсем недавно они применили классическое тестирование поколений, «черный ящик», неструктурированное тестирование к текущим системам UNIX, особенно Linux, FreeBSD и MacOS, чтобы убедиться, что оригинальные методы по-прежнему актуальны и устойчивы ли текущие служебные программы к такому типу тестирования. Они протестировали примерно 75 утилит на каждой платформе, с частотой отказов 12% в Linux, 16% в MacOS и 19% в FreeBSD. (Обратите внимание, что эти показатели отказов были хуже, чем результаты более раннего тестирования тех же систем.) Когда они проанализировали каждый отказ и классифицировали его, они обнаружили, что классические категории отказов, такие как ошибки указателя и массива и отсутствие проверки кодов возврата, все еще широко присутствовали в новых результатах. Кроме того, новые причины отказа возникают из-за сложного состояния программы и алгоритмов, которые не масштабируются с размером или сложностью ввода. Они также протестировали утилиты UNIX, написанные совсем недавно на Rust, и обнаружили, что они имеют такую ​​же надежность, что и написанные на C, хотя (как и ожидалось) с меньшей вероятностью будут иметь ошибки памяти.

В апреле 2012 года Google анонсировал ClusterFuzz, облачную инфраструктуру фаззинга для критически важных для безопасности компонентов веб-браузера Chromium. Исследователи безопасности могут загружать свои собственные фаззеры и собирать вознаграждения за ошибки, если ClusterFuzz обнаруживает сбой с загруженным фаззером.

В сентябре 2014 года Shellshock было обнаружено как семейство ошибок безопасности в широко используемой оболочке UNIX Bash ; большинство уязвимостей Shellshock было обнаружено с помощью фаззера AFL. (Многие службы с выходом в Интернет, такие как некоторые развертывания веб-серверов, используют Bash для обработки определенных запросов, что позволяет злоумышленнику заставить уязвимые версии Bash выполнять произвольные команды. Это может позволить злоумышленнику получить несанкционированный доступ к компьютерной системе.)

В апреле 2015 года Ханно Бёк показал, как фаззер AFL мог обнаружить уязвимость Heartbleed 2014 года. ( Уязвимость Heartbleed была раскрыта в апреле 2014 года. Это серьезная уязвимость, которая позволяет злоумышленникам расшифровать зашифрованные сообщения. Уязвимость была случайно внесена в OpenSSL, который реализует TLS и используется большинством серверов в Интернете. Shodan сообщил о 238 000 машины по-прежнему уязвимы в апреле 2016 г.; 200 000 в январе 2017 г.)

В августе 2016 года Агентство перспективных оборонных исследовательских проектов (DARPA) провело финал первого Cyber ​​Grand Challenge, полностью автоматизированного соревнования по захвату флага, которое длилось 11 часов. Задача заключалась в разработке систем автоматической защиты, которые могут обнаруживать, использовать и исправлять недостатки программного обеспечения в режиме реального времени. Фаззинг использовался как эффективная стратегия нападения для обнаружения недостатков в программном обеспечении оппонентов. Он показал огромный потенциал в автоматизации обнаружения уязвимостей. Победителем стала система Mayhem, разработанная командой ForAllSecure во главе с Дэвидом Брамли.

В сентябре 2016 года Microsoft анонсировала Project Springfield, облачный сервис нечеткого тестирования для поиска критических с точки зрения безопасности ошибок в программном обеспечении.

В декабре 2016 года Google анонсировал OSS-Fuzz, который позволяет непрерывно выполнять фаззинг нескольких критически важных для безопасности проектов с открытым исходным кодом.

На Black Hat 2018 Кристофер Домас продемонстрировал использование фаззинга, чтобы выявить наличие скрытого ядра RISC в процессоре. Это ядро ​​могло обойти существующие проверки безопасности для выполнения команд Ring 0 из Ring 3.

В сентябре 2020 года Microsoft выпустила OneFuzz, автономную платформу фаззинга как услуги, которая автоматизирует обнаружение ошибок программного обеспечения. Он поддерживает Windows и Linux.

Раннее случайное тестирование

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

Выполнение случайных входных данных также называется случайным тестированием или тестированием на обезьянах.

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

В 1983 году Стив Кэппс из Apple разработал «The Monkey», инструмент, который генерировал случайные входные данные для классических приложений Mac OS, таких как MacPaint. Образное «обезьяна» относится к теореме о бесконечной обезьяне, которая гласит, что обезьяна, нажимающая произвольно клавиши на клавиатуре пишущей машинки в течение бесконечного количества времени, в конечном итоге напечатает все произведения Шекспира. В случае тестирования обезьяна напишет конкретную последовательность входных данных, которая вызовет сбой.

В 1991 году был выпущен инструмент crashme, предназначенный для проверки устойчивости Unix и Unix-подобных операционных систем путем случайного выполнения системных вызовов со случайно выбранными параметрами.

Типы

Фаззер можно разделить на несколько категорий:

  1. Фаззер может быть основан на генерации или на мутации, в зависимости от того, генерируются ли входные данные с нуля или путем изменения существующих входных данных.
  2. Фаззер может быть глупым (неструктурированным) или интеллектуальным (структурированным) в зависимости от того, знает ли он о структуре ввода.
  3. Фаззер может быть белого, серого или черного ящика, в зависимости от того, осведомлен ли он о структуре программы.

Повторное использование существующих исходных данных

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

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

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

Зная о структуре ввода

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

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

Тупой фаззер не требует входной модели и, таким образом, может использоваться для фаззинга большего количества программ. Например, AFL - это фаззер, основанный на бессмысленных мутациях, который изменяет исходный файл, переворачивая случайные биты, заменяя случайные байты «интересными» значениями и перемещая или удаляя блоки данных. Однако глупый фаззер может генерировать меньшую долю действительных входных данных и подвергать нагрузку код синтаксического анализатора, а не основные компоненты программы. Недостаток «глупых фаззеров» можно проиллюстрировать с помощью построения действительной контрольной суммы для проверки циклическим избыточным кодом (CRC). CRC - это код обнаружения ошибок, который гарантирует, что целостность данных, содержащихся во входном файле, сохраняется во время передачи. Контрольная сумма вычисляется по входным данным и записывается в файл. Когда программа обрабатывает полученный файл и записанная контрольная сумма не совпадает с пересчитанной контрольной суммой, файл отклоняется как недействительный. Теперь фаззер, не знающий о CRC, вряд ли сгенерирует правильную контрольную сумму. Однако предпринимаются попытки идентифицировать и пересчитать потенциальную контрольную сумму в измененном вводе после того, как тупой фаззер, основанный на мутации, изменил защищенные данные.

Зная структуру программы

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

Черный ящик fuzzer обрабатывает программу как черный ящик и не знает о внутренней структуре программы. Например, инструмент случайного тестирования, который генерирует случайные входные данные, считается фаззером черного ящика. Следовательно, фаззер черного ящика может выполнять несколько сотен вводов в секунду, может быть легко распараллелен и может масштабироваться до программ произвольного размера. Однако фаззеры черного ящика могут лишь поцарапать поверхность и выявить «мелкие» ошибки. Следовательно, есть попытки разработать фаззеры черного ящика, которые могут постепенно узнавать о внутренней структуре (и поведении) программы во время фаззинга, наблюдая за выходом программы на входе. Например, LearnLib использует активное обучение для создания автомата, который представляет поведение веб-приложения.

Белого ящик fuzzer рычаги анализ программ для систематического увеличения охвата кода или достичь определенных мест критических программ. Например, SAGE использует символическое выполнение для систематического исследования различных путей в программе. Если спецификация программы доступна, фаззер белого ящика может использовать методы тестирования на основе моделей для генерации входных данных и проверки выходных данных программы на соответствие спецификации программы. Фаззер белого ящика может быть очень эффективным для выявления ошибок, которые прячутся глубоко в программе. Однако время, затрачиваемое на анализ (программы или ее спецификации), может стать непомерно высоким. Если фаззеру белого ящика требуется относительно слишком много времени для генерации входных данных, фаззер черного ящика будет более эффективным. Следовательно, есть попытки объединить эффективность фаззеров черного ящика и эффективность фаззеров белого ящика.

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

Использует

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

Выявление ошибок

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

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

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

Фаззинг также можно использовать для обнаружения «дифференциальных» ошибок, если доступна эталонная реализация. Для автоматического регрессионного тестирования сгенерированные входные данные выполняются в двух версиях одной и той же программы. Для автоматического дифференциального тестирования сгенерированные входные данные выполняются в двух реализациях одной и той же программы (например, lighttpd и httpd являются реализациями веб-сервера). Если два варианта дают разные выходные данные для одного и того же входа, то в одном из них может быть ошибка, и его следует изучить более внимательно.

Проверка отчетов статического анализа

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

Безопасность браузера

Современные веб-браузеры подвергаются обширному фаззингу. Код Chromium в Google Chrome постоянно обновляется командой безопасности Chrome с 15 000 ядрами. Для Microsoft Краю и Internet Explorer, Microsoft выполняется fuzzed тестирование с 670 машино-лет в процессе разработки продукта, создавая более 400 млрд DOM манипуляции с 1 млрд HTML файлов.

Цепочка инструментов

Фаззер производит большое количество входных данных за относительно короткое время. Например, в 2016 году проект Google OSS-fuzz производил около 4 триллионов входных данных в неделю. Следовательно, многие фаззеры предоставляют набор инструментов, который автоматизирует ручные и утомительные задачи, которые следуют за автоматическим генерированием вызывающих сбой входных данных.

Автоматическая сортировка ошибок

Основная статья: Сортировка ошибок

Автоматическая сортировка ошибок используется для группировки большого количества входных данных, приводящих к сбоям, по основной причине и для определения приоритета каждой отдельной ошибки по серьезности. Фаззер производит большое количество входных данных, и многие из них, приводящие к сбою, могут эффективно выявить одну и ту же программную ошибку. Только некоторые из этих ошибок критичны с точки зрения безопасности и должны исправляться с более высоким приоритетом. Например, координационный центр CERT предоставляет инструменты сортировки Linux, которые группируют аварийные входные данные по произведенной трассировке стека и перечисляют каждую группу в соответствии с их вероятностью использования. Исследовательский центр безопасности Microsoft (MSEC) разработал инструмент! Exploitable, который сначала создает хэш для сбойного ввода, чтобы определить его уникальность, а затем присваивает рейтинг уязвимости:

  • Пригодный для использования
  • Возможно использование
  • Вероятно, не может быть использован, или
  • Неизвестный.

Ранее сообщалось, ошибки могут отбирали раненый автоматически сообщается в систему отслеживания ошибки. Например, OSS-Fuzz проводит крупномасштабные, длительные кампании по фаззингу для нескольких критически важных с точки зрения безопасности программных проектов, где каждая отдельная ошибка, о которой ранее не сообщалось, сообщается непосредственно в систему отслеживания ошибок. Ошибка трекер ОССА-Fuzz автоматически информирует сопровождающий уязвимое программное обеспечения и проверки в регулярных промежутках времени, была ли ошибка была исправлена в самой последней редакции с использованием закачанного свернутого отказом индуцирующего входа.

Автоматическая минимизация ввода

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

Смотрите также

использованная литература

дальнейшее чтение

внешние ссылки

Последняя правка сделана 2023-03-21 10:42:13
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте