I helped a colleague with a forensic analysis by extracting certificates from the Windows registry. In this blog post, we explain how to do this.
The Windows registry contains binary blobs, containing certificates. Like this one:
Examples of locations where certificates can be found:
Certificates, encoded in DER format, always start with value 0x30, as we explained in blog post “PowerShell Inside a Certificate? – Part 1“.
The binary blobs found inside the registry do not start with value 0x30, thus they can not be certificates. However, they do contain certificates prefixed with metadata. Searching for 0x30, we can find such a certificate:
Not all found byte sequences that start with 0x30 are valid. We searched for one starting with 30 8?. Extracting that byte sequence until the end of the binary blob, yielded the certificate my colleague was looking for:
We sought to improve this method, as it is not very precise (you have to know which sequences starting with 0x30 are not actual certificates).
Looking at several binary blobs, we started to distinguish a pattern: each certificate was prefixed by 4 bytes that encoded the length of the certificate (little-endian). And this length field was, in turn, prefixed by 8 constant bytes: 20 00 00 00 01 00 00 00.
This looks like a Type-Length-Value record (TLV). Each certificate has a type 20 00 00 00 01 00 00 00.
Python tool format-bytes.py, a free tool to parse binary data, can be used to parse TLV records, like this:
<QI means little-endian (<), unsigned long long (Q, 8 bytes), unsigned int (I, 4 bytes).
t:0 means that the type field is the first field (0 -> Q) and l:1 means that the length field is the second field (1 -> I).
We see that this binary blob contains 11 TLV records, and that the last one (11) has length 1239 and contains the certificate (type 0x100000020L).
Further research revealed that the type field is actually composed of 2 fields: a property identifier field and a reserved field, both 4 bytes long (I). Possible values for property identifier can be found on the Windows Dev Center and inside the wincrypt.h header.
This means that TLV records inside the binary blob can be parsed like this (format-bytes.py -f “tlv=f:<III,t:0,l:2” blob.bin):
For example, record 5, with type 0x0B (11 decimal) is the friendly name property id: CERT_FRIENDLY_NAME_PROP_ID
It contains the name of the issuer in UTF16.
The certificate itself is inside record 11 (property ID 0x20):
To extract the certificate, perform a binary dump (option -d) and write the output to disk.
TLV records appear often in binary data structures. If you recognize data inside a binary blob (like a certificate), look what data can be found in front of it. Compare several examples, and you might discover a pattern.
Certificates are stored inside the registry together with metadata, structured as TrLV records (r = reserved). The certificate itself is stored inside the record with type 0x20 (32 decimal).
About the authors
Didier Stevens is a malware expert working for NVISO. Didier is a SANS Internet Storm Center senior handler and Microsoft MVP, and has developed numerous popular tools to assist with malware analysis. You can find Didier on Twitter and LinkedIn.
Didier will be teaching a class on malicious documents for red teams at BruCON in October.
10 thoughts on “Extracting Certificates From the Windows Registry”
Actually, it is a sequence of blobs with header.
Header looks like
typedef struct _CAPI_CERT_BLOB_HEADER
You look for block with PropertyId == 0x20, and this is actually a cert blob.
This is explained in the blog post.
Upon reinstalling Windows 10 from an extracted ISO, the SystemCertificates registry tree seems to be kept as it was before. It’s persistent.
I just do not see the point in hiding the certificates. I’m trying to work on developing software so I can provide for my daughter.. I don’t have time to play hide and seek. Can someone simply map this out or will I have to spend endless hours cracking the hex?
thanks for this wonderful blog.
Do you have any information on how to reproduce the entire blob sequence from a der file ?
Would have saved you some heavy lifting to just look it up on the Microsoft Docs: