Finding and utilising leaked code signing certificates
Posted on by Tijme Gommers.
[TL;DR] Using tools such as VirusTotal, it is possible to find leaked code signing certificates. For some, the password can be cracked, after which they can be used to sign malicious code. In this blog post I explain this process, including responsible disclosure measures.
This blog post consists of 4 chapters. Finding leaked certificates, cracking their passwords, using them to sign malware, and reporting leaked certificates to certificate authorities.
1. Finding certificates
There are many ways to find code signing certificates online. If you’re lucky, you’ll find one that is still valid. In my journey, I mostly used VirusTotal, but it seems that platforms like Grayhat Warfare and GitHub also have many certificates uploaded to them. We’ll use VirusTotal in this blog post.
With the query below, you can find files with a byte sequence commonly observed in signing certificates. The sequence is often part of ASN.1 DER encoded files (RFC7292). At offset 4, a version number should be present that always has the value 3. This is denoted by the 02 01 03
. The 4th byte in the sequence is 30
, which represents the start of a new sequence.
content:{02 01 03 30}@4 NOT tag:msi AND NOT tag:peexe
The results can be downloaded via the VirusTotal GUI or API.
I downloaded about 50 certificates that were recently uploaded to VirusTotal.
2. Cracking PKCS#12 passwords
My go-to hash-cracking software is Hashcat. Unfortunately, it does not support cracking PKCS#12 files. John the Ripper does support PKCS#12. First, we need to extract a hash from our PKCS#12 file. This can be done using John’s pfx2john.py
Python script. I made a few changes to make the script compatible with Python 3.
pfx2john.py certificate.pfx > certificate.hash
If you’ve generated hashes based on the certificates you found, you can crack them using John with the following arguments. In this example, we use rockyou.txt
as a wordlist.
If John cannot load your hash, make sure to install the latest version of John from source (to ensure you have PKCS#12 support).
As you can see, some of the hashes got cracked quite easily. The password for the last one is test
. For the cracked certificates, check if they’re trusted and still valid (e.g. not revoked). For the trusted and valid ones, ensure that they have the Code Signing
Object Identifier (OID): 1.3.6.1.5.5.7.3.3
. Now hopefully you have one left. You’ll be able to use it to sign malware!
PS: If you want to use a more extensive password list with John the Ripper, look for one on Weakpass. You could try to use rules and masks as well. I’ve added two examples below for you to get started.
3. Signing malware
If you’ve found and cracked a valid and trusted signing certificate, you can use it to sign malware. I’ll demonstrate signing malware for both Windows and MacOS.
Windows
To sign PE files, there is an amazing open source project called osslsigncode. Once installed, run the following command to create a signed version of your malware.
To verify if the signature is valid and correctly applied, you can use osslsigncode
as well.
Please note that in my experience
osslsigncode
does not check if a certificate has been revoked.
Finally; enjoy your signed malware!
MacOS
If you’re signing an existing (modified) app for MacOS, please first remove the existing signature.
Afterwards, import the signing certificate into your keychain. Right-click it and create a new signing identity. Use a name of your choice.
You can now use this identity to sign your malicious app.
To check if everything worked, we verify the signature. If everything is okay, the command will not output anything.
If something is wrong, an error will be shown. This is what the output looks like when, for example, your certificate is revoked.
4. Reporting leaked certificates
In the example above, the leaked certificate was issued by Sectigo. Sectigo, and any other certificate authority, provides ways to report abuse, including fraudulent or malicious use of certificates. I mailed Sectigo with the following details of the certificate that I found:
- VirusTotal link (including a link to malware signed by the certificate).
- Password.
- Serial number.
- SHA-256 hash.
- SHA-1 hash.
8 days later Sectigo stated that, upon continued investigation, they found that the signing certificate was indeed involved in malicious activity and has now been revoked.