Skip to content

Fuzzing YamlDotNet (C#) project with sydr‐fuzz (AFL and Sharpfuzz backend) (rus)

Daniel Kuts edited this page Apr 19, 2024 · 5 revisions

Введение

В данной статье будет продемонстрирован подход к фаззингу приложений на языке C# с помощью интерфейса Sydr-Fuzz на основе инструмента Sharpfuzz в связке с фаззером AFLplusplus. Sydr-Fuzz предоставляет удобный интерфейс для запуска гибридного фаззинга, задействуя возможности динамического символьного выполнения на базе инструмента Sydr в сочетании с современными фаззерами libFuzzer и AFLplusplus. Помимо фаззинга, Sydr-Fuzz предлагает набор возможностей для минимизации корпуса, сбора покрытия, поиска ошибок в программах посредством проверки предикатов безопасности, а также анализа аварийных завершений при помощи Casr. Помимо программ на чисто компилируемых языках, Sydr-Fuzz поддерживает фаззинг приложений на языках Python, Java и JavaScript. Следующим шагом было добавление возможности фаззинга C# кода через наш инструмент Sydr-Fuzz. Для фаззинга C# приложений бинарные файлы проекта сначала инструментируются через Sharpfuzz, а сам фаззинг осуществляется через AFLplusplus.

Подготовка фаззинг-цели

Для примера создания фаззинг-цели рассмотрим проект YamlDotNet. Инструкция по установке и использованию инструмента Sharpfuzz может быть найдена в его репозитории на GitHub, инструкция по установке фаззера AFLplusplus так же находится в его GitHub репозитории. В нашем репозитории OSS-Sydr-Fuzz уже есть готовый Docker-контейнер с настроенным окружением, который мы и будем использовать для фаззинга.

Сборка и запуск докер-контейнера производится следующей командой:

$ docker build -t oss-sydr-fuzz-yamldotnet .
$ docker run --privileged --network host -v /etc/localtime:/etc/localtime:ro --rm -it -v $PWD:/fuzz oss-sydr-fuzz-yamldotnet /bin/bash

Рассмотрим фаззинг-цель Program.cs:

using SharpFuzz;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using System.IO;
using System.Text;
using YamlDotNet.RepresentationModel;

public class Program
{
    public static void Main(string[] args)
    {
        Fuzzer.OutOfProcess.Run(stream =>
        {
            try {
                string yml = File.ReadAllText(args[0]);
                var input = new StringReader(yml);

                var yaml = new YamlStream();
                var deserializer = new DeserializerBuilder()
                    .WithNamingConvention(CamelCaseNamingConvention.Instance)
                    .Build();
                var serializer = new SerializerBuilder()
                    .JsonCompatible()
                    .Build();

                var doc = deserializer.Deserialize(input);
                var json = serializer.Serialize(doc);
                var parser = new Parser(input);
                parser.Consume<StreamStart>();
                yaml.Load(input);
            }
            catch (YamlException) { }
            catch (System.InvalidOperationException) { }
            catch (System.ArgumentNullException) { }
            catch (System.ArgumentException) { }
        });
    }
}

Во-первых, необходимо подключить модуль Sharpfuzz для использования необходимого интерфейса. Во-вторых, по необходимости нужно добавить необходимые библиотеки проекта. Далее в функции Main нужно вызвать метод Fuzzer.OutOfProcess.Run(), в качестве параметра которой нужно передать функцию, являющуюся целью фаззинга. В данном случае мы передаем lambda-функцию, которая вызывает функции фаззинг-цели.

Фаззинг C# кода через Sharpfuzz подразумевает поиск необработанных исключений, поэтому в данной обертке стоит блок try-catch, так как мы хотим перехватывать и игнорировать исключения, связанные с неправильным форматом .yaml файлов и не являющиеся ошибочным поведением программы.

Сборку фаззинг цели желательно производить в новой директории: создать там новое консольное .NET приложение, скопировать туда написанную фазз-обертку и добавить библиотеку Sharpfuzz:

    $ mkdir build_fuzz && cd build_fuzz
    $ dotnet new console
    $ dotnet add package SharpFuzz
    $ cp -r /path/to/fuzz_target.cs .

Далее для сборки фаззинг-цели нужно в конфигурационном .csproj файле связать ее с модулем фаззинг-проекта. Для этого нужно либо собрать сам проект (в директории проекта с помощью dotnet build или dotnet publish), найти скомпилированный модуль target_name.dll (обычно лежит внутри директории bin/) и указать путь до него в build_fuzz.csproj файле, либо можно указать путь до .csproj файла проекта, тогда при сборке фазз-таргета проект будет пересобираться автоматически. Примеры .csproj файлов:

<ItemGroup>
    <Reference Include="target_name">
      <HintPath>/path/to/bin/target_name.dll</HintPath>
    </Reference>
    <PackageReference Include="SharpFuzz" Version="2.1.1" />
</ItemGroup>

либо

<ItemGroup>
    <ProjectReference Include="/path/to/csproj/target_name.csproj" />
    <PackageReference Include="SharpFuzz" Version="2.1.1" />
</ItemGroup>

После этого нужно собрать фаззинг цель и проинструментировать ее для фаззинга с помощью инструмента Sharpfuzz. Настоятельно рекомендуется при сборке фаззинг-цели использовать ключ -p:CheckForOverfllowUnderflow=true компилятора, который включает проверку целочисленного переполнения в рантайме. Данная проверка позволит отловить ошибки, которые не будут задетектированы фаззером.

    $ dotnet publish build_fuzz.csproj -c release -o bin -p:CheckForOverfllowUnderflow=true
    $ sharpfuzz bin/target_name.dll

Сборка готова! Теперь можно перейти к фаззингу нашей цели.

Подготовка к фаззингу

Посмотрим на конфигурационный файл проекта YamlDotNet parse_yaml.toml:

[sharpfuzz]
args = "-i /corpus -t 10000 -x /yaml.dict"
target = "/build_fuzz/bin/fuzz.dll @@"
casr_bin = "/build_fuzz/bin/release/net8.0/fuzz.dll"
jobs = 2

[cov]
build_dir = "/build_cov"

Здесь таблица [sharpfuzz] отвечает за конфигурацию запуска фаззера AFL++. args - аргументы, здесь обязательно нужно указать путь до корпуса (-i /path/to/corpus), target - путь до .dll файла фазз-обертки, @@ обозначают, что ввод задается через файл, без этого символа ввод будет осуществляться через стандартный ввод, a casr_bin - путь до .dll файла фазз-обертки, не проинструментированного Sharpfuzz (это поле обязательно, если будет использоваться команда sydr-fuzz casr для анализа аварийных завершений). И, наконец, jobs - количество потоков, в которых будет запускаться AFL++.

Далее перейдем к таблице [cov]. Она отвечает за конфигурацию покрытия. Здесь build_dir - директория, в которой находится и собирается фазз-таргет.

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

    $ mkdir build_cov && cd build_cov
    $ dotnet new console
    $ dotnet add package SharpFuzz
    $ cp -r /path/to/fuzz_target.cs .

Рассмотрим пример build-файла проекта, чтобы понять, как можно собрать готовый фазз-таргет.

# Make directories for fuzzing and coverage.
mkdir -p /build_fuzz /build_cov
cp /Program.cs /fuzz.csproj /build_fuzz
cp /Program.cs /fuzz.csproj /build_cov

# Build target for fuzzing.
cd /build_fuzz
dotnet publish fuzz.csproj -c release -o bin
sharpfuzz bin/YamlDotNet.dll

У нас уже написаны фазз-обертка и .csproj файл по вышеописанным правилам. Мы создаем две директории (для фаззинга и сбора покрытия) и копируем в них обертку и конфигурационный файл. Далее, как показано выше, собираем проект в директории для фаззинга и инструментируем .dll модуль проекта. В директории покрытия собирать фазз-таргет необязательно, он будет собран автоматически при запуске сбора покрытия через Sydr-Fuzz через dotnet build. Если нужно собрать проект с определенными настройками, то можно смело это делать, в таком случае нужно собрать его так, чтобы все .dll файлы лежали внутри директории bin.

Фаззинг

Теперь, перейдем к фаззингу! Запустим Sydr-Fuzz следующей командой:

    $ sydr-fuzz -c parse_yaml.toml run
[2024-03-13 17:12:20] [INFO] [AFL++] [*] Fuzzing test case #499 (2207 total, 0 crashes saved, state: in progress, mode=explore, perf_score=229, weight=0, favorite=1, was_fuzzed=1, exec_us=223, hits=32, map=1833, ascii=0, run_time=0:00:10:58)...
[2024-03-13 17:12:20] [INFO] [AFL++] [*] Fuzzing test case #502 (2207 total, 0 crashes saved, state: in progress, mode=explore, perf_score=172, weight=0, favorite=1, was_fuzzed=1, exec_us=187, hits=66, map=1537, ascii=0, run_time=0:00:10:58)...
[2024-03-13 17:12:20] [INFO] [AFL++] [*] Fuzzing test case #506 (2207 total, 0 crashes saved, state: in progress, mode=explore, perf_score=114, weight=0, favorite=1, was_fuzzed=1, exec_us=200, hits=174, map=1566, ascii=0, run_time=0:00:10:58)...
[2024-03-13 17:12:20] [INFO] [AFL++] [*] Fuzzing test case #507 (2207 total, 0 crashes saved, state: in progress, mode=explore, perf_score=114, weight=0, favorite=1, was_fuzzed=1, exec_us=262, hits=231, map=1140, ascii=0, run_time=0:00:10:58)...
[2024-03-13 17:12:20] [INFO] Found crash /fuzz/parse_yaml-out/crashes/crash-48745d7888086b915e559192e1c2dc785db5a1c1
[2024-03-13 17:12:21] [INFO] [AFL++] [*] Fuzzing test case #510 (2207 total, 0 crashes saved, state: in progress, mode=explore, perf_score=114, weight=0, favorite=1, was_fuzzed=1, exec_us=230, hits=155, map=1874, ascii=0, run_time=0:00:10:59)...
[2024-03-13 17:12:21] [INFO] [AFL++] [*] Fuzzing test case #514 (2208 total, 0 crashes saved, state: in progress, mode=explore, perf_score=128, weight=0, favorite=1, was_fuzzed=1, exec_us=182, hits=108, map=921, ascii=0, run_time=0:00:11:00)...
[2024-03-13 17:12:21] [INFO] [AFL++] [*] Fuzzing test case #515 (2210 total, 0 crashes saved, state: in progress, mode=explore, perf_score=128, weight=0, favorite=1, was_fuzzed=1, exec_us=176, hits=97, map=904, ascii=0, run_time=0:00:11:00)...
[2024-03-13 17:12:21] [INFO] [AFL++] [*] Fuzzing test case #516 (2210 total, 0 crashes saved, state: in progress, mode=explore, perf_score=172, weight=0, favorite=1, was_fuzzed=1, exec_us=186, hits=43, map=1558, ascii=0, run_time=0:00:11:00)...
[2024-03-13 17:12:21] [INFO] [AFL++] [*] Fuzzing test case #518 (2210 total, 0 crashes saved, state: in progress, mode=explore, perf_score=114, weight=0, favorite=1, was_fuzzed=1, exec_us=200, hits=160, map=1548, ascii=0, run_time=0:00:11:00)...
[2024-03-13 17:12:21] [INFO] [AFL++] [*] Fuzzing test case #523 (2210 total, 0 crashes saved, state: in progress, mode=explore, perf_score=300, weight=0, favorite=0, was_fuzzed=1, exec_us=194, hits=11, map=1599, ascii=0, run_time=0:00:11:00)...
[2024-03-13 17:12:24] [INFO] [AFL++] 
[2024-03-13 17:12:24] [INFO] [AFL++] +++ Testing aborted by user +++
[2024-03-13 17:12:24] [INFO] [AFL++] [!] 
[2024-03-13 17:12:24] [INFO] [AFL++] Performing final sync, this make take some time ...
[2024-03-13 17:12:24] [INFO] [AFL++] [!] Done!
[2024-03-13 17:12:24] [INFO] [AFL++] [+] We're done here. Have a nice day!
[2024-03-13 17:12:24] [INFO] [AFL++] 
[2024-03-13 17:12:24] [INFO] [RESULTS] Fuzzing corpuses are saved in workers queue directories. Run sydr-fuzz cmin subcommand to gather full corpus at "/fuzz/parse_yaml-out/corpus-old" and minimized corpus at "/fuzz/parse_yaml-out/corpus".
[2024-03-13 17:12:24] [INFO] [RESULTS] [afl_main] Statistics: 1664 new corpus items found, 6.86% coverage achieved, 0 crashes saved, 0 timeouts saved, total runtime 0 days, 0 hrs, 11 min, 3 sec
[2024-03-13 17:12:24] [INFO] [RESULTS] [afl_s01] Statistics: 1563 new corpus items found, 6.99% coverage achieved, 1 crashes saved, 2 timeouts saved, total runtime 0 days, 0 hrs, 11 min, 3 sec
[2024-03-13 17:12:24] [INFO] [RESULTS] timeout/crash: 2/1

После завершения фаззинга у нас на выходе получилось более 4000 новых файлов в корпусе. Стоит запустить минимизацию корпуса:

sydr-fuzz -c parse_yaml.toml cmin
[2024-03-13 17:17:14] [INFO] [CMIN] corpus minimization tool for AFL++ (awk version)
[2024-03-13 17:17:14] [INFO] [CMIN] [*] Obtaining traces for 4312 input files in '/fuzz/parse_yaml-out/corpus-old'.
[2024-03-13 17:17:14] [INFO] [CMIN] [*] Creating 8 parallel tasks with about 539 items each.
[2024-03-13 17:17:14] [INFO] [CMIN] [*] Waiting for parallel tasks to complete ...
[2024-03-13 17:17:26] [INFO] [CMIN] [*] Done!
[2024-03-13 17:17:26] [INFO] [CMIN]     Processing file 1/4312
[2024-03-13 17:17:26] [INFO] [CMIN]     Processing file 44/4312
[2024-03-13 17:17:26] [INFO] [CMIN]     Processing file 87/4312
[2024-03-13 17:17:27] [INFO] [CMIN]     Processing file 130/4312
...
[2024-03-13 17:17:46] [INFO] [CMIN]     Processing file 4215/4312
[2024-03-13 17:17:46] [INFO] [CMIN]     Processing file 4258/4312
[2024-03-13 17:17:47] [INFO] [CMIN]     Processing file 4301/4312
[2024-03-13 17:17:49] [INFO] [CMIN] [+] Found 22119 unique tuples across 4312 files.
[2024-03-13 17:17:49] [INFO] [CMIN] [+] Narrowed down to 839 files, saved in '/fuzz/parse_yaml-out/corpus'.

Теперь наш корпус уменьшился примерно в 5 раз! Теперь можно посмотреть на покрытие кода.

Покрытие

Для сбора покрытия C# кода мы используем 2 инструмента: minicover и AltCover. minicover используется для форматов html, clover, coveralls, xml, opencover, cobertura, text; AltCover - для форматов html или lcov. По умолчанию используется AltCover (так как он позволяет собирать покрытие в параллельном режиме), но если нужно использовать minicover, то в конфигурационном файле нужно задать таблицу [cov] в следующем виде:

[cov]
target = "/build_cov/Program.cs"
source = "/YamlDotNet"
build_dir = "/build_cov"
use_minicover = true

Здесь target - путь до исходного кода обертки, source - путь до директории с исходным кодом проекта, build_dir - директория, в которой находится и собирается фазз-таргет, use_minicover - флаг, указывающий на то, что используется инструмент minicover (по умолчанию он равен false).

Соберем покрытие!

    $ sydr-fuzz -c parse_yaml.toml sharpcov html
[2024-03-13 17:23:13] [INFO] Running sharpcov html "/fuzz/parse_yaml.toml"
[2024-03-13 17:23:13] [INFO] Collecting coverage data for each file in corpus: /fuzz/parse_yaml-out/corpus
[2024-03-13 17:23:13] [INFO] Saving coverage data to /fuzz/parse_yaml-out/coverage/
[2024-03-13 17:23:13] [INFO] Launching dotnet build: cd "/build_cov" && "/usr/bin/dotnet" "build"
[2024-03-13 17:23:20] [INFO] Launching minicover instrumentation: "/root/.dotnet/tools/minicover" "instrument" "--workdir" "/" "--sources" "/build_cov/Program.cs" "--sources" "/YamlDotNet/" "--assemblies" "/build_cov/**/*.dll" "--coverage-file" "/fuzz/parse_yaml-out/coverage/coverage.json" "--hits-directory" "/fuzz/parse_yaml-out/coverage/coverage-hits"
[2024-03-13 17:23:21] [INFO] Launching coverage.
[2024-03-13 17:23:21] [INFO] Collecting coverage: 1/839
[2024-03-13 17:23:22] [INFO] Collecting coverage: 2/839
[2024-03-13 17:23:23] [INFO] Collecting coverage: 3/839
[2024-03-13 17:23:24] [INFO] Collecting coverage: 4/839
...
[2024-03-13 17:33:53] [INFO] Collecting coverage: 836/839
[2024-03-13 17:33:54] [INFO] Collecting coverage: 837/839
[2024-03-13 17:33:54] [INFO] Collecting coverage: 838/839
[2024-03-13 17:33:55] [INFO] Collecting coverage: 839/839
[2024-03-13 17:33:56] [INFO] Launching minicover report to html format: "/root/.dotnet/tools/minicover" "htmlreport" "--workdir" "/" "--coverage-file" "/fuzz/parse_yaml-out/coverage/coverage.json" "--no-fail" "--output" "/fuzz/parse_yaml-out/coverage"
[2024-03-13 17:33:57] [INFO] Coverage collecting to html format is done!

Покрытие (в случае minicover в формате html) будет выглядеть следующим образом:

minicover_html

В случае сбора покрытия с помощью инструмента AltCover, можно дополнительно воспользоваться инструментом reportgenerator. С помощью него можно сгенерировать покрытие в многих форматах, используя .xml файл, сгенерированный после работы AltCover:

    $ reportgenerator -reports:/fuzz/parse_yaml-out/coverage/coverage.xml -reporttypes:Html -targetdir:/fuzz/parse_yaml-out/coverage/html

В опции -reporttypes: следует указать желаемый формат. В результате в директории /fuzz/parse_yaml-out/coverage/html будет находиться отчет о покрытии в формате html.

Сортировка аварийных завершений

Наконец, можно применить Casr для анализа и сортировки аварийных завершений. Но перед этим в конфигурационный файл необходимо добавить поле casr_bin в таблицу [sharpfuzz], где нужно указать путь до бинарного файла, не проинструментированного Sharpfuzz:

[sharpfuzz]
...
target = "/build_fuzz/bin/fuzz.dll @@"
casr_bin = "/build_fuzz/bin/release/net8.0/fuzz.dll"
...

Теперь запустим анализ аварийных завершений с помощью Casr:

    $ sydr-fuzz -c parse_yaml.toml casr

О Casr можно узнать больше в репозитории Casr или из гайда.

Вывод команды будет следующим:

[2024-04-10 14:06:14] [INFO] [CASR-AFL] Analyzing 265 files...
[2024-04-10 14:06:14] [INFO] [CASR-AFL] Timeout for target execution is 30 seconds
[2024-04-10 14:06:14] [INFO] [CASR-AFL] Generating CASR reports...
[2024-04-10 14:06:14] [INFO] [CASR-AFL] Using 8 threads
[2024-04-10 14:06:15] [INFO] [CASR-AFL] Progress: 16/265
[2024-04-10 14:06:16] [INFO] [CASR-AFL] Progress: 36/265
...
[2024-04-10 14:06:26] [INFO] [CASR-AFL] Progress: 235/265
[2024-04-10 14:06:27] [INFO] [CASR-AFL] Progress: 256/265
[2024-04-10 14:06:28] [INFO] [CASR-AFL] Deduplicating CASR reports...
[2024-04-10 14:06:29] [INFO] [CASR-AFL] Number of reports before deduplication: 265. Number of reports after deduplication: 8
[2024-04-10 14:06:29] [INFO] [CASR-AFL] Clustering CASR reports...
[2024-04-10 14:06:29] [INFO] [CASR-AFL] Number of clusters: 5
[2024-04-10 14:06:29] [INFO] [CASR-AFL] ==> <cl1>
[2024-04-10 14:06:29] [INFO] [CASR-AFL] Crash: /fuzz/parse_yaml-out/casr/cl1/id:000011,sig:02,src:000333,time:3317,execs:15906,op:havoc,rep:2
[2024-04-10 14:06:29] [INFO] [CASR-AFL]   casrep: NOT_EXPLOITABLE: System.InvalidOperationException: /YamlDotNet/YamlDotNet/Core/Parser.cs:312
[2024-04-10 14:06:29] [INFO] [CASR-AFL]   Similar crashes: 1
[2024-04-10 14:06:29] [INFO] [CASR-AFL] Cluster summary -> System.InvalidOperationException: 1
[2024-04-10 14:06:29] [INFO] [CASR-AFL] ==> <cl2>
[2024-04-10 14:06:29] [INFO] [CASR-AFL] Crash: /fuzz/parse_yaml-out/casr/cl2/id:000054,sig:02,src:000993,time:35940,execs:149891,op:havoc,rep:1
[2024-04-10 14:06:29] [INFO] [CASR-AFL]   casrep: NOT_EXPLOITABLE: System.ArgumentOutOfRangeException: /YamlDotNet/YamlDotNet/Core/Scanner.cs:2001
[2024-04-10 14:06:29] [INFO] [CASR-AFL]   Similar crashes: 1
[2024-04-10 14:06:29] [INFO] [CASR-AFL] Cluster summary -> System.ArgumentOutOfRangeException: 1
[2024-04-10 14:06:29] [INFO] [CASR-AFL] ==> <cl3>
[2024-04-10 14:06:29] [INFO] [CASR-AFL] Crash: /fuzz/parse_yaml-out/casr/cl3/id:000065,sig:02,src:000835,time:69261,execs:299637,op:havoc,rep:2
[2024-04-10 14:06:29] [INFO] [CASR-AFL]   casrep: NOT_EXPLOITABLE: System.ArgumentException: /YamlDotNet/YamlDotNet/Core/TagName.cs:46
[2024-04-10 14:06:29] [INFO] [CASR-AFL]   Similar crashes: 1
[2024-04-10 14:06:29] [INFO] [CASR-AFL] Cluster summary -> System.ArgumentException: 1
[2024-04-10 14:06:29] [INFO] [CASR-AFL] ==> <cl4>
[2024-04-10 14:06:29] [INFO] [CASR-AFL] Crash: /fuzz/parse_yaml-out/casr/cl4/id:000000,sig:02,src:000023,time:198,execs:1077,op:havoc,rep:6
[2024-04-10 14:06:29] [INFO] [CASR-AFL]   casrep: NOT_EXPLOITABLE: System.ArgumentException: /YamlDotNet/YamlDotNet/Core/TagName.cs:51
[2024-04-10 14:06:29] [INFO] [CASR-AFL]   Similar crashes: 2
[2024-04-10 14:06:29] [INFO] [CASR-AFL] Cluster summary -> System.ArgumentException: 2
[2024-04-10 14:06:29] [INFO] [CASR-AFL] ==> <cl5>
[2024-04-10 14:06:29] [INFO] [CASR-AFL] Crash: /fuzz/parse_yaml-out/casr/cl5/id:000000,sig:02,src:000000,time:53,execs:474,op:havoc,rep:2
[2024-04-10 14:06:29] [INFO] [CASR-AFL]   casrep: NOT_EXPLOITABLE: System.ArgumentNullException: /YamlDotNet/YamlDotNet/Core/Tokens/TagDirective.cs:81
[2024-04-10 14:06:29] [INFO] [CASR-AFL]   Similar crashes: 3
[2024-04-10 14:06:29] [INFO] [CASR-AFL] Cluster summary -> System.ArgumentNullException: 3
[2024-04-10 14:06:29] [INFO] [CASR-AFL] SUMMARY -> System.ArgumentException: 3 System.ArgumentNullException: 3 System.ArgumentOutOfRangeException: 1 System.InvalidOperationException: 1
[2024-04-10 14:06:29] [INFO] Crashes and Casr reports are saved in /fuzz/parse_yaml-out/casr

В результате работы Casr сократил количество крешей с 265 до 8! А затем разбил их на 5 кластеров. Далее рассмотрим отчет работы Casr на одном из крешей (файл .casrep в выходной директории):

Screenshot from 2024-04-10 14-13-05

В отчете указаны место ошибки, стектрейс, информация об окружении и многое другое, что будет полезно для анализа ошибок!

Заключение

В данной статье был показан подход к фаззингу C# кода с помощью инструмента Sydr-Fuzz. Были поддержаны такие этапы, как запуск фаззинга, минимизация корпуса, сбор покрытия и анализ аварийных завершений, а главное, все эти этапы можно быстро и удобно запускать через Sydr-Fuzz!