Попробовал фаззинг


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

Для фаззинга я взял несколько демонов в OpenBSD. Все демоны в OpenBSD имеют опцию -n, с которой можно проверить конфигурационный файл на корректность синтаксиса. Я составлял пример такого конфига, потом мутировал его с помощью zzuf и проверял программой в надежде, что парсер на одном из образцов данных сломается.

$ zzuf -s0:100 -r0.01 smtpd.conf
$ smtpd -n -f opensmtpd.conf

Но ни одной проблемы я тогда не нашёл.

Потом появился afl от lcamtuf и работает он гораздо эффективнее, чем zzuf. Перед сборкой программы он инструментирует её код, помечая блоки, в которых просходит ветвление. Поэтому при выполнении программы afl может “понимать” какие мутации улучшают покрытие кода программы, а какие нет. Ещё один плюс afl в том, что можно задать словарь с комбинациями символов, которые afl не будет мутировать. Автор объясняет принцип работы своего фаззера на примере тестирования утилиты cat.

afl эффективный и простой в использовании фаззер. Наверное этим и объясняется огромный список трофеев на сайте программы. Я много читал отчётов об использовании afl, то интереса использовать его самому не было. C таким инструментом поиск сводится к рутинным операциям: собрать программу, подготовить данные, обработать результаты и сделать патч с исправлением. Но я вспомнил про свои попытки сломать разборщик конфигов в OpenBSD и решил к ней вернуться уже с afl. Я подготовил скрипт для десятка однотипных программ, подготовил данные и запустил фаззинг на пару дней. Пока afl нагружал мою машину я успел покопаться в архиве почтовых рассылок OpenBSD и нашёл множество принятых исправлений после тестирования с afl. Волонтёры и разработчики хорошо “пропылесосили”: sed, last, kdump, nm, bc, lex, libc, fold, tcpdump, ssh, mandoc, ksh, ctags, make, m4, yacc, deroff, cwm, radiusd, ctfdump, ctfconf, sasyncd, libutil, pfctl. Поэтому в успех своего мероприятия я не верил. Но всё-таки они профаззили не всё. Я нашел две ошибки сегментирования в сетевом демоне и больше сотни разных ошибок в make.

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

Метки: opensource softwaretesting