Содержание статьи
info
О фаззинге методом черного ящика читай в статье «WinAFL на практике. Учимся работать фаззером и искать дыры в софте».
Суть фаззинга заключается в том, чтобы автоматически подавать программе неправильные или испорченные данные и отлавливать потенциальные уязвимости.
На свете существует множество фаззеров: AFL++, libfuzz, WinAFL, CI Fuzz, PeachTech Peach Fuzzer, FuzzDB, go-fuzz и прочие, в том числе самописные. Фаззеры применимы не только для программ, но и для сайтов. Например, wfuzz — это веб‑фаззер, который нужен, чтобы вводить любые данные в любое поле HTTP-запроса.
В этой статье идет речь о фаззинге программ. Нашим инструментом будет AFL++ — фаззер, ориентированный на покрытие. Это значит, что он собирает информацию о покрытии для каждого измененного входа, чтобы обнаружить новые пути выполнения и потенциальные ошибки. Если у тебя есть исходник программы, AFL может вставлять вызовы функций в начало каждого базового блока, например в функции и циклы.
О том, как при помощи AFL тестировать блекбоксы, написано множество статей, в том числе о том, как его распараллеливать. Но этот фаззер умеет компилировать программы и делать свои вставки в код, что облегчает фаззинг. Такие вставки называются санитайзерами.
warning
Статья имеет ознакомительный характер и предназначена для специалистов по безопасности, проводящих тестирование в рамках контракта. Автор и редакция не несут ответственности за любой вред, причиненный с применением изложенной информации. Распространение вредоносных программ, нарушение работы систем и нарушение тайны переписки преследуются по закону.
Что такое санитайзеры?
Санитайзеры — это утилиты, которые обычно поставляются вместе с компиляторами. Они помогают искать ошибки в коде во время исполнения. Если обобщить, можно выделить три разновидности санитайзеров:
- address — ищет ошибки работы с памятью;
- thread — ищет проблемы в многопоточных вычислениях (состояние гонки);
- undefined — ищет неопределенное поведение в программе.
Использование санитайзеров вместе с AFL++ — это хороший тон при фаззинге, потому что с ними фаззер будет лучше знать, какого рода ошибки ему нужно искать. С санитайзерами фаззинг всегда будет проходить успешнее, чем без них.
В AFL++ доступны разные санитайзеры, которые помогают обнаруживать ошибки в коде. Вот краткое описание каждого из них.
- AddressSanitizer (ASAN) предназначен для обнаружения ошибок чтения или записи в память, таких как переполнение буфера или использование освобожденной памяти. Он обеспечивает детальную информацию об ошибках и помогает в их отладке.
- MemorySanitizer (MSAN) призван обнаружить неинициализированную память. Он помогает выявить ошибки, связанные с использованием неинициализированных данных и способные привести к непредсказуемому поведению программы.
- ThreadSanitizer (TSAN) предназначен для поиска гонок данных в многопоточных программах. Он помогает выявить ситуации, когда несколько потоков одновременно обращаются к одним и тем же данным, что иногда приводит к непредсказуемым результатам.
- UndefinedBehaviorSanitizer (UBSAN) помогает обнаружить неопределенное поведение в программе, такое как деление на ноль, переполнение целочисленных типов или неправильное использование указателей. Он предупреждает о таких проблемах и помогает предотвратить возможные ошибки.
- Control Flow Integrity (CFI) обеспечивает защиту от атак, связанных с изменением потока управления программы. Он проверяет целостность вызовов функций и предотвращает нежелательные изменения потока выполнения.
- Safe-stack предназначен для защиты от переполнения стека. Он обеспечивает дополнительные механизмы безопасности, чтобы предотвратить возможные атаки, связанные с переполнением стека.
В разных случаях могут пригодиться разные санитайзеры, в том числе это зависит от особенностей и требований проекта.
Например, санитайзер ASAN может выявить следующие проблемы:
- Use-After-Free — использование чанка кучи после его освобождения;
- HeapOverflow — переполнение одного чанка и добавление данных в другой чанк;
- StackOverflow — классическое переполнение буфера.
info
Подробнее о возможностях ASAN читай в документации на GitHub.
Теневая память
Одна из техник, которую используют санитайзеры, — это теневая память. По сути, они поддерживают параллельную структуру данных наряду с фактической памятью программы, при этом каждый бит в теневой памяти соответствует 8 битам в фактической памяти. Такая схема позволяет хранить метаданные о каждом выделении памяти и обнаруживать нарушения при записи в нее.
Например, в программе определяется какой‑то указатель:
*address = ...; // or: ... = *address;
Санитайзер меняет его использование на такое:
if (IsPoisoned(address)) { ReportError(address, kAccessSize, kIsWrite);}*address = ...; // or: ... = *address;
Санитайзер помечает любую высвобождаемую память как «отравленную», а затем следит за доступом к ней. Если произошло переполнение буфера, который выделялся через malloc
, то получается, что кто‑то пишет в отравленную область, а в эту область писать нельзя. Так фаззер обнаруживает баг.
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»