From 259f1e6f2c235cbabc43268f32bde8d009c41cc3 Mon Sep 17 00:00:00 2001 From: soffensive Date: Sat, 15 Dec 2018 14:09:49 +0100 Subject: [PATCH 1/4] detect only js and json file extensions --- DetectDynamicJS.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/DetectDynamicJS.py b/DetectDynamicJS.py index fcafd51..cfdf19c 100644 --- a/DetectDynamicJS.py +++ b/DetectDynamicJS.py @@ -48,7 +48,7 @@ def registerExtenderCallbacks(self, callbacks): # Define some constants self.validStatusCodes = [200] self.ifields = ['cookie', 'authorization'] - self.possibleFileEndings = ["js", "jsp", "json"] + self.possibleFileEndings = ["js", "json"] self.possibleContentTypes = [ "javascript", "ecmascript", "jscript", "json"] self.ichars = ['{', '<'] @@ -199,14 +199,16 @@ def hasScriptFileEnding(self, requestResponse): Checks for common script file endings """ url = self._helpers.analyzeRequest(requestResponse).getUrl() - fileEnding = ".totallynotit" + extractedFileEnding = ".totallynotit" urlSplit = str(url).split("/") if len(urlSplit) != 0: fileName = urlSplit[len(urlSplit) - 1] fileNameSplit = fileName.split(".") - fileEnding = fileNameSplit[len(fileNameSplit) - 1] - fileEnding = fileEnding.split("?")[0] - return any(fileEnd in fileEnding for fileEnd in self.possibleFileEndings) + extractedFileEnding = fileNameSplit.pop() # pop() returns last item of list when called without index + extractedFileEnding = extractedFileEnding.lower() # account for upper case letters + extractedFileEnding = extractedFileEnding.split("?")[0] + return extractedFileEnding in self.possibleFileEndings # will not detect, e.g., 'jspa' as script file ending + def hasScriptContentType(self, response): """ Checks for common content types, that could be scripts """ From 3dcf93fa0cd13c8b7ef6b78c4bfe358a7d3fcfb9 Mon Sep 17 00:00:00 2001 From: soffensive Date: Sat, 15 Dec 2018 14:34:58 +0100 Subject: [PATCH 2/4] before sending a request check if there is any authentication information --- DetectDynamicJS.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/DetectDynamicJS.py b/DetectDynamicJS.py index cfdf19c..f3f0cd0 100644 --- a/DetectDynamicJS.py +++ b/DetectDynamicJS.py @@ -76,6 +76,7 @@ def doPassiveScan(self, baseRequestResponse): baseRequestResponse = self.switchMethod(baseRequestResponse) if (not self.isScannableRequest(baseRequestResponse) or not self.isScript(baseRequestResponse) or + not self.containsAuthenticationCharacteristics(baseRequestResponse) or self.isProtected(baseRequestResponse)): return None newRequestResponse = self.sendUnauthenticatedRequest(baseRequestResponse) @@ -94,6 +95,19 @@ def doPassiveScan(self, baseRequestResponse): scan_issues.append(issue) return scan_issues + def containsAuthenticationCharacteristics(self, requestResponse): + """ + Check whether the request contains ambient authority information + returns a boolean + """ + reqHeaders = self._helpers.analyzeRequest(requestResponse).getHeaders() + newHeaders = [] + for header in reqHeaders: + headerName = header.split(':')[0].lower() + if headerName in self.ifields: + return True + return False + def sendUnauthenticatedRequest(self, requestResponse): """ Send the request without ambient authority information From 1f73652a10c793d752517d5e879523ff79bc38a6 Mon Sep 17 00:00:00 2001 From: soffensive Date: Sat, 15 Dec 2018 16:17:26 +0100 Subject: [PATCH 3/4] remove duplicate has authentication characteristic --- DetectDynamicJS.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/DetectDynamicJS.py b/DetectDynamicJS.py index f3f0cd0..a2b3119 100644 --- a/DetectDynamicJS.py +++ b/DetectDynamicJS.py @@ -170,8 +170,7 @@ def isScannableRequest(self, requestResponse): """ response = requestResponse.getResponse() responseInfo = self._helpers.analyzeResponse(response) - return (self.hasValidStatusCode(responseInfo.getStatusCode()) and - self.hasAuthenticationCharacteristic(requestResponse)) + return self.hasValidStatusCode(responseInfo.getStatusCode()) def hasValidStatusCode(self, statusCode): """ @@ -179,15 +178,6 @@ def hasValidStatusCode(self, statusCode): """ return statusCode in self.validStatusCodes - def hasAuthenticationCharacteristic(self, requestResponse): - """ - Detects whether the request contains some kind of authentication - information. - """ - reqHeaders = self._helpers.analyzeRequest(requestResponse).getHeaders() - hfields = [h.split(':')[0] for h in reqHeaders] - return any(h for h in self.ifields if h not in str(hfields).lower()) - def stripAuthenticationCharacteristics(self, requestResponse): """ Strip possible ambient authority information. From 244e3095f16ea14ac8d676b0d50898d28e56fe47 Mon Sep 17 00:00:00 2001 From: soffensive Date: Sat, 15 Dec 2018 16:19:17 +0100 Subject: [PATCH 4/4] perform checks before switching POST to GET (which causes the sending of an HTTP request) --- DetectDynamicJS.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/DetectDynamicJS.py b/DetectDynamicJS.py index a2b3119..ff9293b 100644 --- a/DetectDynamicJS.py +++ b/DetectDynamicJS.py @@ -72,13 +72,15 @@ def doPassiveScan(self, baseRequestResponse): # for this test. scan_issues = [] - if not self.isGet(baseRequestResponse.getRequest()): - baseRequestResponse = self.switchMethod(baseRequestResponse) if (not self.isScannableRequest(baseRequestResponse) or not self.isScript(baseRequestResponse) or not self.containsAuthenticationCharacteristics(baseRequestResponse) or self.isProtected(baseRequestResponse)): return None + + if not self.isGet(baseRequestResponse.getRequest()): + baseRequestResponse = self.switchMethod(baseRequestResponse) + newRequestResponse = self.sendUnauthenticatedRequest(baseRequestResponse) issue = self.compareResponses(newRequestResponse, baseRequestResponse) if not issue: