From 959042021f804e1df6dd2427d8076649d642547d Mon Sep 17 00:00:00 2001 From: mathkar Date: Thu, 20 Sep 2018 12:00:31 -0700 Subject: [PATCH 1/4] Changes to check for response other than 200 OK --- DetectDynamicJS.py | 78 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 15 deletions(-) diff --git a/DetectDynamicJS.py b/DetectDynamicJS.py index fcafd51..be5aac8 100644 --- a/DetectDynamicJS.py +++ b/DetectDynamicJS.py @@ -27,6 +27,7 @@ from array import array from time import sleep import difflib + import re except ImportError: print "Failed to load dependencies. This issue maybe caused by using an unstable Jython version." @@ -71,7 +72,6 @@ def doPassiveScan(self, baseRequestResponse): # This is, because the insertionPoint idea doesn't work well # for this test. scan_issues = [] - if not self.isGet(baseRequestResponse.getRequest()): baseRequestResponse = self.switchMethod(baseRequestResponse) if (not self.isScannableRequest(baseRequestResponse) or @@ -79,20 +79,39 @@ def doPassiveScan(self, baseRequestResponse): self.isProtected(baseRequestResponse)): return None newRequestResponse = self.sendUnauthenticatedRequest(baseRequestResponse) - issue = self.compareResponses(newRequestResponse, baseRequestResponse) - if not issue: - return None - # If response is script, check if script is dynamic - if self.isScript(newRequestResponse): - # sleep, in case this is a generically time stamped script - sleep(1) - secondRequestResponse = self.sendUnauthenticatedRequest(baseRequestResponse) - isDynamic = self.compareResponses(secondRequestResponse, newRequestResponse) - if isDynamic: - issue = self.reportDynamicOnly(newRequestResponse, baseRequestResponse, - secondRequestResponse) - scan_issues.append(issue) - return scan_issues + if(self.isScannableRequest(newRequestResponse)): + issue = self.compareResponses(newRequestResponse, baseRequestResponse) + if not issue: + return None + # If response is script, check if script is dynamic + if self.isScript(newRequestResponse): + # sleep, in case this is a generically time stamped script + sleep(1) + secondRequestResponse = self.sendUnauthenticatedRequest(baseRequestResponse) + isDynamic = self.compareResponses(secondRequestResponse, newRequestResponse) + if isDynamic: + issue = self.reportDynamicOnly(newRequestResponse, baseRequestResponse, + secondRequestResponse) + scan_issues.append(issue) + return scan_issues + else: + if(self.hasScriptContent(newRequestResponse)): + issue = self.compareResponses(newRequestResponse, baseRequestResponse) + if not issue: + return None + + if self.isScript(newRequestResponse): + # sleep, in case this is a generically time stamped script + sleep(1) + secondRequestResponse = self.sendUnauthenticatedRequest(baseRequestResponse) + isDynamic = self.compareResponses(secondRequestResponse, newRequestResponse) + if isDynamic: + issue = self.reportDynamicOnly(newRequestResponse, baseRequestResponse, + secondRequestResponse) + scan_issues.append(issue) + return scan_issues + else: + return None def sendUnauthenticatedRequest(self, requestResponse): """ @@ -341,6 +360,35 @@ def consolidateDuplicateIssues(self, existingIssue, newIssue): else: return 0 + def has401StatusCode(self, requestResponse): + """ + Checks if the status code of the request is 401 + """ + response = requestResponse.getResponse() + responseInfo = self._helpers.analyzeResponse(response) + statusCode = responseInfo.getStatusCode() + return statusCode == 401 + + def hasScriptContent(self,requestResponse): + """ + Checks if the response of the request contains the scipt content + """ + nResponse = requestResponse.getResponse() + nResponseInfo = self._helpers.analyzeResponse(nResponse) + nBodyOffset = nResponseInfo.getBodyOffset() + nBody = nResponse.tostring()[nBodyOffset:] + first_char = nBody[0:1] + if(first_char in "[" or first_char in "{"): + return "first_char" + matchvar = re.match( r'(.*)\s*(var|let|const) ([a-zA-Z])+\s*=(.*)|(.*)\s*(window.) ([a-zA-Z])+\s*=(.*)', nBody,re.M|re.I) + matchfunction=re.match( r'(.*)\s*function\((.*)\)(.*)', nBody,re.M|re.I) + + if matchvar: + return matchvar + if matchfunction: + return matchfunction + else: + return None class ScanIssue(IScanIssue): From 1365145ab51c4a3f03a54afbb47c64f9a4c11944 Mon Sep 17 00:00:00 2001 From: mathkar Date: Mon, 1 Oct 2018 14:35:19 -0700 Subject: [PATCH 2/4] Changes as per comments given in previous pull request --- DetectDynamicJS.py | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/DetectDynamicJS.py b/DetectDynamicJS.py index be5aac8..d22e2a4 100644 --- a/DetectDynamicJS.py +++ b/DetectDynamicJS.py @@ -79,7 +79,9 @@ def doPassiveScan(self, baseRequestResponse): self.isProtected(baseRequestResponse)): return None newRequestResponse = self.sendUnauthenticatedRequest(baseRequestResponse) - if(self.isScannableRequest(newRequestResponse)): + if((not (self.isScannableRequest(newRequestResponse)) and + self.hasScriptContent(newRequestResponse)) or + self.isScannableRequest(newRequestResponse)): issue = self.compareResponses(newRequestResponse, baseRequestResponse) if not issue: return None @@ -92,26 +94,8 @@ def doPassiveScan(self, baseRequestResponse): if isDynamic: issue = self.reportDynamicOnly(newRequestResponse, baseRequestResponse, secondRequestResponse) - scan_issues.append(issue) + scan_issues.append(issue) return scan_issues - else: - if(self.hasScriptContent(newRequestResponse)): - issue = self.compareResponses(newRequestResponse, baseRequestResponse) - if not issue: - return None - - if self.isScript(newRequestResponse): - # sleep, in case this is a generically time stamped script - sleep(1) - secondRequestResponse = self.sendUnauthenticatedRequest(baseRequestResponse) - isDynamic = self.compareResponses(secondRequestResponse, newRequestResponse) - if isDynamic: - issue = self.reportDynamicOnly(newRequestResponse, baseRequestResponse, - secondRequestResponse) - scan_issues.append(issue) - return scan_issues - else: - return None def sendUnauthenticatedRequest(self, requestResponse): """ From 0a49b68bc6bc9f1c0960e6610f51c8a6ba961a09 Mon Sep 17 00:00:00 2001 From: mathkar Date: Mon, 8 Oct 2018 12:09:52 -0700 Subject: [PATCH 3/4] Add ScriptContent check --- DetectDynamicJS.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DetectDynamicJS.py b/DetectDynamicJS.py index d22e2a4..680fad5 100644 --- a/DetectDynamicJS.py +++ b/DetectDynamicJS.py @@ -74,7 +74,8 @@ def doPassiveScan(self, baseRequestResponse): scan_issues = [] if not self.isGet(baseRequestResponse.getRequest()): baseRequestResponse = self.switchMethod(baseRequestResponse) - if (not self.isScannableRequest(baseRequestResponse) or + if ((not (self.isScannableRequest(baseRequestResponse)) and + self.hasScriptContent(baseRequestResponse)) or not self.isScript(baseRequestResponse) or self.isProtected(baseRequestResponse)): return None From 68204158c6115c5d3aa33058fbd7ada05d8fd8d1 Mon Sep 17 00:00:00 2001 From: mathkar Date: Wed, 28 Nov 2018 16:57:31 -0800 Subject: [PATCH 4/4] Typo fixed --- DetectDynamicJS.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/DetectDynamicJS.py b/DetectDynamicJS.py index 680fad5..cb8b686 100644 --- a/DetectDynamicJS.py +++ b/DetectDynamicJS.py @@ -345,18 +345,9 @@ def consolidateDuplicateIssues(self, existingIssue, newIssue): else: return 0 - def has401StatusCode(self, requestResponse): - """ - Checks if the status code of the request is 401 - """ - response = requestResponse.getResponse() - responseInfo = self._helpers.analyzeResponse(response) - statusCode = responseInfo.getStatusCode() - return statusCode == 401 - def hasScriptContent(self,requestResponse): """ - Checks if the response of the request contains the scipt content + Checks if the response of the request contains the script content """ nResponse = requestResponse.getResponse() nResponseInfo = self._helpers.analyzeResponse(nResponse)