mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
Add doc/sample for CryptObject
This commit is contained in:
@@ -42,12 +42,24 @@ CertificateContext
|
||||
|
||||
.. autoclass:: CertificateContext
|
||||
|
||||
|
||||
EHCERTSTORE
|
||||
'''''''''''
|
||||
|
||||
.. autoclass:: EHCERTSTORE
|
||||
|
||||
|
||||
CryptObject
|
||||
'''''''''''
|
||||
|
||||
.. autoclass:: CryptObject
|
||||
|
||||
.. warning::
|
||||
|
||||
The methods and property of this class will problably change as I haven't yet had the time
|
||||
to try it out in real cases.
|
||||
|
||||
|
||||
CryptContext
|
||||
''''''''''''
|
||||
|
||||
|
||||
+23
-10
@@ -525,7 +525,7 @@ This sample is a working POC able to generate key-pair, encrypt and decrypt file
|
||||
|
||||
Ouput::
|
||||
|
||||
(cmd λ) python samples\encryption_demo.py genkey YOLOCERTIF mykey --pfxpassword MYPASSWORD
|
||||
(cmd λ) python ..\samples\encryption_demo.py genkey YOLOCERTIF mykey --pfxpassword MYPASSWORD
|
||||
<CertificatContext "YOLOCERTIF" serial="1b a4 3e 17 f7 ed ec ab 4f f8 11 46 48 e9 29 25">
|
||||
|
||||
(cmd λ) ls
|
||||
@@ -533,7 +533,7 @@ Ouput::
|
||||
|
||||
(cmd λ) echo|set /p="my secret message" > message.txt
|
||||
|
||||
(cmd λ) python samples\encryption_demo.py crypt message.txt message.crypt mykey.cer
|
||||
(cmd λ) python ..\samples\encryption_demo.py crypt message.txt message.crypt mykey.cer
|
||||
Encryption done. Result:
|
||||
bytearray(b'0\x82\x01\x19\x06\t*\x86H\x86\xf7\r\x01\x07\x03\xa0\x82\x01\n0\x82\x01\x06\x02\x01\x001\x81\xc30\x81
|
||||
\xc0\x02\x01\x000)0\x151\x130\x11\x06\x03U\x04\x03\x13\nYOLOCERTIF\x02\x10\x1b\xa4>\x17\xf7\xed\xec\xabO\xf8\x11
|
||||
@@ -543,7 +543,7 @@ Ouput::
|
||||
\xc6\x12x\x1am\xc8\x01t\xac\xa6\xf3#\x02\xd4J \x8eZ\xbb\x10W\xe1 0;\x06\t*\x86H\x86\xf7\r\x01\x07\x010\x14\x06\x08*
|
||||
\x86H\x86\xf7\r\x03\x07\x04\x08\x14F\x04\xad\xed9\xed<\x80\x18\x80]6\xccTV\xbc\xb8*\x84QY!~\xb3\n\x1aV\xd4\rf\xd1n:')
|
||||
|
||||
(cmd λ) python samples\encryption_demo.py decrypt message.crypt mykey.pfx BADPASS
|
||||
(cmd λ) python ..\samples\encryption_demo.py decrypt message.crypt mykey.pfx BADPASS
|
||||
Traceback (most recent call last):
|
||||
File "..\samples\encryption_demo.py", line 103, in <module>
|
||||
res.func(**res.__dict__)
|
||||
@@ -576,13 +576,13 @@ Ouput::
|
||||
|
||||
(cmd λ) python .\samples\certificate.py
|
||||
Analysing certificate: <CertificateContext "Microsoft Windows" serial="33 00 00 01 06 6e c3 25 c4 31 c9 18 0e 00 00 00 00 01 06">
|
||||
* name: <Microsoft Windows>
|
||||
* issuer: <Microsoft Windows Production PCA 2011>
|
||||
* raw_serial: <[51, 0, 0, 1, 6, 110, 195, 37, 196, 49, 201, 24, 14, 0, 0, 0, 0, 1, 6]>
|
||||
* serial: <33 00 00 01 06 6e c3 25 c4 31 c9 18 0e 00 00 00 00 01 06>
|
||||
* encoded start: <bytearray(b'0\x82\x05\x040\x82\x03\xec\xa0\x03\x02\x01\x02\x02\x133\x00\x00\x01\x06')>
|
||||
* name: <Microsoft Windows>
|
||||
* issuer: <Microsoft Windows Production PCA 2011>
|
||||
* raw_serial: <[51, 0, 0, 1, 6, 110, 195, 37, 196, 49, 201, 24, 14, 0, 0, 0, 0, 1, 6]>
|
||||
* serial: <33 00 00 01 06 6e c3 25 c4 31 c9 18 0e 00 00 00 00 01 06>
|
||||
* encoded start: <bytearray(b'0\x82\x05\x040\x82\x03\xec\xa0\x03\x02\x01\x02\x02\x133\x00\x00\x01\x06')>
|
||||
|
||||
This certificate has 1 certificate chain
|
||||
This certificate has 1 certificate chain(s)
|
||||
Chain 0:
|
||||
<CertificateContext "Microsoft Windows" serial="33 00 00 01 06 6e c3 25 c4 31 c9 18 0e 00 00 00 00 01 06">:
|
||||
* issuer: <Microsoft Windows Production PCA 2011>
|
||||
@@ -593,4 +593,17 @@ Ouput::
|
||||
|
||||
Looking for <Microsoft Root Certificate Authority 2010> in trusted certificates
|
||||
matches = [<CertificateContext "Microsoft Root Certificate Authority 2010" serial="28 cc 3a 25 bf ba 44 ac 44 9a 9b 58 6b 43 39 aa">]
|
||||
Found it !
|
||||
Found it !
|
||||
|
||||
== PE Analysis ==
|
||||
Target sha1 = <059cb1ba1a41433a18dd8f87422c2ac3bf35b7b8>
|
||||
Analysing <CryptObject "C:\windows\system32\ntdll.dll" content_type=CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED(0xaL)>
|
||||
File has 1 signer(s):
|
||||
Signer 0:
|
||||
* Issuer: bytearray(b'0\x81\x841\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x130\x11\x06\x03U\x04\x08\x13\nWashington1\x100\x0e\x06\x03U\x04\x07\x13\x07Redmond1\x1e0\x1c\x06\x03U\x04\n\x13\x15Microsoft Corporation1.0,\x06\x03U\x04\x03\x13%Microsoft Windows Production PCA 2011')
|
||||
* HashAlgorithme: 2.16.840.1.101.3.4.2.1
|
||||
* Certificate: <CertificateContext "Microsoft Windows" serial="33 00 00 01 06 6e c3 25 c4 31 c9 18 0e 00 00 00 00 01 06">
|
||||
|
||||
File embdeds 2 certificate(s):
|
||||
* 0) <CertificateContext "Microsoft Windows" serial="33 00 00 01 06 6e c3 25 c4 31 c9 18 0e 00 00 00 00 01 06">
|
||||
* 1) <CertificateContext "Microsoft Windows Production PCA 2011" serial="61 07 76 56 00 00 00 00 00 08">
|
||||
+29
-7
@@ -1,3 +1,4 @@
|
||||
import hashlib
|
||||
import windows.crypto
|
||||
|
||||
windowscert = """-----BEGIN CERTIFICATE-----
|
||||
@@ -35,15 +36,15 @@ raw_cert = ("".join(windowscert.split("\n")[1:-1])).decode('base64')
|
||||
cert = windows.crypto.CertificateContext.from_buffer(raw_cert)
|
||||
|
||||
print("Analysing certificate: {0}".format(cert))
|
||||
print("* name: <{0}>".format(cert.name))
|
||||
print("* issuer: <{0}>".format(cert.issuer))
|
||||
print("* raw_serial: <{0}>".format(cert.raw_serial))
|
||||
print("* serial: <{0}>".format(cert.serial))
|
||||
print("* encoded start: <{0!r}>".format(cert.encoded[:20]))
|
||||
print(" * name: <{0}>".format(cert.name))
|
||||
print(" * issuer: <{0}>".format(cert.issuer))
|
||||
print(" * raw_serial: <{0}>".format(cert.raw_serial))
|
||||
print(" * serial: <{0}>".format(cert.serial))
|
||||
print(" * encoded start: <{0!r}>".format(cert.encoded[:20]))
|
||||
|
||||
print ""
|
||||
chains = cert.chains
|
||||
print("This certificate has {0} certificate chain".format(len(chains)))
|
||||
print("This certificate has {0} certificate chain(s)".format(len(chains)))
|
||||
for i, chain in enumerate(chains):
|
||||
print("Chain {0}:".format(i))
|
||||
for ccert in chain:
|
||||
@@ -63,4 +64,25 @@ print("matches = {0}".format(matchs))
|
||||
if matchs:
|
||||
print("Found it !")
|
||||
else:
|
||||
print("Not found :(")
|
||||
print("Not found :(")
|
||||
|
||||
## Extract certificates of a PE file
|
||||
|
||||
print ("")
|
||||
print ("== PE Analysis ==")
|
||||
TARGET_FILE = r"C:\windows\system32\ntdll.dll"
|
||||
print("Target sha1 = <{0}>".format(hashlib.sha1(open(TARGET_FILE, "rb").read()).hexdigest()))
|
||||
cryptobj = windows.crypto.CryptObject(TARGET_FILE)
|
||||
print("Analysing {0}".format(cryptobj))
|
||||
print("File has {0} signer(s):".format(cryptobj.nb_signer))
|
||||
for i, signer in ((i, cryptobj.get_signer_data(i)) for i in range(cryptobj.nb_signer)):
|
||||
print("Signer {0}:".format(i))
|
||||
print(" * Issuer: {0!r}".format(windows.crypto.ECRYPT_DATA_BLOB(signer.Issuer.cbData, signer.Issuer.pbData).data))
|
||||
print(" * HashAlgorithme: {0}".format(signer.HashAlgorithm.pszObjId))
|
||||
cert = cryptobj.get_signer_certificate(i)
|
||||
print(" * Certificate: {0}".format(cert))
|
||||
|
||||
print("")
|
||||
print("File embdeds {0} certificate(s):".format(cryptobj.nb_cert))
|
||||
for i, certificate in ((i, cryptobj.get_cert(i)) for i in range(cryptobj.nb_cert)):
|
||||
print(" * {0}) {1}".format(i, certificate))
|
||||
@@ -32,6 +32,10 @@ CRYPT_OBJECT_FORMAT_TYPE_DICT = {x:x for x in CRYPT_OBJECT_FORMAT_TYPE}
|
||||
|
||||
## Move CryptObject to new .py ?
|
||||
class CryptObject(object):
|
||||
"""Extract information from an CryptoAPI object.
|
||||
|
||||
Current main use is extracting the signers certificates from a PE file.
|
||||
"""
|
||||
MSG_PARAM_KNOW_TYPES = {CMSG_SIGNER_INFO_PARAM: CMSG_SIGNER_INFO,
|
||||
CMSG_SIGNER_COUNT_PARAM: DWORD,
|
||||
CMSG_CERT_COUNT_PARAM: DWORD}
|
||||
@@ -71,17 +75,30 @@ class CryptObject(object):
|
||||
winproxy.CryptMsgGetParam(self.hmsg, param_type, index, buffer, signer_info)
|
||||
|
||||
if param_type in self.MSG_PARAM_KNOW_TYPES:
|
||||
buffer = self.MSG_PARAM_KNOW_TYPES[param_type].from_buffer_copy(buffer)
|
||||
buffer = self.MSG_PARAM_KNOW_TYPES[param_type].from_buffer(buffer)
|
||||
return buffer
|
||||
|
||||
def get_nb_signer(self):
|
||||
@property
|
||||
def nb_signer(self):
|
||||
"""The number of signers for the CryptObject
|
||||
|
||||
:type: :class:`int`
|
||||
"""
|
||||
return self.msg_get_param(CMSG_SIGNER_COUNT_PARAM).value
|
||||
|
||||
def get_signer_data(self, index=0):
|
||||
"""Returns the signer informations for signer nb ``index``
|
||||
|
||||
:return: :class:`CMSG_SIGNER_INFO`
|
||||
"""
|
||||
return self.msg_get_param(CMSG_SIGNER_INFO_PARAM, index)
|
||||
|
||||
def get_signer_certificate(self):
|
||||
data = self.get_signer_data()
|
||||
def get_signer_certificate(self, index=0):
|
||||
"""Return the certificate used for signer nb ``index``
|
||||
|
||||
:return: :class:`CertificateContext`
|
||||
"""
|
||||
data = self.get_signer_data(index)
|
||||
cert_info = CERT_INFO()
|
||||
cert_info.Issuer = data.Issuer
|
||||
cert_info.SerialNumber = data.SerialNumber
|
||||
@@ -93,20 +110,24 @@ class CryptObject(object):
|
||||
return self.msg_get_param(CMSG_CERT_PARAM, index)
|
||||
|
||||
def get_cert(self, index=0):
|
||||
"""Return embded certificate number ``index``.
|
||||
|
||||
note: not all embded certificate are directly used to sign the :class:`CryptObject`.
|
||||
|
||||
:return: :class:`CertificateContext`
|
||||
"""
|
||||
return CertificateContext.from_buffer(self.get_raw_cert(index))
|
||||
|
||||
cert = property(get_cert)
|
||||
|
||||
#@property
|
||||
@property
|
||||
def nb_cert(self):
|
||||
"TEST"
|
||||
"""The number of certificate embded in the :class:`CryptObject`
|
||||
|
||||
:type: :class:`int`
|
||||
"""
|
||||
return self.msg_get_param(CMSG_CERT_COUNT_PARAM).value
|
||||
|
||||
#@property
|
||||
def all_certs(self):
|
||||
return [self.get_cert(i) for i in range(self.nb_cert())]
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return '<{0} "{1}" content_type={2}>'.format(type(self).__name__, self.filename, self.content_type)
|
||||
|
||||
|
||||
@@ -46,11 +46,10 @@ def encrypt(cert_or_certlist, msg, algo=szOID_RSA_DES_EDE3_CBC, initvector=genin
|
||||
"""
|
||||
alg_ident = CRYPT_ALGORITHM_IDENTIFIER()
|
||||
alg_ident.pszObjId = algo
|
||||
# Is 'certs' an iterable ?
|
||||
try:
|
||||
certlist = tuple(cert_or_certlist)
|
||||
except TypeError as e:
|
||||
if isinstance(cert_or_certlist, PCERT_CONTEXT):
|
||||
certlist = (cert_or_certlist,)
|
||||
else:
|
||||
certlist = tuple(cert_or_certlist)
|
||||
|
||||
# Set (compute if needed) the IV
|
||||
if initvector is None:
|
||||
|
||||
Reference in New Issue
Block a user