Содержание статьи
Пара слов о фаззинге
Прежде чем разбираться с сетевыми протоколами и, тем более, писать код, поговорим о фаззинге в целом.
Фаззинг — одна из техник автоматизированного тестирования, при которой цели (программе, протоколу, сервису и так далее) подаются на вход искаженные, неправильные, неожиданные или даже случайные данные в попытке сломать программу.
Почему именно такие данные? Все очень просто: программисты нечасто продумывают «неправильные» сценарии использования программ, полагаясь на то, что пользователь будет действовать разумно. Программе же все равно: что было написано, то и будет исполнено.
В результате слишком длинная строка, пустое поле или несовместимые параметры могут привести к вполне реальным сбоям в работе, которые могут не только нарушить логику исполнения, но и открыть доступ к возможностям, которых быть не должно (если ты понимаешь, о чем я).
info
Как‑то мне задали занятный вопрос: в чем принципиальное отличие фаззинга от брутфорса (ведь и тот и другой отправляют кучу данных в попытке получить несанкционированный доступ)? Ответ на него лежал на поверхности: брутфорс перебирает по словарю в попытке легитимно (честно) пройти авторизацию, а фаззинг — это именно поиск уязвимости.
Для чего используют фаззинг?
На данный момент для следующих задач:
- Поиск уязвимостей — самый очевидный вариант. Большинство багов сегодня (особенно с учетом разрастающейся кодовой базы серьезных проектов) находятся именно с помощью фаззеров.
- Стресс‑тесты — неожиданно, но крайне приятно бывает знать, что твой условный сервер WebDAV не упадет после первого пустого запроса от curl.
- Обнаружение не критичных, но неприятных багов — согласись, мало радости, если твой сайт станет падать после какого‑нибудь «неправильного» запроса.
Виды фаззинга
Естественно, если есть разные задачи, то решают их разными видами фаззинга. Их разделяют в зависимости от способа генерации данных, полноты обратной связи и цели фаззинга.
По способам генерации данных методы фаззинга делятся на следующие виды:
- Dumb fuzzing (он же фаззинг случайными данными) — один из самых примитивных подходов: передача цели случайных значений. К сожалению, сейчас такое срабатывает редко, но, как известно, «раз в год и палка стреляет».
- Mutational fuzzing (мутационный фаззинг) — наиболее популярный на сегодняшний день подход, основанный на мутации (изменении) примеров входных данных по всему диапазону возможных значений.
- Generation-based fuzzing (генеративный фаззинг) — не самый популярный, тем не менее нужный вид, позволяющий получить наиболее полное покрытие всех допустимых состояний.
Если же делать классификацию по полноте обратной связи, то получается следующая картина:
- Greybox fuzzing (фаззинг методом серого ящика) — фаззер получает от программы обратную связь (чаще всего это покрытие кода), что позволяет умнее и быстрее находить баги.
- Blackbox fuzzing (фаззинг методом черного ящика) — иногда бывает такое, что из обратной связи есть только информация, продолжает ли цель функционировать после очередной порции данных. При отсутствии других вариантов это лучше, чем ничего.
И наконец — разделение фаззинга по целям исследования:
- Binary fuzzing (бинарный фаззинг) — в качестве цели выступает бинарный файл (программа).
- Network fuzzing (сетевой фаззинг) — то же самое, но в качестве цели — сетевой протокол.
Давай рассмотрим последние два вида поподробнее.
Бинарный фаззинг
Это, пожалуй, наиболее известный и популярный вид фаззинга. Неудивительно: благодаря своей результативности он получил огромную поддержку сообщества в виде множества инструментов и отличной документации.
Чем же бинарный фаззинг так хорош?
- У него минимальный порог входа — чтобы начать фаззинг, иногда хватает просто бинаря и парочки хороших примеров для мутаций.
- Позволяет использовать покрытие кода — чаще всего фаззер получает обратную связь от программы, что позволяет ему быстрее находить способы тестирования тех или иных участков программы.
- Работает быстро, и скорость выполнения зависит от меньшего числа переменных (что, кстати, значит и меньше задержек).
Большинство современных инструментов созданы именно для бинарного фаззинга, и именно он сформировал то, как мы представляем себе автоматизированный поиск уязвимостей.
Главные мастодонты бинарного фаззинга — это AFL и AFL++.
Вот что происходит во время их работы:
- Компиляция программы со специальными вставками‑флагами, необходимыми для измерения покрытия входа.
- Запуск цели с разными входными данными (основная часть работы).
- Сохранение данных, которые позволили открыть новые пути исполнения кода.
- Фиксация данных, при которых программа свалилась с ошибкой.
AFL++ — форк AFL, который привнес множество полезных функций. В их числе:
- интеграция лучших мутаторов;
- встроенная поддержка QEMU, Frida, Unicorn и некоторых других эмуляторов;
- фаззинг без исходников путем пересборки программы с помощью различных инструментов.
Но если бинарный фаззинг такой классный, то почему бы просто не применить его ко всем целям подряд? Например, к сетевым протоколам. Но с ними это так просто не сработает.
Сетевой фаззинг
Сетевой фаззинг — это совершенно другой мир: он обладает рядом крайне неприятных особенностей, которые делают использование привычных инструментов попросту невозможным:
- Сложность входных данных — в отличие от бинарей, где все параметры чаще всего можно описать при запуске программы, сетевой протокол требует многоступенчатого общения между клиентом и сервером.
- Необходимость правильной последовательности передачи — нужно не только организовать диалог, данные еще нужно передать в правильном порядке: инициализация → авторизация → выполнение команд.
- Меньше скорость, соединение ненадежно — мало того что скорость фаззинга замедляется (по подсчетам авторов AFL, разница может быть в сто раз!), пакеты могут теряться, что приводит к ложным срабатываниям.
- Сложность распараллеливания — если создать сто процессов одной и той же программы не проблема, то создать сеть из ста условных роутеров — та еще задача (даже если деньги не ограничены).
- Отсутствие обратной связи — чаще всего получить доступ к трейслогу программы невозможно и судить о том, смогла ли очередная порция данных сломать обработку, приходится лишь по наличию ответа от сервера, что сокращает количество потенциальных багов (и, кстати, отсылает нас к третьему пункту этого списка).
www
Кстати, если ты не знал, обработку сетевого взаимодействия чаще всего реализуют в виде конечного автомата (finite state machine), о них есть хорошая статья на «Хабрахабре».
Несмотря на все ужасы, фаззинг протоколов все же реален, и люди им занимаются. Для этого было создано несколько прекрасных инструментов:
- Peach — ранее проприетарный фаззер, впоследствии ставший опенсорсным. Сложен в использовании и перестал активно развиваться.
- Defensics — коммерческий фаззер. Не смогу о нем сказать что‑либо, так как не выпало возможности попробовать.
- AFLnet — расширение классического AFL, адаптированное под сетевые протоколы. «Из коробки» доступны некоторые популярные протоколы. Тестирование все еще происходит методом серого ящика, но в целом это выглядит как очень хороший вектор развития сетевого фаззинга.
- Sulley — по сути, прародитель всех сетевых фаззеров. Сейчас заброшен, но заложил важные концепции направления.
- Kitty — один из форков Sulley, разработанный в Cisco SAS и ориентированный на свои специфические задачи.
- Boofuzz — еще один форк Sulley, на сегодня самый популярный выбор. Именно о нем мы и будем говорить дальше.
info
Ты тоже заметил отсылку к «Корпорации монстров», увидев, как называются три последних инструмента? И не зря: тулзы действительно названы в честь персонажей из мультфильма.
Boofuzz
Для AFL особая настройка перед началом работы не нужна, а вот в случае с Boofuzz все чуть сложнее: первым делом нужно описать сам протокол и порядок сообщений, которые отправляются тестируемому серверу.
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»
