3

I'm looking to improve defense-in-depth on a system, primarily by closing some holes in injected DLLs. Certain applications installed on the system cause helper DLLs (e.g. shell extensions, BHOs, etc.) to be loaded into processes. Unfortunately, many of these were not compiled with ASLR / DEP opt-in flags. Since the affected processes are prime targets for exploitation, I've been going through manually and patching the support in so that so-called "universal" ROP chains can't be exploited.

One side-effect of my changes is that a lot of the components now have invalid code signatures. This doesn't seem to have broken anything, but I'd like to re-sign them with a locally installed certificate, using some kind of personal root certificate as a parent. As a bonus, I can take advantage of the force integrity flag.

What steps should I take to do the following?

  1. Create and install a root certificate, with a child (intermediate?) certificate for code signing.
  2. Strip the existing certificates from binaries.
  3. Re-sign binaries with the new certificate.

I've never really messed with the certificate store on Windows, beyond a few quick forays into checking existing ones or installing the Burp CA, so I'm a little lost here. Is OpenSSL a good option for generating the certificates, or is there a better Windows-specific solution? What tools are ideal for re-signing binaries?

4

You'll probably want to use the code signing tool as part of Visual Studio, and makecert.exe will probably be easier to use for cert generation. You'll have to make sure you get the proper cert template though otherwise the code signing will fail. A good source of information could be found here: http://msdn.microsoft.com/en-us/library/ie/ms537364(v=vs.85).aspx

If you store the code signing key locally the net security gained is pretty low. You'd really want to at least move it off to a secure machine, or possibly store it on a VM, on a removable disk, encrypted, and never connected. The problem with this though is that any time an app loads the DLL, Windows will attempt to validate the signature and try to verify that the certificate hasn't been put on a revocation list, which means an outbound call to an unknown location, causing blocking timeouts, which leads to awful performance and random things failing to start.

You'd probably want to stand up a full CA (gag) to get this all working properly. Alternative options are to get an actual code signing certificate from a trusted CA, and sign the DLLs using that. Though if those DLLs ever got out into the wild with your signature odds are good your cert will be revoked... eventually.

As well, if you're doing this to core Windows components then you'll likely just break your installation since the internal protections will freak out about the unknown signature.

Lastly, if you're doing this to certain non-Microsoft drivers or kernel-mode components, you might have a bad time because Windows hard codes CAs that can sign certs for certain components that have certain key usages. See: http://www.alex-ionescu.com/?p=146.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.