From 4c5544dc85f8af91624fca48a11948e4782b4131 Mon Sep 17 00:00:00 2001 From: Maksym Adamantis Date: Wed, 12 Feb 2025 18:43:32 +0100 Subject: [PATCH] bugfix: working filters --- authorization/authorization.py | 152 +++++++++++++++++++-------------- gui/interception_filters.py | 6 +- 2 files changed, 92 insertions(+), 66 deletions(-) diff --git a/authorization/authorization.py b/authorization/authorization.py index c519abe..16de0d2 100644 --- a/authorization/authorization.py +++ b/authorization/authorization.py @@ -79,99 +79,123 @@ def message_passed_interception_filters(self, messageInfo): resBodyBytes = messageInfo.getResponse()[resInfo.getBodyOffset():] resStr = self._helpers.bytesToString(resBodyBytes) - message_passed_filters = True for i in range(0, self.IFList.getModel().getSize()): interceptionFilter = self.IFList.getModel().getElementAt(i) - interceptionFilterTitle = interceptionFilter.split(":")[0] + try: + interceptionFilterTitle, interceptionFilterContent = interceptionFilter.split(":", 1) + interceptionFilterContent = interceptionFilterContent[1:] + except Exception as e: + print(interceptionFilter) + print(e) + continue + if interceptionFilterTitle == "Scope items only": currentURL = URL(urlString) if not self._callbacks.isInScope(currentURL): - message_passed_filters = False + return False if interceptionFilterTitle == "URL Contains (simple string)": - if interceptionFilter[30:] not in urlString: - message_passed_filters = False + if interceptionFilterContent not in urlString: + return False if interceptionFilterTitle == "URL Contains (regex)": - regex_string = interceptionFilter[22:] + regex_string = interceptionFilterContent if re.search(regex_string, urlString, re.IGNORECASE) is None: - message_passed_filters = False + return False if interceptionFilterTitle == "URL Not Contains (simple string)": - if interceptionFilter[34:] in urlString: - message_passed_filters = False + if interceptionFilterContent in urlString: + return False if interceptionFilterTitle == "URL Not Contains (regex)": - regex_string = interceptionFilter[26:] + regex_string = interceptionFilterContent if not re.search(regex_string, urlString, re.IGNORECASE) is None: - message_passed_filters = False + return False if interceptionFilterTitle == "Request Body contains (simple string)": - if interceptionFilter[40:] not in bodyStr: - message_passed_filters = False + if interceptionFilterContent not in bodyStr: + return False if interceptionFilterTitle == "Request Body contains (regex)": - regex_string = interceptionFilter[32:] + regex_string = interceptionFilterContent if re.search(regex_string, bodyStr, re.IGNORECASE) is None: - message_passed_filters = False + return False if interceptionFilterTitle == "Request Body NOT contains (simple string)": - if interceptionFilter[44:] in bodyStr: - message_passed_filters = False + if interceptionFilterContent in bodyStr: + return False if interceptionFilterTitle == "Request Body Not contains (regex)": - regex_string = interceptionFilter[36:] + regex_string = interceptionFilterContent if not re.search(regex_string, bodyStr, re.IGNORECASE) is None: - message_passed_filters = False + return False if interceptionFilterTitle == "Response Body contains (simple string)": - if interceptionFilter[41:] not in resStr: - message_passed_filters = False + if interceptionFilterContent not in resStr: + return False if interceptionFilterTitle == "Response Body contains (regex)": - regex_string = interceptionFilter[33:] + regex_string = interceptionFilterContent if re.search(regex_string, resStr, re.IGNORECASE) is None: - message_passed_filters = False + return False if interceptionFilterTitle == "Response Body NOT contains (simple string)": - if interceptionFilter[45:] in resStr: - message_passed_filters = False + if interceptionFilterContent in resStr: + return False if interceptionFilterTitle == "Response Body Not contains (regex)": - regex_string = interceptionFilter[37:] + regex_string = interceptionFilterContent if not re.search(regex_string, resStr, re.IGNORECASE) is None: - message_passed_filters = False - - if interceptionFilterTitle == "Header contains": - for header in list(resInfo.getHeaders()): - if interceptionFilter[17:] in header: - message_passed_filters = False - - if interceptionFilterTitle == "Header doesn't contain": - for header in list(resInfo.getHeaders()): - if not interceptionFilter[17:] in header: - message_passed_filters = False + return False + + if interceptionFilterTitle == "Request headers contain": + if not any([ + interceptionFilterContent in h + for h in reqInfo.getHeaders() + ]): + return False + + if interceptionFilterTitle == "Request headers don't contain": + if any([ + interceptionFilterContent in h + for h in reqInfo.getHeaders() + ]): + return False + + if interceptionFilterTitle == "Response headers contain": + if not any([ + interceptionFilterContent in h + for h in resInfo.getHeaders() + ]): + return False + + if interceptionFilterTitle == "Response headers don't contain": + if any([ + interceptionFilterContent in h + for h in resInfo.getHeaders() + ]): + return False if interceptionFilterTitle == "Only HTTP methods (newline separated)": - filterMethods = interceptionFilter[39:].split("\n") + filterMethods = interceptionFilterContent.split("\n") filterMethods = [x.lower() for x in filterMethods] reqMethod = str(self._helpers.analyzeRequest(messageInfo).getMethod()) if reqMethod.lower() not in filterMethods: - message_passed_filters = False + return False if interceptionFilterTitle == "Ignore HTTP methods (newline separated)": - filterMethods = interceptionFilter[41:].split("\n") + filterMethods = interceptionFilterContent.split("\n") filterMethods = [x.lower() for x in filterMethods] reqMethod = str(self._helpers.analyzeRequest(messageInfo).getMethod()) if reqMethod.lower() in filterMethods: - message_passed_filters = False + return False if interceptionFilterTitle == "Ignore OPTIONS requests": reqMethod = str(self._helpers.analyzeRequest(messageInfo).getMethod()) if reqMethod == "OPTIONS": - message_passed_filters = False + return False - return message_passed_filters + return True def handle_message(self, toolFlag, messageIsRequest, messageInfo): if tool_needs_to_be_ignored(self, toolFlag): @@ -223,41 +247,41 @@ def auth_enforced_via_enforcement_detectors(self, filters, requestResponse, andO for filter in filters: filter = self._helpers.bytesToString(bytes(filter)) - filter_kv = filter.split(":", 1) - inverse = "NOT" in filter_kv[0] - filter_kv[0] = filter_kv[0].replace(" NOT", "") - filter = ":".join(filter_kv) - - if filter.startswith("Status code equals: "): - statusCode = filter[20:] + inverse = "NOT" in filter + filter = filter.replace(" NOT", "") + filter_name, filter_content = filter.split(':', 1) + filter_content = filter_content[1:] # remove the ' ' + + if filter_name == "Status code equals": + statusCode = filter_content filterMatched = inverse ^ isStatusCodesReturned(self, requestResponse, statusCode) - elif filter.startswith("Headers (simple string): "): - filterMatched = inverse ^ (filter[25:] in self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()])) + elif filter_name == "Headers (simple string)": + filterMatched = inverse ^ (filter_content in self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()])) - elif filter.startswith("Headers (regex): "): - regex_string = filter[17:] + elif filter_name == "Headers (regex)": + regex_string = filter_content p = re.compile(regex_string, re.IGNORECASE) filterMatched = inverse ^ bool(p.search(self._helpers.bytesToString(requestResponse.getResponse()[0:analyzedResponse.getBodyOffset()]))) - elif filter.startswith("Body (simple string): "): - filterMatched = inverse ^ (filter[22:] in self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():])) + elif filter_name == "Body (simple string)": + filterMatched = inverse ^ (filter_content in self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():])) - elif filter.startswith("Body (regex): "): - regex_string = filter[14:] + elif filter_name == "Body (regex)": + regex_string = filter_content p = re.compile(regex_string, re.IGNORECASE) filterMatched = inverse ^ bool(p.search(self._helpers.bytesToString(requestResponse.getResponse()[analyzedResponse.getBodyOffset():]))) - elif filter.startswith("Full response (simple string): "): - filterMatched = inverse ^ (filter[31:] in self._helpers.bytesToString(requestResponse.getResponse())) + elif filter_name == "Full response (simple string)": + filterMatched = inverse ^ (filter_content in self._helpers.bytesToString(requestResponse.getResponse())) - elif filter.startswith("Full response (regex): "): - regex_string = filter[23:] + elif filter_name == "Full response (regex)": + regex_string = filter_content p = re.compile(regex_string, re.IGNORECASE) filterMatched = inverse ^ bool(p.search(self._helpers.bytesToString(requestResponse.getResponse()))) - elif filter.startswith("Full response length: "): - filterMatched = inverse ^ (str(len(response)) == filter[22:].strip()) + elif filter_name == "Full response length": + filterMatched = inverse ^ (str(len(response)) == filter_content.strip()) if andEnforcementCheck: if auth_enforced and not filterMatched: diff --git a/gui/interception_filters.py b/gui/interception_filters.py index bbd2d3e..7917c2c 100644 --- a/gui/interception_filters.py +++ b/gui/interception_filters.py @@ -39,8 +39,10 @@ def draw(self): "Response Body contains (regex): ", "Response Body NOT contains (simple string): ", "Response Body Not contains (regex): ", - "Header contains: ", - "Header doesn't contain: ", + "Request headers contain: ", + "Request headers don't contain: ", + "Response headers contain: ", + "Response headers don't contain: ", "Only HTTP methods (newline separated): ", "Ignore HTTP methods (newline separated): ", "Ignore spider requests: (Content is not required)",