diff --git a/BappManifest.bmf b/BappManifest.bmf index b8db79a..bd2e9c9 100644 --- a/BappManifest.bmf +++ b/BappManifest.bmf @@ -2,7 +2,7 @@ Uuid: b2244cbb6953442cb3c82fa0a0d908fa ExtensionType: 2 Name: Upload Scanner RepoName: upload-scanner -ScreenVersion: 1.0.8a +ScreenVersion: 1.0.9a SerialVersion: 12 MinPlatformVersion: 0 ProOnly: True diff --git a/UploadScanner.py b/UploadScanner.py index 057769f..3987501 100755 --- a/UploadScanner.py +++ b/UploadScanner.py @@ -654,18 +654,16 @@ def deserialize_settings(self): print e def save_project_setting(self, name, value): - request = """GET /"""+name+""" HTTP/1.0 - # You can ignore this item in the site map. It was created by the UploadScanner extension. - # The reason is that the Burp API is missing a certain functionality to save settings. - # TODO Burp API limitation: This is a hackish way to be able to store project-scope settings - # We don't want to restore requests/responses of tabs in a totally different Burp project - # However, unfortunately there is no saveExtensionProjectSetting in the Burp API :( - # So we have to abuse the addToSiteMap API to store project-specific things - - # Even when using this hack we currently cannot persist Collaborator interaction checks - # (IBurpCollaboratorClientContext is not serializable and Threads loose their Python class - # functionality when unloaded) due to Burp API limitations. - """ + request = "GET /"+name+" HTTP/1.0\r\n\r\n" \ + "You can ignore this item in the site map. It was created by the UploadScanner extension. The \n" \ + "reason is that the Burp API is missing a certain functionality to save settings. \n" \ + "TODO Burp API limitation: This is a hackish way to be able to store project-scope settings.\n" \ + "We don't want to restore requests/responses of tabs in a totally different Burp project.\n" \ + "However, unfortunately there is no saveExtensionProjectSetting in the Burp API :(\n" \ + "So we have to abuse the addToSiteMap API to store project-specific things\n" \ + "Even when using this hack we currently cannot persist Collaborator interaction checks\n" \ + "(IBurpCollaboratorClientContext is not serializable and Threads loose their Python class\n" \ + "functionality when unloaded) due to Burp API limitations." response = None if value: response = "HTTP/1.1 200 OK\r\n" + value @@ -922,7 +920,25 @@ def processHttpMessage(self, _, messageIsRequest, base_request_response): else: issue_copy.detail = issue_copy.detail.replace(BurpExtender.MARKER_URL_CONTENT, "UNKNOWN") - + if matcher.check_xss: + content_disposition = False + for header in headers: + if header.lower().startswith("content-disposition: attachment"): + # This is a special case for "Content-Disposition: attachment" handling + desc = "

This response includes the 'Content-Disposition: attachment' header. " \ + "This means the file is not shown inline, but downloaded in browsers. " \ + "So this might be unexploitable. However, as there were so many bypasses " \ + "for this in the past, this is still flagged as an issue. Certain old " \ + "browsers could still be convinced into inlining the file and therefore " \ + "execute the XSS payload. Moreover, browser plugins (flash/pdf/Java) might " \ + "also not honor the Content-Disposition header. There have also been browser " \ + "bugs that allowed executing the XSS. Moreover, an HTTP header injection can " \ + "be used to still execute the XSS. See " \ + "https://markitzeroday.com/xss/bypass/2018/04/17/defeating-content-disposition.html" \ + " for further information." + issue_copy.detail += desc + issue_copy.severityPy = "Tentative" + break self._create_download_scan_issue(base_request_response, issue_copy) # As the matcher was now triggered, we can remove it as it should not trigger again, @@ -2504,18 +2520,38 @@ def _xxe_svg_external_image(self, injector, burp_colab): # External Image with '.format(BurpExtender.MARKER_COLLAB_URL)) basename = BurpExtender.DOWNLOAD_ME + self.FILE_START + "SvgXlink" - name = "XXE/SSRF via SVG" # Xlink" + name = "XXE/SSRF via SVG" # Xlink severity = "High" confidence = "Certain" detail = "A Burp Colaborator interaction was detected when uploading an SVG image with an Xlink reference " \ - "which contains a burp colaborator URL. This means that Server Side Request Forgery is possible. " \ - 'The payload was . ' + \ + "which contains a burp collaborator URL. This means that Server Side Request Forgery is possible. " \ + 'The payload was . ' + \ "Usually you will be able to read local files, eg. local pictures. " \ "Interactions:

".format(BurpExtender.MARKER_COLLAB_URL) issue = self._create_issue_template(injector.get_brr(), name, detail, confidence, severity) colab_tests.extend(self._send_collaborator(injector, burp_colab, self.SVG_TYPES, basename, content_xlink, issue, redownload=True)) + # External iFrame according to https://twitter.com/akhilreni_hs/status/1113762867881185281 and + # https://gist.github.com/akhil-reni/5ed75c28a5406c300597431eafcdae2d + content_iframe = '' \ + ''.format(str(injector.opts.image_width), + str(injector.opts.image_height), + BurpExtender.MARKER_COLLAB_URL) + basename = BurpExtender.DOWNLOAD_ME + self.FILE_START + "SvgIframe" + name = "XXE/SSRF via SVG" # Iframe + severity = "High" + confidence = "Certain" + detail = "A Burp Colaborator interaction was detected when uploading an SVG image with an iframe reference " \ + "which contains a burp collaborator URL. This means that Server Side Request Forgery is possible. " \ + 'The payload was