def is_detection_set(self, args): det_functions = ["contains", "resp_code_det", "response_time"] args_set = False for name in det_functions: if args[name] is not None: return Error(self.owtf, "You need to specify at least one Detection Function.")
def require(self, args, params): param_missing = False for param in params: if args[param] is None: param_missing = True print "Specify: --%s" % param if param_missing: Error(self.owtf, "Missing Parameter(s).")
def find_length(owtf, http_helper, lsig, url, method, detection_struct, ch, headers, body=None): """This function finds the length of the fuzzing placeholder""" size = 8192 minv = 0 http_client = HTTPClient() new_url = url new_body = body new_headers = headers payload = "" for loop in range(0, 15): # used to avoid potential deadloops payload = size * ch if lsig in url: new_url = url.replace(lsig, payload) elif body is not None and lsig in body: new_body = body.replace(lsig, payload) elif headers is not None and lsig in str(headers): raw_val = str(headers) raw_val = raw_val.replace(lsig, payload) new_headers = ast.literal_eval(str(raw_val)) else: Error(owtf, "Length signature not found!") request = http_helper.create_http_request(method, new_url, new_body, new_headers) try: response = http_client.fetch(request) except HTTPError as e: if e.response: response = e.response for struct in detection_struct: if struct["method"](response, struct["arguments"]): http_client.close() return binary_search( http_helper, lsig, minv, size, url, method, detection_struct, ch, headers, body) minv = size size *= 2
def start(self, args): # Initializations self.sig = args["fuzzing_signature"] or self.sig self.pm = PlaceholderManager(self.sig) target = args["target"] methods = self.init_methods(args) headers = self.init_headers(args) data = args["data"] or "" self.init_detection_struct(args) self.init_request.headers = headers self.http_helper = HTTPHelper(self.init_request) self.fuzzer = Fuzzer(self.http_helper) # Finding the length of a placeholder if args["mode"] == "length": self.require(args, ["accepted_value"]) self.is_detection_set(args) if len(methods) > 1: Error(self.owtf, "Only you need to specify only one Method") print "Scanning mode: Length Detection" ch = args["accepted_value"][0] length = find_length(self.owtf, self.http_helper, self.length_signature, target, methods[0], self.detection_struct, ch, headers, data) print "Placeholder Allowed Length = %s" % str(length) # Detecting Allowed Sources elif args["mode"] == "detect_accepted_sources": self.is_detection_set(args) self.require(args, ["methods", "param_name", "accepted_value", "param_source"]) if len(methods) > 1: Error(self.owtf, "Only you need to specify only one Method") print "Scanning mode: Allowed Sources Detection" accepted_method = methods[0] param_name = args["param_name"] accepted_value = args["accepted_value"] param_source = args["param_source"] requests = detect_accepted_sources(self.http_helper, target, data, headers, param_name, param_source, accepted_value, accepted_method) responses = self.fuzz(args, requests) analyze_accepted_sources(responses, self.detection_struct) elif args["mode"] == "content_type_tamper": print "Tampering Content-Type mode" cnt_types = load_payload_file("./payloads/HTTP/content_types.txt") new_headers = self.http_helper.add_header_param(headers, "Content-Type", self.fsig) self.pm = PlaceholderManager(self.sig) # cnt_types = Payloads requests = self.pm.transformed_http_requests(self.http_helper, methods, target, cnt_types, new_headers, data) responses = self.fuzz(args, requests) for response in responses: print "[->]Request" print_request(response) print "[<-]Response" print_response(response) print # HPP modes elif args["mode"] == "asp_hpp" or args["mode"] == "param_overwriting": self.require(args, ["param_name", "param_source", "payloads"]) param_name = args["param_name"] param_source = args["param_source"] self.is_detection_set(args) payloads = [] for p_file in args["payloads"]: payloads += load_payload_file(p_file) if args["mode"] == "asp_hpp": print "Scanning mode: ASP HPP Parameter Splitting" requests = asp_hpp(self.http_helper, methods, payloads, param_name, param_source, target, headers, data) responses = self.fuzz(args, requests) elif args["mode"] == "param_overwriting": requests = param_overwrite(self.http_helper, param_name, param_source, payloads[0], target, data, headers) responses = self.fuzz(args, requests) analyze_responses(responses, self.http_helper, self.detection_struct) elif args["mode"] == "detect_chars": self.is_detection_set(args) payloads = [] for i in range(0, 256): payloads.append(chr(i)) requests = self.pm.transformed_http_requests(self.http_helper, methods, target, payloads, headers, data) responses = self.fuzz(args, requests) sent_payloads = analyze_chars(responses, self.http_helper, self.detection_struct) payloads = [] if sent_payloads["detected"]: # urlencode blocked chars print print "URL encoding bad characters" for bad_char in sent_payloads["detected"]: payloads.append(urlencode(bad_char)) requests = self.pm.transformed_http_requests(self.http_helper, methods, target, payloads, headers, data) responses = self.fuzz(args, requests) analyze_encoded_chars(responses, self.http_helper, self.detection_struct) print print "UnicodeURL encoding bad characters" payloads = [] # unicode urlencode blocked chars for bad_char in sent_payloads["detected"]: payloads.append(unicode_urlencode(bad_char)) requests = self.pm.transformed_http_requests(self.http_helper, methods, target, payloads, headers, data) responses = self.fuzz(args, requests) analyze_encoded_chars(responses, self.http_helper, self.detection_struct) # Finding a white-listed character good_char = None for char in string.letters: good_char = char break if not good_char: for char in string.digits: good_char = char break if not good_char: good_char = sent_payloads["undetected"][0] print print "Sending a detected char followed by an undetected" payloads = [] # add an accepted char before a blocked char for bad_char in sent_payloads["detected"]: payloads.append(bad_char + good_char) requests = self.pm.transformed_http_requests(self.http_helper, methods, target, payloads, headers, data) responses = self.fuzz(args, requests) analyze_encoded_chars(responses, self.http_helper, self.detection_struct) print print "Sending a detected char after an undetected" payloads = [] for bad_char in sent_payloads["detected"]: payloads.append(good_char + bad_char) requests = self.pm.transformed_http_requests(self.http_helper, methods, target, payloads, headers, data) responses = self.fuzz(args, requests) analyze_encoded_chars(responses, self.http_helper, self.detection_struct) print "Sending an undetected char after a detected" payloads = [] for bad_char in sent_payloads["detected"]: payloads.append(bad_char + good_char) requests = self.pm.transformed_http_requests(self.http_helper, methods, target, payloads, headers, data) responses = self.fuzz(args, requests) analyze_encoded_chars(responses, self.http_helper, self.detection_struct) print "Sending an detected char surrounded by undetected chars" payloads = [] for bad_char in sent_payloads["detected"]: payloads.append(good_char + bad_char + good_char) requests = self.pm.transformed_http_requests(self.http_helper, methods, target, payloads, headers, data) responses = self.fuzz(args, requests) analyze_encoded_chars(responses, self.http_helper, self.detection_struct) # Fuzzing mode elif args["mode"] == "fuzz": fuzzing_placeholders = PlaceholderManager.get_placeholder_number(self.template_signature_re, str(args)) if fuzzing_placeholders > 1: Error(self.owtf, "Multiple fuzzing placeholder signatures found. " "Only one fuzzing placeholder is supported.") elif fuzzing_placeholders == 0: Error(self.owtf, "No fuzzing placeholder signatures found.") self.is_detection_set(args) payloads = [] if args["payloads"]: for p_file in args["payloads"]: payloads += load_payload_file(p_file) else: payloads.append("") print "Scanning mode: Fuzzing Using placeholders" requests = self.pm.transformed_http_requests(self.http_helper, methods, target, payloads, headers, data) responses = self.fuzz(args, requests) analyze_responses(responses, self.http_helper, self.detection_struct) elif args["mode"] == "show_transform_functions": print transformations_info() elif args["mode"] == "overchar": self.require(args, ["payloads", "accepted_value"]) length = int(args["length"][0]) accepted_value = args["accepted_value"][0] payloads = [] for p_file in args["payloads"]: payloads += load_payload_file(p_file) payloads = [(length - len(payload)) * accepted_value + payload for payload in payloads] requests = self.pm.transformed_http_requests(self.http_helper, methods, target, payloads, headers, data) responses = self.fuzz(args, requests) analyze_responses(responses, self.http_helper, self.detection_struct) else: Error(self.owtf, "Unknown bypassing mode.")