Didier Stevens

Tuesday 6 August 2019

Update: pdf-parser.py Version 0.7.2

Filed under: My Software,PDF,Update — Didier Stevens @ 0:00

This is a bugfix version.

pdf-parser_V0_7_2.zip (https)
MD5: 7D417F2313FF505AC96B80D80495BB78
SHA256: 3CDB98A57DAABC98382BFA361390AE3637F96852F6F078D03A7922766AE14B57

Saturday 23 March 2019

Quickpost: PDF Tools Download Feature

Filed under: My Software,PDF,Quickpost — Didier Stevens @ 9:34

When I’m asked to perform a quick check of an online PDF document, that I expect to be benign, I will just point my PDF tools to the online document. When you provide an URL argument to pdf-parser, it will download the document and perform the analysis (without writing it to disk).


Quickpost info


 

Thursday 7 March 2019

Analyzing a Phishing PDF with /ObjStm

Filed under: maldoc,Malware,My Software,PDF — Didier Stevens @ 0:00

I got hold of a phishing PDF where the /URI is hiding inside a stream object (/ObjStm).

First I start the analysis with pdfid.py:

There is no /URI reported, but remark that the PDF contains 5 stream objects (/ObjStm). These can contain /URIs. In the past, I would search and decompress these stream objects with pdf-parser.py, and then pipe the result through pdfid.py, in order to detect /URIs (or other objects that require further analysis).

Since pdf-parser.py version 0.7.0, I prefer another method: using option -O to let pdf-parser.py extract and parse the objects inside stream objects.

With option -a (here combined with option -O), I can get statistics and keywords just like with pdfid:

Now I can see that there is a /URI inside the PDF (object 43).

Thus I can use option -k to get the value of /URI entries, combined with option -O to look inside stream objects:

And here I have the /URI.

Another method, is to select object 43:

From this output, we also see that object 43 is inside stream object 16.

Remark: if you use option -O on a PDF that does not contain stream objects (/ObjStm), pdf-parser will behave as if you didn’t provide this option. Hence, if you want, you can always use option -O to analyze PDFs.

Wednesday 6 March 2019

Update: pdf-parser.py Version 0.7.1

Filed under: My Software,PDF,Update — Didier Stevens @ 0:00

This is a bug fix version for statistics (-a).

pdf-parser_V0_7_1.zip (https)
MD5: 1480D3BF602686C9E7C2FE82AC6C963B
SHA256: D2C8E0599A84127C36656AA2600F9668A3CB12EF306D28752D6D8AC436A89D1A

Thursday 28 February 2019

Update: pdf-parser.py Version 0.7.0

Filed under: My Software,PDF,Update — Didier Stevens @ 0:00

This new version of pdf-parser brings support for analysis of stream objects (/ObjStm). Use new option -O to enable this mode.

Stream objects (/ObjStm) are objects that contain other objects: they have a stream, containing other objects. These contained objects can not have a stream.

pdfid.py detects the presence of stream objects:

But pdfid can not look inside a stream, to figure out what objects are inside. That’s why I always say to use pdf-parser to select and decompress stream objects, and then pipe this through pdfid:

When pdf-parser parses a stream object, it does not parse the content of its stream:

This changes with this new version of pdf-parser. When option -O is used, pdf-parser extracts objects from /ObjStm streams and handles them like normal objects. In the following example, object 2 is contained in object 1:

pdf-parser provides statistics for a PDF’s content with option -a:

Combining option -a with option -O includes objects present inside stream objects (this is an alternative for combining both tools: pdf-parser -s objstm -f a.pdf | pdfid -f):

This output shows that /JavaScript can be found in object 7. We need to use option -O to find object 7 “hiding” in object 1:

If we forget to use option -O, object 7 is not found:

Here is a video showing this new feature:

pdf-parser_V0_7_0.zip (https)
MD5: CDE355BB3FCACE3C4EDBC762E632F9AB
SHA256: 219FF0BB729C4478679A79163CA9942296ACF49E4EC06D128CBC53FBEE25FF05

Tuesday 23 October 2018

Update: pdf-parser.py Version 0.6.9

Filed under: My Software,PDF,Update — Didier Stevens @ 0:00

This new version of pdf-parser.py brings 2 new features; the idea came to me during private & public trainings I gave on malicious documents (if you are interested in a training, please get in touch).

The statistics option (-a –stats) has been enhanced with a search for keywords section:

In this section, the result of searches for particular keywords (that might indicate a malicious PDF) is displayed: you get the number of hits followed by the indices of the objects that contain this keyword.

In the example above, we see that object 11 contains JavaScript.

Remark that this section is the result of a search command (-s): search in pdf-parser is not case-senstive and partial (unlike PDFiD). That explains why /AA is found in object 37, while it’s actually /Aacute:

pdf-parser will also read file pdfid.ini (if present) so that the personal keywords you added to PDFiD are also used by pdf-parser.

–overridingfilters is a new option: it allows for the processing of streams with a different filter (or filter chain) than the one specified in the object’s dictionary. Use value raw to obtain the raw stream, without filtering.

pdf-parser_V0_6_9.zip (https)
MD5: 27D65A96FEAF157360ACBBAAB9748D27
SHA256: 3F102595B9EAE5842A1B4723EF965344AE3AB01F90D85ECA96E9678A6C7092B7

Friday 3 August 2018

Update: PDFiD.py Version 0.2.5

Filed under: My Software,PDF,Update — Didier Stevens @ 0:00

It’s the second time now that a friend reports to me that PDFiD produces no output at all when a pdf is analyzed.

In both cases, the filename was something like sample[1].pdf (a file you could find in Internet Explorer’s cache, for example).

PDFiD can process multiple files, and accepts UNIX shell-style wildcards. Not only * and ?, but also []. So with a filename like sample[1].pdf, PDFiD is actually looking for a file with filename sample1.pdf. Which it doesn’t find, and thus produces no output.

About two years ago, when first a friend reported this, I added option -l –literal. If you use this option, then PDFiD will do no wildcard expansion, and will thus find file sample[1].pdf.

Recently, another friend had the same problem. And was not aware of the existence of option -l.

This new version of PDFiD will display a warning when you use wildcard characters in filenames (without option -l) and when no files match. Like this:

I also renamed option –literal to –literalfilenames, to be consistent across my tools.

pdfid_v0_2_5.zip (https)
MD5: 9B835D9E934A7AA7E68C3649A7AA5DAF
SHA256: 4DD43D7BDA885C5A579FC1F797E93A536E1DB5A4AB52A9337759A69D3B0250E0

Thursday 31 May 2018

PDFiD: GoToE and GoToR Detection (“NTLM Credential Theft”)

Filed under: My Software,PDF — Didier Stevens @ 0:00

The article “NTLM Credentials Theft via PDF Files” explains how PDF documents can refer to a resource via UNC paths. This is done using  PDF names /GoToE or /GoToR.

My tool pdfid.py can now be extended to report /GoToE and /GoToR usage in a PDF file, without having to change the source code. You just have to edit the pdfid.ini file (or create it) to include these names, like this:

[keywords]
/URI
/GoToE
/GoToR

Using pdfid configured like this on a “credential stealing PDF” gives the following result:

pdfid.ini has to be located in the same directory as pdfid.py. And remember that names in the PDF language are case-sensitive.

 

Monday 12 February 2018

Update: pdfid.py Version 0.2.4

Filed under: My Software,Update — Didier Stevens @ 0:00

This is a bug fix version for  bugs reported by different users, more details in history.

pdfid_v0_2_4.zip (https)
MD5: 36D5554BC881E7E21382ADA1305ED6F4
SHA256: C1DA287C9C06E3158F79CECF9C2E9A7773FC57FC92021F17B79DDD4B1E5DBB2A

Friday 29 December 2017

Cracking Encrypted PDFs – Conclusion

Filed under: Encryption,Forensics,Hacking,PDF — Didier Stevens @ 0:00

TL;DR: PDFs protected with 40-bit keys can not guarantee confidentiality, even with strong passwords. When you protect your PDFs with a password, you have to encrypt your PDFs with strong passwords and use long enough keys. The PDF specification has evolved over time, and with it, the encryption options you have. There are many encryption options today, you are no longer restricted to 40-bit keys. You can use 128-bit or 256-bit keys too.

There is a trade-off too: the more advanced encryption option you use, the more recent the PDF reader must be to support the encryption option you selected. Older PDF readers are not able to handle 256-bit AES for example.

Since each application capable of creating PDFs will have different options and descriptions for encryption, I can not tell you what options to use for your particular application. There are just too many different applications and versions. But if you are not sure if you selected an encryption option that will use long enough keys, you can always check the /Encrypt dictionary of the PDF you created, for example with my pdf-parser (in this example /Length 128 tells us a 128-bit key is used):

Or you can use QPDF to encrypt an existing PDF (I’ll publish a blog post later with encryption examples for QPDF).

But don’t use 40-bit keys, unless confidentiality is not important to you:

I first showed (almost 4 years ago) how PDFs with 40-bit keys can be decrypted in minutes, using a commercial tool with rainbow tables. This video illustrates this.

Later I showed how this can be done with free, open source tools: Hashcat and John the Ripper. But although I could recover the encryption key using Hashcat, I still had to use a commercial tool to do the actual decryption with the key recovered by Hashcat.

Today, this is no longer the case: in this series of blog posts, I show how to recover the password, how to recover the key and how to decrypt with the key, all with free, open source tools.

Overview of the complete blog post series:

 

Next Page »

Blog at WordPress.com.