Wednesday, May 24, 2017

In this blogpost I disclose some additional
information about a vulnerability I showed during my presentation at Appsec
Belfast 2017.

In the presentation I showed that it is possible to
trigger JavaScript execution in any web page as soon as a PDF is trusted.

Although I am aware that a trusted PDF has quite a lot
of permissions, I want to explain in this post how FDF can be used to execute
JavaScript in a targeted domain.

!NOTE: THIS ONLY WORKS WITH THE ADOBE PDF BROWSER
PLUGIN!

What is FDF

In this post I am not going to talk about PDF at all,
as the used PDF for this attack does not matter. It just needs to be properly
rendered inside the browser and be hosted on the same domain as the injected
FDF (eg. your own server like http://attacker.com).

So what is FDF. FDF is a file structure, which allows
to exchange field values, Javascript, annotations (eg. comments) and other
information between PDFs. There are different ways to load this type of files
into a PDF, but I will focus on one particular as it is the simplest one.

It has a similar structure to PDF but I am not going
into any details. The reason being is that FDF defines two keys in his
root structure we are going to use for this attack:

/F: The source file or target file: the PDF document
file that this FDF file was exported from or is intended to be imported
into.

/Target: The name of a browser frame in which the
underlying PDF document is to be opened. This mimics the behavior of the target
attribute in HTML tags.

Basically these two keys allow us to define the PDF, which the FDF
belongs to and the window name it is currently loaded.

What do you think happens if we define the following keys:

/F (javascript:alert(location))

/Target (anywindowname)

As long as the PDF, which loads the FDF, is not
trusted, you will get a warning box that tells you that certain features are
blocked and you need to trust this PDF.

As soon as you trust the PDF, the specified URL in /F
key is actually injected in the targeted window name. If it happens to be that
the tab, with the specified name, has eg. google.com loaded, the JavaScript
will be executed in the context of google.com.

By looking at the specified index.html, you will see
that I use the PDF open parameters to load a FDF file. The specification for
this behaviour can be found here: PDF open parameters

But enough of the details. Here is a step by step
guide, with the payloads copy&paste ready:

6. Given that my PDF is really simple, you will get a
dialog: There was an error parsing this pdf document (just ignore it, you could
also use a valid PDF, but then I couldn't copy&paste it in my blog because
of the size)

7. After you clicked that you trusted the document
once, nothing will happen but the yellow warning sign is not displayed.

8. Click the UXSS button. An alert should show up in
the victim page (in my default example: google.com)

// Edit: https://twitter.com/evilcos was so kind to host the PoC on his webserver.
// He modified the FDF payload, so that document.cookie will be alerted
==> http://xssor.io/s/pdf.html

If any problems occur: Write me on twitter
@insertscript:

Note: Why I am disclosing this? It requires clicks and
yes I am aware that clickjacking could help but given that most of the time
users only need to click once or maybe twice to execute a local program, I feel
quite safe disclosing this vulnerability.