Обновить

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

В разделе "Подготовка Curl" речь о сборке с адресным санитайзером, но в CFLAGS стоит undefined, хотя LDFLAGS корректный

Опечатался, спасибо

Фаззинг функций, обрабатывающих аргументы командной строки

Для воссоздания структуры argv вы разделяете входную строку по пробелам, но они могут использоваться в http-заголовках, url (с некоторыми нюансами) и прочих полях, которые могут обрабатываться curl'ом (а может и нет, но флаг CURLU_ALLOW_SPACE есть)

Также приведённый пример в "Структура массива argv" со строкой "Two Three" не выглядит валидным тогда :)

В репозитории AFL++ есть готовый вариант обвязки для фаззинга через аргументы, который применим и для libfuzzer. В нём разделение идёт по двум подряд стоящим нуль-терминаторам, но в аргументах может быть не только ascii

CURLU_ALLOW_SPACE - Разрешает пробелы в URL если вы используете curl_url_set() с этим флагом, пробелы могут быть приняты и сохранены.

Можете не разбивать по пробелам. Вероятность того, что вы получите неверный url выше чем при разбивке по пробелам. Например оставите пробел в названии протокола.

Моменты с пробелами в url будут покрываться фаззером при помощи генерации последовательности -%20

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

Опять же:
Автор не претендует на описание самых эффективных или универсальных методов фаззинга. 

Если вы предпочитаете использовать стандартный header от afl++, то это ваш выбор.

Извиняюсь за тогда беглый анализ, глаз сильно зацепился за CURLU_ALLOW_SPACE, но на поток управления флаг не сильно сказывается при обработке URL.

Если поискать по коду макросы ISSPACE/ISBLANK, то сильнее всего на поток управления при обработке аргументов командной строки пробелы оказывают при обработке флагов --form-string (в функции formparse) и --expand-<...> (в функции varexpand).

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

А насколько нужен валидный URL - это зависит от тестируемого сценария, для чего мы вообще применяем фаззинг к данному функционалу.

Про вероятности...

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

Но libfuzzer не настолько прост, в нём много разных интересных эвристик :)

По умолчанию libfuzzer перехватывает сравнительные операции и использует их операнды для мутаций (TableOfRecentCompares, MemMemTable).

Хорошие слова оттуда, которые привели к успешным мутациям, записываются во внутренний словарь, который тоже используется.

Таким образом можно даже не писать простые словари, он сам подберёт полезные слова.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации