コード例 #1
0
 public FuzzerGenerationViewModel(FuzzerGenerationEntity entity)
 {
     id                = entity.id;
     run_id            = entity.run_id;
     run_position      = entity.run_position;
     population_size   = entity.population_size;
     execution_time    = entity.execution_time;
     executed_requests = entity.executed_requests;
 }
コード例 #2
0
 public void AddFuzzerGeneration(FuzzerGenerationEntity model)
 {
     using (var connection = GetConnection())
     {
         connection.Open();
         model.id = connection.Query <int>(
             @"INSERT INTO fuzzer_generation
             ( run_id, run_position, population_size, execution_time, executed_requests ) VALUES 
             ( @run_id, @run_position, @population_size, @execution_time, @executed_requests )
             RETURNING id;", model).First();
     }
 }
コード例 #3
0
ファイル: Program.cs プロジェクト: rmkerr/RiverFuzz
        public static async Task Fuzz(JObject config)
        {
            // Set up a database connection to store the results.
            // TODO: Move this hardcoded connection string to a config file.
            FuzzerRepository databaseHelper = new FuzzerRepository("Server=db;Database=riverfuzz;Port=5432;User Id=postgres;Password='******';");

            if (config.Value <bool?>("ResetDatabase") ?? false)
            {
                databaseHelper.InitializeDatabase();
            }

            // Set up HttpClient.
            HttpClientHandler handler = new HttpClientHandler();

            handler.UseCookies        = false;
            handler.AllowAutoRedirect = false;
            HttpClient client = new HttpClient(handler);

            client.Timeout = TimeSpan.FromMilliseconds(1000);

            // Load all response tokenizers.
            List <IResponseTokenizer> responseTokenizers = new List <IResponseTokenizer>();

            responseTokenizers.Add(new JsonTokenizer());
            responseTokenizers.Add(new BearerTokenizer());
            responseTokenizers.Add(new HtmlFormTokenizer());
            responseTokenizers.Add(new CookieTokenizer());

            // Load all request tokenizers.
            List <IRequestTokenizer> requestTokenizers = new List <IRequestTokenizer>();

            requestTokenizers.Add(new JsonTokenizer());
            requestTokenizers.Add(new QueryTokenizer());
            requestTokenizers.Add(new BearerTokenizer());
            requestTokenizers.Add(new KnownUrlArgumentTokenizer());
            requestTokenizers.Add(new HtmlFormTokenizer());
            requestTokenizers.Add(new CookieTokenizer());

            TokenCollection startingData = new TokenCollection();

            // Generators take a sequence and modify it.
            List <IGenerator> generators = new List <IGenerator>();

            generators.Add(new BestKnownMatchGenerator());
            generators.Add(new RemoveTokenGenerator(5));

            List <string> dictionary = await databaseHelper.GetAllDictionaryEntries();

            generators.Add(new DictionarySubstitutionGenerator(dictionary, 10));

            // Parse the list of endpoints we should include in this run, then load them.
            DatabaseLoader       databaseParse = new DatabaseLoader(databaseHelper, config.Value <string>("Target"));
            List <int>           endpointIds   = config["TargetEndpoints"].Select(x => (int)x).ToList();
            List <KnownEndpoint> endpoints     = await databaseParse.LoadEndpointsById(endpointIds);

            // Add the endpoints to the population and set up bucketers.
            PopulationManager population = new PopulationManager();

            foreach (KnownEndpoint endpoint in endpoints)
            {
                endpoint.Tokenize(requestTokenizers, responseTokenizers);
                population.AddEndpoint(endpoint, new TokenNameBucketer());

                // If the endpoint is not already in the database, add it.
                if (endpoint.Request.Id == null)
                {
                    databaseHelper.AddEndpoint(KnownEndpointEntity.FromRequest(endpoint.Request));
                }
            }

            // Record the time we started this run.
            FuzzerRunEntity runInfo = new FuzzerRunEntity();

            runInfo.name       = config.Value <string?>("RunName") ?? "Untitled Fuzzer Run";
            runInfo.start_time = DateTime.Now;
            runInfo.end_time   = DateTime.MaxValue;
            databaseHelper.AddFuzzerRun(runInfo);

            // TimeSpan used to stop the fuzzer.
            TimeSpan  timeLimit = TimeSpan.FromMinutes(config.Value <int>("ExecutionTime"));
            Stopwatch runTime   = new Stopwatch();

            runTime.Start();

            // In each generation, we will:
            // 1: Generate a new set of viable sequences by mutating the existing population.
            // 2: Execute each viable sequence and caputure results.
            // 3: Bucket the results.
            // 4: Keep the shortest sequences from each bucket.
            // 5: Repeat with the new population.
            for (int generation = 0; runTime.ElapsedMilliseconds < timeLimit.TotalMilliseconds; generation++)
            {
                Console.WriteLine("\n\n----------------------------------------------------------------------------------");
                Console.WriteLine($"Generation {generation}");
                Console.WriteLine("----------------------------------------------------------------------------------");

                Stopwatch generationStopwatch = new Stopwatch();
                generationStopwatch.Start();

                int popCount     = population.Population.Count; // Store since we will be growing list.
                int requestCount = 0;                           // Used for performance measurement.

                // Loops over each existing seed sequence in the population.
                for (int seed = 0; seed < popCount; ++seed)
                {
                    // Combine the starting dictionary and the results of this request sequence.
                    List <TokenCollection> seedTokens;
                    if (population.Population[seed].GetResults() == null)
                    {
                        seedTokens = new List <TokenCollection>();
                        seedTokens.Add(new TokenCollection(startingData));
                    }
                    else
                    {
                        seedTokens = population.Population[seed].GetResults();
                    }

                    int candidateNumber = 0;
                    // Generate candidate request sequences by mutating that seed.
                    foreach (IGenerator generator in generators)
                    {
                        foreach (RequestSequence candidate in generator.Generate(population.Endpoints, population.Population[seed], seedTokens))
                        {
                            Stopwatch candidateStopwatch = new Stopwatch();
                            candidateStopwatch.Start();

                            // Execute the request sequence.
                            await candidate.Execute(client, responseTokenizers, startingData);

                            // Add a response to the population. If it looks interesting, we will look at it later.
                            population.AddResponse(candidate);

                            List <Response>?responses = candidate.GetResponses();
                            if (responses != null)
                            {
                                requestCount += responses.Count;
                            }

                            candidateStopwatch.Stop();

                            if (candidateStopwatch.ElapsedMilliseconds > 500)
                            {
                                Console.WriteLine($"\tWARNING: Long running candidate {candidateNumber++} completed in {candidateStopwatch.ElapsedMilliseconds}ms");
                            }
                        }
                    }
                }
                // await resetHelper.Reset(client);

                population.MinimizePopulation();

                generationStopwatch.Stop();
                Console.WriteLine($"Generation {generation} completed in {generationStopwatch.ElapsedMilliseconds}ms");

                FuzzerGenerationEntity genEntity = new FuzzerGenerationEntity {
                    population_size   = population.Population.Count,
                    run_position      = generation,
                    execution_time    = generationStopwatch.Elapsed,
                    executed_requests = requestCount,
                    run_id            = runInfo.id.Value
                };
                databaseHelper.AddFuzzerGeneration(genEntity);

                Console.WriteLine($"Population size: {population.Population.Count}");
                Console.WriteLine($"Requests per second: {requestCount / generationStopwatch.Elapsed.TotalSeconds}");
            }

            runInfo.end_time = DateTime.Now;
            databaseHelper.UpdateFuzzerRunEndTime(runInfo);

            foreach (RequestSequence sequence in population.Population)
            {
                Response?finalResponse = sequence.GetLastResponse();
                if (finalResponse != null)
                {
                    await databaseHelper.AddRequestSequence(sequence, runInfo);
                }
            }
        }