Exemplo n.º 1
0
        public void ExactStringBucketer_SimpleStrings_MultipleBucket()
        {
            ExactStringBucketer bucketer = new ExactStringBucketer();

            RequestSequence sequence1 = GenerateSequence(1, "non-matching 1");
            RequestSequence sequence2 = GenerateSequence(1, "non-matching 2");

            bucketer.Add(sequence1);
            bucketer.Add(sequence2);

            Assert.Equal(2, bucketer.Bucketize().Count);
        }
Exemplo n.º 2
0
        public void ExactStringBucketer_SimpleStrings_SingleBucket()
        {
            ExactStringBucketer bucketer = new ExactStringBucketer();

            RequestSequence sequence1 = GenerateSequence(1, "matching");
            RequestSequence sequence2 = GenerateSequence(1, "matching");

            bucketer.Add(sequence1);
            bucketer.Add(sequence2);

            Assert.Single(bucketer.Bucketize());
        }
Exemplo n.º 3
0
        public bool Add(RequestSequence sequence)
        {
            List <Response> responses = sequence.GetResponses();
            Response        response  = responses[responses.Count - 1];

            List <TokenCollection> allResults = sequence.GetResults();
            TokenCollection        results    = allResults[allResults.Count - 1];

            SortedSet <string> tokenNames = new SortedSet <string>();

            foreach (IToken token in results)
            {
                if (UseValueOverrides.Contains(token.Name))
                {
                    tokenNames.Add($"{token.Name}:{token.Value}");
                }
                else
                {
                    tokenNames.Add(token.Name);
                }
            }

            StringBuilder sb = new StringBuilder();

            sb.Append(response.Status.ToString());

            if (response.Status != System.Net.HttpStatusCode.RequestTimeout)
            {
                foreach (string name in tokenNames)
                {
                    sb.Append(name);
                }
            }

            if (!sequence.GetDebugMetadata().Exists(x => x.Type == "BucketDebug"))
            {
                sequence.AddMetadata("BucketDebug", sb.ToString());
            }

            if (!Sorted.ContainsKey(sb.ToString()))
            {
                Console.WriteLine($"Added new bucket {sb.ToString()}");
                Sorted.Add(sb.ToString(), new List <RequestSequence>());
                Sorted[sb.ToString()].Add(sequence);
                return(true);
            }

            Sorted[sb.ToString()].Add(sequence);
            return(false);
        }
Exemplo n.º 4
0
        public IEnumerable <RequestSequence> Generate(List <KnownEndpoint> endpoints, RequestSequence sequence, List <TokenCollection> sequenceResults)
        {
            // Only build off sequences that have an actual result.
            if (sequence.GetLastResponse() == null || (int)sequence.GetLastResponse().Status < 300)
            {
                // Search for an endpoint that we can append to the end of this request sequence.
                foreach (KnownEndpoint endpoint in endpoints)
                {
                    bool            foundMatch     = true;
                    TokenCollection requirements   = endpoint.InputTokens;
                    Stage           candidateStage = new Stage(endpoint.Request.Clone());

                    foreach (IToken token in requirements)
                    {
                        int    matchIndex = 0;
                        IToken?matchToken = null;

                        // Substituting a token with the same name is usually a good bet, but sometimes gets stuck if there is a false positive.
                        // Add some level of randomness to keep things working.
                        int skip = Rand.Next(0, 2);

                        if (skip >= 2 && GetRandomNameMatch(sequenceResults, token.Name, out matchToken, out matchIndex))
                        {
                            // Find a token that has the same name as this one.
                            candidateStage.Substitutions.Add(new SubstituteNamedToken(token, matchToken, matchIndex));
                        }
                        else if (skip >= 1 && GetRandomTypeMatch(sequenceResults, token.SupportedTypes, out matchToken, out matchIndex))
                        {
                            // Find a token that has the same type as this one.
                            candidateStage.Substitutions.Add(new SubstituteNamedToken(token, matchToken, matchIndex));
                        }
                        else
                        {
                            // Use the original value from the example request.
                            candidateStage.Substitutions.Add(new SubstituteConstant(token, token.Value));
                        }
                    }
                    if (foundMatch)
                    {
                        RequestSequence newSequence = sequence.Copy();
                        newSequence.Add(candidateStage);
                        yield return(newSequence);
                    }
                }
            }
        }
Exemplo n.º 5
0
        public bool Add(RequestSequence sequence)
        {
            List <Response> responses = sequence.GetResponses();
            Response        response  = responses[responses.Count - 1];

            StringBuilder sb = new StringBuilder();

            sb.Append(response.Status.ToString());

            if (!Sorted.ContainsKey(sb.ToString()))
            {
                Sorted.Add(sb.ToString(), new List <RequestSequence>());
                Sorted[sb.ToString()].Add(sequence);
                return(true);
            }
            Sorted[sb.ToString()].Add(sequence);
            return(false);
        }
Exemplo n.º 6
0
        RequestSequence GenerateSequence(int numStages, string responseContent)
        {
            RequestSequence sequence = new RequestSequence();

            // Force creation of the results list by 'executing' the empty sequence.
            sequence.Execute(null, null, null);

            for (int i = 0; i < numStages; ++i)
            {
                Request request = new Request(new Uri(@"http://localhost/rest/user/login/"), HttpMethod.Get);
                request.Content = "{ \"email\":\"[email protected]\",\"password\":\"123456\"}";

                sequence.Add(new Stage(request));

                Response response = new Response(System.Net.HttpStatusCode.OK, responseContent);
                sequence.GetResponses().Add(response);
            }

            return(sequence);
        }
        public IEnumerable <RequestSequence> Generate(List <KnownEndpoint> endpoints, RequestSequence sequence, List <TokenCollection> sequenceResults)
        {
            if (dictionary.Count == 0)
            {
                yield break;
            }

            for (int i = 0; i < MaxSubstitutions; ++i)
            {
                if (sequence.StageCount() == 0)
                {
                    continue;
                }

                RequestSequence newSequence   = sequence.Copy();
                int             selectedStage = rand.Next(0, newSequence.StageCount());

                Stage stage = newSequence.Get(selectedStage);

                if (stage.Substitutions.Count == 0)
                {
                    continue;
                }

                int           subIndex = rand.Next(0, newSequence.Get(selectedStage).Substitutions.Count);
                ISubstitution sub      = newSequence.Get(selectedStage).Substitutions[subIndex];
                newSequence.Get(selectedStage).Substitutions.RemoveAt(subIndex);

                string             replacement        = dictionary[rand.Next(0, dictionary.Count)];
                SubstituteConstant substituteConstant = new SubstituteConstant(sub.GetTarget(), replacement);
                newSequence.Get(selectedStage).Substitutions.Add(substituteConstant);

                yield return(newSequence);
            }
            yield break;
        }
Exemplo n.º 8
0
        public void MinimizePopulation()
        {
            Population = new List <RequestSequence>();

            // We always need the option of starting from an empty sequence.
            Population.Add(new RequestSequence());

            foreach (IBucketer bucketer in Bucketers.Values)
            {
                // Get the bucketed requests, then reset the bucketer to free up memory.
                List <List <RequestSequence> > buckets = bucketer.Bucketize();
                bucketer.Reset();

                // Go through each bucket and pick the shortest sequence to save.
                foreach (List <RequestSequence> bucket in buckets)
                {
                    RequestSequence shortest = null;
                    foreach (RequestSequence candidate in bucket)
                    {
                        bool candidateIsValid = (candidate.GetResponses().Count > 0 && candidate.GetLastResponse().Status != HttpStatusCode.RequestTimeout);
                        if (candidateIsValid && (shortest == null ||
                                                 (candidate.StageCount() < shortest.StageCount() ||
                                                  (candidate.StageCount() == shortest.StageCount() &&
                                                   candidate.SubstitutionCount() < shortest.SubstitutionCount()))))
                        {
                            shortest = candidate;
                        }
                    }
                    if (shortest != null)
                    {
                        Population.Add(shortest);
                        bucketer.Add(shortest);
                    }
                }
            }
        }
Exemplo n.º 9
0
        public void AddResponse(RequestSequence sequence)
        {
            Request finalRequest = sequence.Get(sequence.StageCount() - 1).Request;

            Bucketers[finalRequest.OriginalEndpoint].Add(sequence);
        }
Exemplo n.º 10
0
        public async Task AddRequestSequence(RequestSequence sequence, FuzzerRunEntity run)
        {
            RequestSequenceEntity model = new RequestSequenceEntity();

            model.request_count      = sequence.StageCount();
            model.substitution_count = sequence.SubstitutionCount();
            model.run_id             = run.id.GetValueOrDefault(0);

            using (var connection = GetConnection())
            {
                connection.Open();

                model.id = connection.Query <int>(
                    @"INSERT INTO sequences
                    ( request_count, substitution_count, run_id ) VALUES 
                    ( @request_count, @substitution_count, @run_id )
                    RETURNING id;", model).First();

                foreach (SequenceMetadata meta in sequence.GetDebugMetadata())
                {
                    SequenceMetadataEntity metadata_entity =
                        new SequenceMetadataEntity {
                        sequence_id = model.id, content = meta.Content, type = meta.Type
                    };

                    connection.Execute(@"INSERT INTO sequence_metadata 
                                         ( sequence_id, type, content ) VALUES
                                         ( @sequence_id, @type, @content );", metadata_entity);
                }
            }

            sequence.Id = model.id;

            List <Response>?results = sequence.GetResponses();

            if (results != null && results.Count == sequence.StageCount())
            {
                for (int i = 0; i < sequence.StageCount(); ++i)
                {
                    Request       request      = sequence.Get(i).Request;
                    RequestEntity requestModel = RequestEntity.FromRequest(request);
                    requestModel.sequence_id       = model.id;
                    requestModel.sequence_position = i;
                    AddExecutedRequest(requestModel);
                    request.Id = requestModel.id;

                    Response       response      = results[i];
                    ResponseEntity responseModel = ResponseEntity.FromResponse(response);
                    responseModel.sequence_id       = model.id;
                    responseModel.sequence_position = i;
                    AddResponse(responseModel);
                    response.Id = responseModel.id;

                    foreach (ISubstitution sub in sequence.Get(i).Substitutions)
                    {
                        SubstitutionEntity subModel = SubstitutionEntity.FromSubstitution(sub);
                        subModel.sequence_id       = model.id;
                        subModel.sequence_position = i;
                        AddSubstitution(subModel);
                    }
                }

                if (sequence.GetLastResponse() != null)
                {
                    int statusCode = (int)sequence.GetLastResponse().Status;
                    RequestSequenceLabelEntity labelEntity = new RequestSequenceLabelEntity();
                    labelEntity.sequence_id = model.id.Value;
                    if (statusCode >= 100 && statusCode < 200)
                    {
                        labelEntity.name = "Informational";
                    }
                    else if (statusCode >= 200 && statusCode < 300)
                    {
                        labelEntity.name = "Success";
                    }
                    else if (statusCode >= 300 && statusCode < 400)
                    {
                        labelEntity.name = "Redirection";
                    }
                    else if (statusCode >= 400 && statusCode < 500)
                    {
                        labelEntity.name = "Client Error";
                    }
                    else if (statusCode >= 500 && statusCode < 600)
                    {
                        labelEntity.name = "Server Error";
                    }
                    else
                    {
                        labelEntity.name = "Unknown Status";
                    }
                    await AddRequestSequenceLabel(labelEntity);
                }
            }
            else
            {
                Console.WriteLine("Warning: Truncated request sequence.");
            }
        }