Intrepidus Group
Insight

An executable wolf in a PDF sheep’s clothing

Posted: April 13, 2010 – 12:47 pm | Author: | Filed under: pdf

A few of us over at Intrepidus Group have been following the recent issues with the PDF format and the software that renders PDF documents closely.  Didier Stevens has an excellent blog detailing his work with the PDF format. A recent podcast from Eurotrash Security included an interview with Didier. Based on his research, the podcast and the ongoing research in the field it seemed that it would only be a matter of time before his PoC shows up in the wild. However, I wanted to see how difficult it would be to go from a well-known command launching PDF to one that embeds an executable and controls the message in the security prompt.  The goal is to recreate, or at least emulate the proof of concept from Didier that has caused the PDF specification, Adobe and the developers behind Foxit reader so much consternation.

In the Eurotrash podcast Didier discusses his five stage loading technique for embedding an executable into a PDF. The main tools involved in his technique are Batch files and VBScript. Stage 1, the first step, was to create a batch file and then execute it. The batch file creates an executable extracting VBScript file. The executable extracting VBScript then pulls the executable out of the PDF document and writes it to disk. Finally, the extractor then launches the executable it has written to disk. The main trick is to get a clean, extractable, ASCII representation of the binary payload in the PDF file. I decided to try this on my own. In my mind it is very important to understand how difficult this exploit is to create and what the risk is to the world at large.

I started with Didier’s command launching PDF. There is no malicious activity going on in this PDF. It launches an existing command on the user’s system. The user gets a prompt similar to this one:

If the user has already checked the, “Do not show this message again” box, a command prompt would simply have opened. This is not terribly interesting on its own. The discussion of why multimedia embedding and command launching are in the PDF specification is a topic for a different time. So, how do we go from that standard command launching action to controlling the contents of this dialog box and embedding an arbitrary binary in the PDF document? That was my main question I set out to answer. Knowing the high-level technique Didier used and some of the pitfalls he encountered I knew many things not to try. My first goal was to control the message in the dialog box as that is a critical component of the social engineering aspect of this attack. This meant a trip to the Adobe website to download the 8MB PDF specification. I started by reading the command launching section.  It indicates that you can pass parameters to commands launched. The parameters are what the PDF specification refers to as a byte string. A left angle bracket < followed by a number of hex digits and closed by a right angle bracket >.

A bit of Python scripting and I had a byte string encoding script to automate the process. I used this to create and pass in some test parameters. My first thought was pass in a series of newline characters and then a message I wanted to display. I encoded the parameters and gave it a shot. Almost immediately I was rewarded with:

The command prompt still launched as well. The parameters byte string to cmd.exe might look something like this: <2F6320D43726560A0A0A0A0A0A0A0A4E6F74653A205468697320>. The way this works is by including several newline characters (\x0A) to push the social engineering message down to the bottom of the dialog box. This encouraged me to continue the research. It turns out this was the most simple part of the whole attack. The next step was to create a file on the system using command prompt parameters. Through experimentation, trial and error I was able to create a multiple line file with parameters sent to cmd.exe when the PDF was launched. The next step was to create the two VBScript files. This is where the technique diverges just a little from Didier’s. It is possible to write to the VBScript file and then execute it as well as the resulting stage 2 VBScript file with one compound cmd.exe parameter. This technique cuts out the batch file step and made my life a bit less complicated.

The stage one VBScript extracts the stage two VBScript from the PDF document. The stage two VBScript has an ASCII encoded binary embedded in it. It then opens the payload executable file and writes it to permanent storage. The final step for the extractor is to launch the executable. When everything goes off it looks like this:

The following program greets the victim after clicking through the dialog:

Pressing any key causes the program to close. There are many caveats and limitations with the basic, but functional, techniques. The first limitation is the length of a command parameter. The length of the launch action parameter limits the size of the stage 1 binary to a relatively small amount. The second limitation is the size of the embedded executable. VBScript limits the amount of data that can be stored into one variable, limiting the overall size of the embedded payload.  The payload binary is UPX packed and weighs in at about 11KiB. The PoC did not tolerate the encoding of a 50KiB binary. The next limitation is the working directory the PDF attack code runs from. If other PDF documents are open, the current PoC may not be able to find the PDF, which means the stage 1 VBScript will not be able to create the stage 2 executable extractor VBScript. It would not take very much effort to embed larger payloads and polish this into a working and robust attack. The goal was to determine the overall difficulty of reaching the point where a proof of concept could embed executable in a PDF, extract it, and executed via a launch action.

We have decided to release the proof of concept PDF. If you download and open this PDF and click through the dialog be aware. The proof of concept creates two VBScript files and one executable file in the directory that it was opened in. In order for the proof of concept to work you must have no other PDF documents open or the start directory will be wrong and the stage 2 extractor will not be able to find the PDF document (and thus the executable payload). Click here to download the Proof of Concept PDF . This proof of concept was tested on Adobe Acrobat Reader 9.0.0 on Windows XP and Adobe Acrobat Reader 9.3.0 on Windows 7.

If you wish to disable this and lock down your Acrobat reader, which is highly encouraged, please visit Didier’s blog and read his post on the topic.

Download the embedded executable launching proof of concept here. Make sure you download it and save it locally and open it outside of the browser. It probably won’t work in the browser due to the working directory. I leave it as an exercise to the reader to improve the payloads to work more reliably. Also, it should be fairly simple to build an executable that propagates this payload to any PDF on the user’s file system. Check out some research done on this here and here.

UPDATE: thanks to sudosecure.net for leading me over to an example of malware abusing this very feature in the wild.

Both comments and trackbacks are currently closed.

3 Comments

  1. Posted April 13, 2010 at 10:06 pm | Permalink

    @ jeremy — lol, so this wasn’t you last night right:

  2. xx
    Posted April 20, 2010 at 3:44 am | Permalink

    infact
    Dim bl
    Function c(d)
    c=Chr(d)
    End Function
    b=Array(c(77),c(90),c(144),c(0),c(3),c(0),c(0),c(0),c(4),c(0),c(0),c(0),c(255),c(255),c(0),c(0), “”)
    bl=16
    Set fso = CreateObject(“Scripting.FileSystemObject”)
    Set f = fso.OpenTextFile(“me.exe”, 2, True)
    For i = 0 To bl
    f.write(b(i))
    Next
    f.close()

    the code above would write the bytes btween 0x7f~0xff intead of 0×00,so the executeable would not work!
    like this:
    4D5A00000300000004000000FFFF0000….
    it should be
    4D5A90000300000004000000FFFF0000….

  3. Jeremy Allen
    Posted April 20, 2010 at 12:42 pm | Permalink

    I am not quite sure what the issue was/is. This script reliably reproduced null bytes in all of the files I tested. I tested with very large binaries and the CRC32 and MD5 checksums of the files encoded with this script came out just fine.

One Trackback

  1. [...] This post was mentioned on Twitter by Jeremy Allen and Dean H. Saxe, Intrepidus Group. Intrepidus Group said: “An executable wolf in a PDF sheep’s clothing” — http://bit.ly/cR47tg [blog] (hat tip @didierstevens) ^Z [...]

image

This site is protected with Urban Giraffe's plugin 'HTML Purified' and Edward Z. Yang's Powered by HTML Purifier. 24576 items have been purified.