
Комментарии 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).
Хорошие слова оттуда, которые привели к успешным мутациям, записываются во внутренний словарь, который тоже используется.
Таким образом можно даже не писать простые словари, он сам подберёт полезные слова.
Особенности подачи входных данных при фаззинге в режиме Persistent Mode на примере Libfuzzer + CURL