Ejemplo n.º 1
0
    def attack_upload(self, original_request):
        # Should not yield request as it will mark it as attacked
        mutator = FileMutator(payloads=self.payloads)
        current_parameter = None
        vulnerable_parameter = False

        for mutated_request, parameter, payload, flags in mutator.mutate(original_request):
            try:
                if current_parameter != parameter:
                    # Forget what we know about current parameter
                    current_parameter = parameter
                    vulnerable_parameter = False
                elif vulnerable_parameter:
                    # If parameter is vulnerable, just skip till next parameter
                    continue

                if self.verbose == 2:
                    print("[¨] {0}".format(mutated_request))

                try:
                    response = self.crawler.send(mutated_request)
                except RequestException as exception:
                    yield exception
                else:
                    pattern = search_pattern(response.content, self.flag_to_patterns(flags))
                    if pattern and not self.false_positive(original_request, pattern):
                        self.add_vuln(
                            request_id=original_request.path_id,
                            category=Vulnerability.XXE,
                            level=Vulnerability.HIGH_LEVEL,
                            request=mutated_request,
                            info="XXE vulnerability leading to file disclosure",
                            parameter=parameter
                        )

                        self.log_red("---")
                        self.log_red(
                            Vulnerability.MSG_PARAM_INJECT,
                            self.MSG_VULN,
                            original_request.url,
                            parameter
                        )
                        self.log_red(Vulnerability.MSG_EVIL_REQUEST)
                        self.log_red(mutated_request.http_repr())
                        self.log_red("---")
                        vulnerable_parameter = True
                        self.vulnerables.add(original_request.path_id)
            except KeyboardInterrupt as exception:
                yield exception
Ejemplo n.º 2
0
    async def attack_upload(self, original_request):
        mutator = FileMutator(payloads=self.payloads)
        current_parameter = None
        vulnerable_parameter = False

        for mutated_request, parameter, _payload, flags in mutator.mutate(original_request):
            if current_parameter != parameter:
                # Forget what we know about current parameter
                current_parameter = parameter
                vulnerable_parameter = False
            elif vulnerable_parameter:
                # If parameter is vulnerable, just skip till next parameter
                continue

            if self.verbose == 2:
                print("[¨] {0}".format(mutated_request))

            try:
                response = await self.crawler.async_send(mutated_request)
            except RequestError:
                self.network_errors += 1
            else:
                pattern = search_pattern(response.content, self.flag_to_patterns(flags))
                if pattern and not await self.false_positive(original_request, pattern):
                    self.add_vuln(
                        request_id=original_request.path_id,
                        category=NAME,
                        level=HIGH_LEVEL,
                        request=mutated_request,
                        info="XXE vulnerability leading to file disclosure",
                        parameter=parameter
                    )

                    self.log_red("---")
                    self.log_red(
                        Messages.MSG_PARAM_INJECT,
                        self.MSG_VULN,
                        original_request.url,
                        parameter
                    )
                    self.log_red(Messages.MSG_EVIL_REQUEST)
                    self.log_red(mutated_request.http_repr())
                    self.log_red("---")
                    vulnerable_parameter = True
                    self.vulnerables.add(original_request.path_id)
Ejemplo n.º 3
0
    def finish(self):
        endpoint_url = "{}get_xxe.php?session_id={}".format(
            self.internal_endpoint, self._session_id)
        print(
            _("[*] Asking endpoint URL {} for results, please wait...").format(
                endpoint_url))
        sleep(2)
        # A la fin des attaques on questionne le endpoint pour savoir s'il a été contacté
        endpoint_request = Request(endpoint_url)
        try:
            response = self.crawler.send(endpoint_request)
        except RequestException:
            self.network_errors += 1
            print(
                _("[!] Unable to request endpoint URL '{}'").format(
                    self.internal_endpoint))
            return

        data = response.json
        if not isinstance(data, dict):
            return

        for request_id in data:
            original_request = self.persister.get_path_by_id(request_id)
            if original_request is None:
                continue
                # raise ValueError("Could not find the original request with ID {}".format(request_id))

            page = original_request.path
            for hex_param in data[request_id]:
                parameter = unhexlify(hex_param).decode("utf-8")

                for infos in data[request_id][hex_param]:
                    request_url = infos["url"]
                    # Date in ISO format
                    request_date = infos["date"]
                    request_ip = infos["ip"]
                    request_size = infos["size"]
                    payload_name = infos["payload"]

                    if parameter == "QUERY_STRING":
                        vuln_message = Messages.MSG_QS_INJECT.format(
                            self.MSG_VULN, page)
                    elif parameter == "raw body":
                        vuln_message = _(
                            "Out-Of-Band {0} by sending raw XML in request body"
                        ).format(self.MSG_VULN)
                    else:
                        vuln_message = _(
                            "Out-Of-Band {0} via injection in the parameter {1}"
                        ).format(self.MSG_VULN, parameter)

                    more_infos = _(
                        "The target sent {0} bytes of data to the endpoint at {1} with IP {2}.\n"
                        "Received data can be seen at {3}.").format(
                            request_size, request_date, request_ip,
                            request_url)

                    vuln_message += "\n" + more_infos

                    # placeholder if shit happens
                    payload = (
                        "<xml>"
                        "See https://phonexicum.github.io/infosec/xxe.html#attack-vectors"
                        "</xml>")

                    for payload, flags in self.payloads:
                        if "{}.dtd".format(payload_name) in payload:
                            payload = payload.replace(
                                "[PATH_ID]", str(original_request.path_id))
                            payload = payload.replace("[PARAM_AS_HEX]",
                                                      "72617720626f6479")
                            break

                    if parameter == "raw body":
                        mutated_request = Request(original_request.path,
                                                  method="POST",
                                                  enctype="text/xml",
                                                  post_params=payload)
                    elif parameter == "QUERY_STRING":
                        mutated_request = Request("{}?{}".format(
                            original_request.path, quote(payload)),
                                                  method="GET")
                    elif parameter in original_request.get_keys or parameter in original_request.post_keys:
                        mutator = Mutator(
                            methods="G"
                            if original_request.method == "GET" else "P",
                            payloads=[(payload, Flags())],
                            qs_inject=self.must_attack_query_string,
                            parameters=[parameter],
                            skip=self.options.get("skipped_parameters"))

                        mutated_request, __, __, __ = next(
                            mutator.mutate(original_request))
                    else:
                        mutator = FileMutator(
                            payloads=[(payload, Flags())],
                            parameters=[parameter],
                            skip=self.options.get("skipped_parameters"))
                        mutated_request, __, __, __ = next(
                            mutator.mutate(original_request))

                    self.add_vuln(request_id=original_request.path_id,
                                  category=NAME,
                                  level=HIGH_LEVEL,
                                  request=mutated_request,
                                  info=vuln_message,
                                  parameter=parameter)

                    self.log_red("---")
                    self.log_red(vuln_message)
                    self.log_red(Messages.MSG_EVIL_REQUEST)
                    self.log_red(mutated_request.http_repr())
                    self.log_red("---")