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); } } } }
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."); } }