Didier Stevens

Thursday 25 July 2013

Update: Lookup Tools

Filed under: My Software,Networking,Update — Didier Stevens @ 20:11

It looks like I didn’t release this update to my lookup tools.

lookup-hosts.py has a new argument: -R. This does a reverse lookup of the IP addresses (thus after it resolved the hostname).

20130725-220124

And now you can also use letters as a counter: test-[a-z].com

lookup-tools_V0_0_2.zip (https)
MD5: 310904722F900FA34C567FC38634124E
SHA256: 85626574A99BF4D2AB786D8C2FF5B8F6649F1FC7410F1786A24EF0201AAF64AA

Thursday 18 July 2013

Update: js-unicode-unescape.1sc

Filed under: 010 Editor,My Software,Update — Didier Stevens @ 18:36

Because I had to use a workaround in my js-unicode-unescape.1sc script to copy an array of bytes to the clipboard, I asked the 010 Editor developers if they could add a function that does exactly this.

They included this new function, CopyBytesToClipboard, in their new version 5.0.

Here is a new version that uses this function:
js-unicode-unescape_v0_0_2.zip (https)
MD5: 6200C4F235CA527E8C0DCD5076CB1C09
SHA256: 2CACC9EE1BB1D1BC4C9FABC6EC3B3440CFF304AA560966B0B531279C369549BB

Wednesday 10 July 2013

The Art Of Defuzzing

Filed under: My Software — Didier Stevens @ 21:05

I had something of a puzzle to solve. A friend asked me to look at a set of files, all of the same size, but with some differences.

After some analysis, it dawned on me that these files were the result of a simple fuzzer applied to a single file. So I quickly wrote a program that took these files as input and reconstituted the original file. Later I wrote a more generic defuzzer. Here is an example:

defuzzer.py result.png a*.png

Number of defuzzed bytes: 171
Number of defuzzed sequences: 33
Length of shortest defuzzed sequence: 1
Length of longest defuzzed sequence: 10
Fuzz bytes:
'A': 171

From the result you can see that the program was able to reconstitute the original file, and that the fuzzer that was used to produce the different a*.png files, overwrote 33 byte-sequences with the character A. The longest sequence was 10 bytes long, the shortest only 1 byte. In total, 171 bytes were overwritten.

defuzzer_v0_0_2.zip (https)
MD5: 75188EF950625B78937C3473D825C582
SHA256: 056AB8BA7F3B2B52F8C7BFC2959D7F1AE3FEAC4BE90C675B2DFF6B521225D93E

Wednesday 3 July 2013

Update: virustotal-search.py

Filed under: My Software,Update — Didier Stevens @ 20:09

Mark Woan reported an issue with virustotal-search.py: sometimes VirusTotal returns a JSON object that the json parser can’t parse.

That’s something I didn’t expect. I’ve added error handling for this case.

virustotal-search_V0_0_9.zip (https)
MD5: FECD02796889CDFE9FA67287F2DE567C
SHA256: 0CE06CBAFC6341835EB8A62377F5C4EB067747EE28E7ED8BB25FD69A4B99FA97

Monday 24 June 2013

shellcode2vba

Filed under: Hacking,My Software,Shellcode — Didier Stevens @ 4:00

This update adds x64 shellcode support to my shellcode2vbs.py script.

shellcode2vba_v0_3.zip (https)
MD5: 44AF2685975346F9DE09E48E7FB855CE
SHA256: 04C42FA26717CCC7BC17A7BEDA02C746CA1A8BC8C6CE184670CD686796B5FF10

Monday 10 June 2013

PDFiD: False Positives

Filed under: My Software,PDF — Didier Stevens @ 8:48

I’m giving a 2-day training on PDF at Brucon 2013. Early-bird price applies til June 15th.

Sometimes PDFiD will give you false positives for /JS and /AA. This happens with files of a couple of MBs or bigger, because it’s statistically very likely that /AA or /JS (only three bytes long) appear inside a stream. And since PDFiD, contrary to pdf-parser, has no notion of pdf objects and streams, it can produce false positives, like this:

PDFiD 0.1.2 CCNPSecurityFIREWALL642617OfficialCertGuide.pdf
 PDF Header: %PDF-1.6
 obj                 6018
 endobj              6017
 stream              1897
 endstream           1897
 xref                   1
 trailer                1
 startxref              1
 /Page                773
 /Encrypt               1
 /ObjStm                0
 /JS                    3
 /JavaScript            0
 /AA                    1
 /OpenAction            0
 /AcroForm              0
 /JBIG2Decode           0
 /RichMedia             0
 /Launch                0
 /EmbeddedFile          0
 /XFA                   0
 /Colors > 2^24         0

And when you search for /AA or /JS with pdf-parser, you will not find objects that have /AA or /JS in their dictionary:

pdf-parser.py -s /AA CCNPSecurityFIREWALL642617OfficialCertGuide.pdf

Up til now, I advised users suspecting false positives, to search the PDF document with a hex editor and see if they found /AA or /JS inside a stream. But now, with the latest version of pdf-parser supporting searching inside a stream, you can do it like this:

pdf-parser.py --searchstream /AA --unfiltered CCNPSecurityFIREWALL642617OfficialCertGuide.pdf
obj 1848 0
 Type: /XObject
 Referencing: 38 0 R
 Contains stream

  <<
     /Length 121194
     /Filter /DCTDecode
     /Width 800
     /Height 600
     /BitsPerComponent 8
     /ColorSpace 38 0 R
     /Intent /RelativeColorimetric
     /Type /XObject
     /Subtype /Image
  >>

Thursday 30 May 2013

pdf-parser: Searching Inside Streams

Filed under: My Software,PDF — Didier Stevens @ 12:38

I’m giving a 2-day training on PDF at Brucon 2013. Early-bird price applies til June 15th.

This new version of pdf-parser comes with options to search inside streams. For example, you can select all objects with the word Linux inside a stream with this command:

pdf-parser.py --searchstream Linux manual.pdf

The search is not case sensitive. To make it case sensitive, use option –casesensitive. Filters are applied to streams (e.g. decompressed) before the search is performed. To search in the raw stream data, use option –unfiltered.

Regular expression searching is done with option –regex. This allows you, for example, to select objects with embedded Flash files. Flash files begin with FWS, CWS or ZWS:

pdf-parser.py --searchstream "^[FCZ]WS" --regex sample.pdf

Regular expression searching has another advantage. You can search for bytes: \xCA\xFE.

 pdf-parser_V0_4_2.zip (https)
MD5: B0C8F02358B386E7924DACB3059F8161
SHA256: E90620320AF6ED8E474B42BF6850E246446391878F87AE34DCDBD1D9945A6671

Wednesday 15 May 2013

Quickpost: Signed PDF Stego

Filed under: Encryption,Hacking,PDF,Quickpost — Didier Stevens @ 14:08

A signed PDF file is just like all signed files with embedded signatures: the signature itself is excluded from the hash calculation.

Open a signed PDF document in a hex editor and search for string /ByteRange. You’ll find something like this:

36 0 obj
<</ByteRange[0 227012 248956 23362 ]            /Contents<308226e106092a864886f7

This indicates which byte sequences  are used for the hash calculation (position and length of each sequence). So in this example, byte sequence 227013-248955 is excluded, because it contains the signature in hex format padded with 0x00 bytes. This padding is not part of the DER signature, you can change it without changing or invalidating the signature.


Quickpost info

Monday 13 May 2013

Adobe Reader and CRLs

Filed under: Encryption,PDF — Didier Stevens @ 18:08

There’s something that I wanted to test out for quite some time, but kept postponing until recently. Adobe Reader will ask confirmation before it retrieves a URL when a PDF document contains an action to do so. But what about the Certificate Revocation List in a signed PDF document?

When you open a signed PDF document with Adobe Reader, the signature gets checked automatically. If the signature is not OK, for example because it doesn’t chain up to a trusted root CA, revocations checks are not performed. In other words, the CRL is not downloaded:

20130426-141512

But when I change the settings so that my root CA is trusted, the signature is considered valid and the CRL is retrieved. No warning is given to the user, it happens automatically and silently. Here is the log entry on my server:

192.168.1.1 – – [26/Apr/2013:11:33:35 -0400] “GET /root.crl HTTP/1.1” 200 709 “-” “PPKHandler”

PPKHandler is the User Agent String.

20130426-173447

20130426-173632

The CRL file can’t be an empty file, and must be signed by the root CA, otherwise the signature is considered invalid.

So when you open a signed PDF document with Adobe Reader, the signature is automatically checked and the CRL is silently downloaded. This is done with a request to the webserver of the commercial CA which issued the certificate (crl.adobe.com, crl.geotrust.com, …). You can change automatic checking with Preferences / Signatures / Verification.

A quick check with Foxit Reader reveals it doesn’t check the signature automatically.

Wednesday 8 May 2013

Howto: Make Your Own Cert And Revocation List With OpenSSL

Filed under: Encryption — Didier Stevens @ 10:34

Here is a variant to my “Howto: Make Your Own Cert With OpenSSL” method. This time, I needed a signing cert with a Certificate Revocation List (CRL) extension and an (empty) CRL. I used instructions from this post.

Adding a CRL extension to a certificate is not difficult, you just need to include a configuration file with one line. But creating a CRL file requires more steps, that’s why I needed this howto. The start of this howto is the same as my previous howto.

First we generate a 4096-bit long RSA key for our root CA and store it in file ca.key:

openssl genrsa -out ca.key 4096

Generating RSA private key, 4096 bit long modulus
...................................................................................++
........................................................................++
e is 65537 (0x10001)

If you want to password-protect this key, add option -des3.

Next, we create our self-signed root CA certificate ca.crt; you’ll need to provide an identity for your root CA:

openssl req -new -x509 -days 1826 -key ca.key -out ca.crt

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:BE
State or Province Name (full name) []:Brussels
Locality Name (eg, city) [Default City]:Brussels
Organization Name (eg, company) [Default Company Ltd]:Didier Stevens
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:Didier Stevens CA
Email Address []:

The -x509 option is used for a self-signed certificate. 1826 days gives us a cert valid for 5 years.

Next step: create our subordinate CA that will be used for the actual signing. First, generate the key:

openssl genrsa -out ia.key 4096

Generating RSA private key, 4096 bit long modulus
.....++
.............................................................................++
e is 65537 (0x10001)

Then, request a certificate for this subordinate CA:

openssl req -new -key ia.key -out ia.csr

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:BE
State or Province Name (full name) []:Brussels
Locality Name (eg, city) [Default City]:Brussels
Organization Name (eg, company) [Default Company Ltd]:Didier Stevens
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:Didier Stevens IA
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Make sure the Common Name is different for both certs, otherwise you’ll get an error. Now, before we process the request for the subordinate CA certificate and get it signed by the root CA, we need to create a couple of files (this step is done with Linux; to create empty file certindex on Windows, you could use Notepad in stead of touch).

touch certindex
echo 01 > certserial
echo 01 > crlnumber

And also create this configuration file (ca.conf):

# Mainly copied from:
# http://swearingscience.com/2009/01/18/openssl-self-signed-ca/

[ ca ]
default_ca = myca

[ crl_ext ]
# issuerAltName=issuer:copy  #this would copy the issuer name to altname
authorityKeyIdentifier=keyid:always

 [ myca ]
 dir = ./
 new_certs_dir = $dir
 unique_subject = no
 certificate = $dir/ca.crt
 database = $dir/certindex
 private_key = $dir/ca.key
 serial = $dir/certserial
 default_days = 730
 default_md = sha1
 policy = myca_policy
 x509_extensions = myca_extensions
 crlnumber = $dir/crlnumber
 default_crl_days = 730

 [ myca_policy ]
 commonName = supplied
 stateOrProvinceName = supplied
 countryName = optional
 emailAddress = optional
 organizationName = supplied
 organizationalUnitName = optional

 [ myca_extensions ]
 basicConstraints = CA:false
 subjectKeyIdentifier = hash
 authorityKeyIdentifier = keyid:always
 keyUsage = digitalSignature,keyEncipherment
 extendedKeyUsage = serverAuth
 crlDistributionPoints = URI:http://example.com/root.crl
 subjectAltName  = @alt_names

 [alt_names]
 DNS.1 = example.com
 DNS.2 = *.example.com

Notice the crlDistributionPoints and DNS. entries pointing to domain example.com. You should change them to your domain.

Now you can sign the request:

openssl ca -batch -config ca.conf -notext -in ia.csr -out ia.crt

Using configuration from ca.conf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName          : PRINTABLE:'BE'
stateOrProvinceName   :ASN.1 12:'Brussels'
localityName          :ASN.1 12:'Brussels'
organizationName      :ASN.1 12:'Didier Stevens'
commonName            :ASN.1 12:'Didier Stevens IA'
Certificate is to be certified until May  3 21:13:02 2015 GMT (730 days)

Write out database with 1 new entries
Data Base Updated

To use this subordinate CA key for Authenticode signatures with Microsoft’s signtool, you’ll have to package the keys and certs in a PKCS12 file:

openssl pkcs12 -export -out ia.p12 -inkey ia.key -in ia.crt -chain -CAfile ca.crt

Enter Export Password:
Verifying - Enter Export Password:

Finally, you can generate the empty CRL file:
openssl ca -config ca.conf -gencrl -keyfile ca.key -cert ca.crt -out root.crl.pem
openssl crl -inform PEM -in root.crl.pem -outform DER -out root.crl
rm root.crl.pem

rm is a Linux command, use del on a Windows machine.

The last step is to host this root.crl file on the webserver pointed to in the CRL extension (http://example.com/root.crl in this example).

If you need to revoke the intermediate certificate, use this command:

openssl ca -config ca.conf -revoke ia.crt -keyfile ca.key -cert ca.crt

And then regenerate the CRL file like explained above.

« Previous PageNext Page »

Blog at WordPress.com.