Our Blog

Recreating certificates using Apostille

Reading time ~3 min

Sometimes on an engagement, you’d like to construct a believable certificate chain, that you have the matching private keys for. An example might be that a mobile app is doing cert pinning, based on attributes of the signing certificate, such as the Canonical Name (CN), serial number, or Issuer, or that you are intercepting an embedded app that only supports a particular algorithm. Whatever the reason, it’s a fairly complicated process if you are not familiar with X509 certificates. And trying to kludge it together with OpenSSL and some shell scripts under time constraints will only make you tear your hair out! While Metasploit can do some of this, it only clones a single certificate and self-signs it, rather than cloning the entire chain. If you need more than that, keep reading!

Apostille makes use of the Java BouncyCastle crypto libraries to effectively “clone” a certificate from an URL, or from a provided Java KeyStore (JKS) containing the targeted certificates or certificate chains.

It does this by first looking for self-signed certificates in the root of the chain. If it doesn’t find one, it will look for the CA certificate in the Java Trust Store. Then, it will generate a new PrivateKey that matches the parameters of the PublicKey in the certificate, such as algorithm (RSA, DSA and EC are currently supported, but it is not much effort to add new algorithms) and key size/curve/whatever. It then constructs a certificate by copying all of the attributes (serial number, validity period, etc.) and critical and non-critical Extensions from the target certificate, and signs it using the generated PrivateKey. The end result is a certificate that is indistinguishable from the original, apart from the actual key values.

If there are more certificates in the chain, it then works its way along the chain, following a similar approach as described above, but signing the certificate with the PrivateKey of the parent.

The end result is an X509Certificate chain that is indistinguishable from the original, apart from the key values, and this can then be used in tools such as Burp or Mallet to intercept TLS traffic.

When you run Apostille, you will receive a sequence of PEM-encoded private keys and public keys on stdout, that you can redirect to a file. If you provide an output file name, and passwords, all of the private keys and certificates will also be written to a Java KeyStore, from which you can extract the bits you need, using a tool such as KeyStore Explorer.

Of course, you still need to get the CA cert onto your target somehow (and to be honest, I haven’t explored this too much/at all), as this could cause conflicts with the existing legitimate certificate in the Trust Store. You may have to delete the original CA certificate from the victim’s Trust Store to get around this (if that is even possible on your target platform!).

Apostille is available at https://github.com/SensePost/Apostille

Feedback is welcome!