Example #1
0
 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.")
Example #2
0
 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).")
Example #3
0
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
Example #4
0
    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.")