How do systems protect against a stolen code-signing certificate after the certificate expires?
This is why Microsoft recommends to never remove expired code signing certs from CRLs. An alternative scenario: attacker signs their malware before cert expiry. If they can remain undiscovered past cert expiry, then the cert won't get added to the CRL even on discovery, and their malware will never get blocked. Thus the revocation status of code signing certs must be tracked forever.
From Microsoft's Code Signing Best Practices document:
In most PKI deployments, only certificates that have not yet expired are placed on the CRL. This means that when a revoked certificate expires, it is eventually removed from the CRL. However, timestamping allows Authenticode signatures to remain valid indefinitely. As a result, revoked code-signing certificates should not be removed from the CRL. This paper recommends always revoking compromised certificates that were used to sign publicly released software and maintaining these entries in the CRL indefinitely.
Microsoft Certificate Server enables administrators to configure the CA to keep all revoked certificates in the CRL. However, the CA does not distinguish between code-signing certificates and other certificates. For this reason, administrators should dedicate a CA for the sole purpose of handling code-signing production certificates.
So to answer your question - yes, the malware can run again if the CRL for code signing certs isn't managed properly.
Dealing with digital signatures is more complex than we can suppose at first sight.
Your scenario is correct: if you do not have a proof of the date/time of the signature you cannot be sure it has not been done after the revocation and expiration of the certificate. You can also note that, even if the certificate has not been revoked, a signature done after the certificate expiration should not be considered valid.
First solution
Adding a time-stamp to the software signature. This time-stamp is called signature time-stamp. This time-stamp provides a proof that the signature existed at a given date. It prooves that the signature has been computed before the expiration of the certificate. But it does not solve the second problem: what if the certificate has been revoked?
Second solution
Along with the signature time-stamp you can also attach a copy of the CRL (or an OCSP response) to the signature. It will prove that the certificate was not revoked when the signature was produced.
But time-stamp tokens and CRL are also signed objects. They also need to be validated. So, should we also get the CRL which proves that the signature time-stamp has been signed by a valid certificate? Short answer: Yes, things seems to get more complicated.
Third solution
Some signature standards (like CAdES) have proposed a better solution: along with the signature time-stamp, you should collect every items required to validate the signature off-line (i.e. being able to validate the certificate without having to download any additional object). It includes all intermediate CA certificates and CRLs. This is not an endless process since you are going to eventually reach one or several trustfully root CA but it may be quite complex (Note that a good X.509 validation algorithm should output all these items along with the certificate validity status). And after having fetched all these objects, you must put a time-stamp on it. This time-stamp is called archive time-stamp
Now the signature validation process is the following:
- You validate the global time-stamp on-line. It means you download all necessary element in order to ensure that the time-stamp signature is valid. Now you have a proof that all the enclosed object (CRL...) existed at the archive time-stamp date.
- You validate the signature off-line only with the elements which was covered by the archive time-stamp as if the current date was the date of the archive time-stamp.
With this solution the scenario you was presenting is not possible since the signature verifier has a proof of the expiration and validity status of the certificate at the date of the signature.
This solution is currently implementing for validation of long-term document signature but unfortunately, as far as I known, not for code signature validation. Today vendors are using other mechanisms like stolen certificate blacklists, which are easier to implement.
UPDATE Sept, 25 2014 (after reading @maureen comment)
First, your understanding of the process is correct: since every certificate is removed from the CRL after the expiration date, you cannot assess whether a certificate has been revoked or not in the past. Hence it is not possible to validate a signature after the expiration of a certificate.
But even if a certificate has been compromise (or simply revoked because, for instance the customer lost his USB crypto-token), all signatures created before should be considered valid. The process I described in my answer tries to explain how it is possible to answer today (i.e. even after the expiration of the certificate) that question: "Was the signature valid was it was created".