def _set_hex_definitions(self, requestId): """ Helper that sets the various hex definition values @return: None @rtype : None """ self._hex_definition = str_to_hex_def(str(self.definition)) request_id_component = requestId if requestId else self.endpoint self._request_id = str_to_hex_def(request_id_component) self._method_endpoint_hex_definition = str_to_hex_def(self.method + request_id_component)
def hex_definition(self): """ Hex representation of sequence's definition. @return: Hex representation of sequence's definition. @rtype : Str """ seq_hex_definition = [] for request in self.requests: seq_hex_definition.append(request.hex_definition) return str_to_hex_def("".join(seq_hex_definition))
def _set_schemas(examples: RequestExamples, body_schema: BodySchema, method: str, endpoint: str): """ Assigns a specified RequestExamples object to the matching request in the RequestCollection @param examples: The RequestExamples object to set @param body_schema: The BodySchema object to set @param method: The request's method @param endpoint: The request's endpoint @return: None """ def _print_req_not_found(): logger.write_to_main( "Request from grammar does not exist in the Request Collection!\n" f"{method} {endpoint}\n",\ print_to_console=True ) request_collection = GrammarRequestCollection().request_id_collection hex_def = str_to_hex_def(endpoint) # Find the request's endpoint in the request collection if hex_def in request_collection: # Find the matching request by method. # This loop will run max n = # unique methods for the request for req in request_collection[hex_def]: if req.method == method: if examples: # Set the request's matching examples req.set_examples(examples) if body_schema: # Set the request's matching body schema req.set_body_schema(body_schema) break else: # The endpoint was found in the request collection, but not with this method _print_req_not_found() else: # Failed to find request in the request collection _print_req_not_found()
def apply(self, rendered_sequence, lock): """ Applies check for fuzzing request payload body @param rendered_sequence: Object containing the rendered sequence information @type rendered_sequence: RenderedSequence @param lock: Lock object used to sync more than one fuzzing job @type lock: thread.Lock @return: None @type : None """ if not rendered_sequence.sequence: return self._sequence = copy.copy(rendered_sequence.sequence) last_request = self._sequence.last_request # Remove the last request from the sequence list because it will be replaced # with new requests. self._sequence.requests = self._sequence.requests[:-1] self._sequence._sent_request_data_list = self._sequence._sent_request_data_list[: -1] last_request_def = str_to_hex_def( last_request.method) + last_request.request_id # check to see if we already tested this request if last_request_def in self._tested_requests: return self._tested_requests.add(last_request_def) if last_request.examples: self._log( "Sending examples for request: \n" f"{last_request.endpoint}\n" f"Previous attempt was {'valid' if rendered_sequence.valid else 'invalid'}." ) self._send_each_example(last_request)
def apply(self, rendered_sequence, lock): """ Applies check for fuzzing request payload body @param rendered_sequence: Object containing the rendered sequence information @type rendered_sequence: RenderedSequence @param lock: Lock object used to sync more than one fuzzing job @type lock: thread.Lock @return: None @type : None """ # one-time setup if not self._setup_done: # read the customized fuzzing recipe, if provided if self._recipe_file: with open(self._recipe_file, 'r') as fr: recipe_str = fr.read() recipe_json = json.loads(recipe_str) self._setup_fuzzing_pipelines(recipe_json) # log self._log(f'fuzzing valid {self._fuzz_valid}') self._log(f'fuzzing invalid {self._fuzz_invalid}') self._log(f'start with examples {self._start_with_examples}') self._log(f'size dep budget {self._size_dep_budget}') self._log(f'use feedback {self._use_feedback}') self._log(f'recipe {self._recipe_file}') # finish one-time setup self._setup_done = True if not rendered_sequence.sequence or\ (rendered_sequence.valid and not self._fuzz_valid) or\ (not rendered_sequence.valid and not self._fuzz_invalid): return self._sequence = rendered_sequence.sequence # only fuzz the body of the last request last_request = self._sequence.last_request # check if the request has non-empty body if not last_request.body_schema: return last_request_def = str_to_hex_def( last_request.method) + last_request.request_id # check if the request has been fuzzed if self._mode == 'normal' and last_request_def in self._fuzzed_requests: self._log( f'Skip visited request {last_request.endpoint_no_dynamic_objects}' ) return self._log( f'Start fuzzing request: {last_request.method} {last_request.endpoint_no_dynamic_objects}' ) self._fuzzed_requests.add(last_request_def) # record and log the body schema to be fuzzed node_num = last_request.body_schema.node_count self._log(f'#node: {node_num}') # reset the response value mapping and global budget self._response_values = {} self._global_count = 0 # get the corresponding request examples self._examples_values = {} if last_request.examples: for example in last_request.examples.body_examples: tag_content = example.get_schema_tag_mapping() for tag in tag_content: if tag in self._examples_values: self._examples_values[tag].append(tag_content[tag]) else: self._examples_values[tag] = [tag_content[tag]] # set the initial starting body schemas if last_request.examples and self._start_with_examples: body_schema_list = list(last_request.examples.body_examples) + [ last_request.body_schema ] else: body_schema_list = [last_request.body_schema] # trigger different fuzzing modes if self._pipelines: self._log('Fuzz using custom recipe') self._run_pipelines(last_request, body_schema_list) elif self._use_feedback: self._log('Fuzz using dynamic feedback') self._run_feedback_fuzzing(last_request, body_schema_list) else: self._log('Fuzz using static strategy') self._run_oneway_fuzzing(last_request, body_schema_list)