[Cryptography-dev] Parsing DER from PE File

Robert Simmons rsimmons0 at gmail.com
Sun Dec 23 04:17:27 EST 2018


import os
import pathlib
import pefile

target =
pathlib.Path().home().joinpath('Desktop').joinpath('HWID_4_0_6YMBWX.exe')
fname = str(target)
totsize = os.path.getsize(target)
pe = pefile.PE(fname)
pe.parse_data_directories(directories=[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']])
sigoff = 0
siglen = 0
for s in pe.__structures__:
    if s.name == 'IMAGE_DIRECTORY_ENTRY_SECURITY':
        sigoff = s.VirtualAddress
        siglen = s.Size
pe.close()
with open(fname, 'rb') as fh:
    fh.seek(sigoff)
    thesig = fh.read(siglen)

from cryptography.hazmat.backends.openssl.backend import backend
from cryptography.hazmat.backends.openssl import x509

bio = backend._bytes_to_bio(thesig[8:])
pkcs7 = backend._lib.d2i_PKCS7_bio(bio.bio, backend._ffi.NULL)
certs = []
for i in range(backend._lib.sk_X509_num(signers)):
    x509_ptr = backend._lib.sk_X509_value(signers, i)
    certs.append(x509._Certificate(backend, x509_ptr))

That's the exact code I'm trying to run with the provided code snippet at
the end. If you want to follow along with the exact file I'm working with:
hxxps://dangerous[.]link/d9b72c43-1bdd-415b-b15f-3a436b26bca8

The password to that file is "infected" and btw: it is live malware, so
please treat it accordingly. Run code on it in a safe environment for
handling malware.

On Sun, Dec 23, 2018 at 4:10 AM Robert Simmons <rsimmons0 at gmail.com> wrote:

> I've added the use case to the issue as requested. I tried the code
> snippet, but the contents of signers is missing. What should that be?
>
> NameError: name 'signers' is not defined
>
> On Fri, Dec 21, 2018 at 11:21 AM Paul Kehrer <paul.l.kehrer at gmail.com>
> wrote:
>
>> Out of curiosity, does the following code load the cert you expect? der
>> should be the bytes of extracted.der:
>>
>> from cryptography.hazmat.backends.openssl.backend import backend
>> from cryptography.hazmat.backends.openssl import x509
>>
>> bio = backend._bytes_to_bio(der)
>> pkcs7 = backend._lib.d2i_PKCS7_bio(bio.bio, backend._ffi.NULL)
>> certs = []
>> for i in range(backend._lib.sk_X509_num(signers)):
>>     x509_ptr = backend._lib.sk_X509_value(signers, i)
>>     certs.append(x509._Certificate(backend, x509_ptr))
>>
>> Certs will be a list of signer certificates -- in this case, just one
>> cert in the list. Please note that this code does not manage memory
>> correctly so it should strictly be used to test if the cert you need is
>> being properly extracted :)
>>
>> -Paul (reaperhulk)
>>
>>
>> On December 21, 2018 at 8:02:13 AM, Paul Kehrer (paul.l.kehrer at gmail.com)
>> wrote:
>>
>> Thanks, that's perfect. Looking at this data it's actually a PKCS7
>> envelope holding multiple certificates and at the moment cryptography
>> unfortunately has no interface for parsing PKCS7. If you wouldn't mind
>> sharing your use case directly on
>> https://github.com/pyca/cryptography/issues/3983 then it will help me
>> when I'm prioritizing features for upcoming releases.
>>
>> -Paul
>>
>>
>> On December 20, 2018 at 2:23:11 PM, Robert Simmons (rsimmons0 at gmail.com)
>> wrote:
>>
>> Definitely. I've attached the DER data as extracted from the PE file
>> using the following code:
>>
>> pe = pefile.PE(fname)
>>
>> pe.parse_data_directories(directories=[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']])
>> sigoff = 0
>> siglen = 0
>> for s in pe.__structures__:
>>     if s.name == 'IMAGE_DIRECTORY_ENTRY_SECURITY':
>>         sigoff = s.VirtualAddress
>>         siglen = s.Size
>> pe.close()
>> with open(fname, 'rb') as fh:
>>     fh.seek(sigoff)
>>     thesig = fh.read(siglen)
>> with open('extracted.der', 'wb') as fh:
>>     fh.write(thesig[8:])
>>
>> I've attached extracted.der as a zip file to maintain integrity as an
>> attachment.
>>
>> Thanks!
>>
>> On Thu, Dec 20, 2018 at 11:12 AM Paul Kehrer <paul.l.kehrer at gmail.com>
>> wrote:
>>
>>> Could you give us an example (in hex or b64 or something) so we can
>>> easily reproduce? Make sure any certs you're giving us don't contain
>>> sensitive data of course.
>>>
>>> -Paul
>>>
>>>
>>> On December 19, 2018 at 11:55:04 PM, Robert Simmons (rsimmons0 at gmail.com)
>>> wrote:
>>>
>>> I've asked this question on Stack Overflow here:
>>> https://stackoverflow.com/q/53862702/1033217
>>>
>>> I have compared my code to Dider Stevens's disitool here (examine the
>>> function ExtractDigitalSignature):
>>>
>>> https://github.com/DidierStevens/DidierStevensSuite/blob/master/disitool.py
>>>
>>> When I load that extracted file into a variable and try to parse it with
>>> cryptography, it fails. If I pipe the same file to openssl on the command
>>> line, it works.
>>>
>>> I am thinking this has to do with the number of certificates in the
>>> directory in the PE file. There can be three (cert, intermediate CA, and
>>> CA, etc).
>>>
>>> Any idea what's going on?
>>> _______________________________________________
>>> Cryptography-dev mailing list
>>> Cryptography-dev at python.org
>>> https://mail.python.org/mailman/listinfo/cryptography-dev
>>>
>>> _______________________________________________
>>> Cryptography-dev mailing list
>>> Cryptography-dev at python.org
>>> https://mail.python.org/mailman/listinfo/cryptography-dev
>>>
>> _______________________________________________
>> Cryptography-dev mailing list
>> Cryptography-dev at python.org
>> https://mail.python.org/mailman/listinfo/cryptography-dev
>>
>> _______________________________________________
>> Cryptography-dev mailing list
>> Cryptography-dev at python.org
>> https://mail.python.org/mailman/listinfo/cryptography-dev
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cryptography-dev/attachments/20181223/b9f255c9/attachment-0001.html>


More information about the Cryptography-dev mailing list