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