What are Digital Signatures?
Digital Signatures provide a way to determine whether or not I can trust a particular file. A digital signature on a file can be used to verify that the file was signed by a code signing certificate issued by a certificate authority. Then you can decide whether or not you trust the owner of the code signing certificate and the certificate authority that issued it. This is done via a list of trusted certificate authorities that are stored in the Windows Certificate Store on each host.
What digital signatures do not tell you is whether or not a file is malicious or legitimate. Adversaries can acquire code signing certificates from certificate authorities or steal code signing certificates from legitimate authors. These certificates can allow adversaries to create malware that contains valid digital signatures. In fact, most certificate authorities do not require any type of checking to assess whether or not the files being signed by the certificates the authority issues are non-malicious.
Certificate authorities are in the business of non-repudiation, meaning they care about making sure the author cannot successfully dispute its authorship or the validity of an associated signature. Certificate authorities accomplish this by requiring validation of either personal identity or legal business before issuing a certificate. By doing so, the entity is directly tied to anything that is signed by the certificate issued to that entity.
Therefore, if that certificate is used to sign malware, then one of two things must be true:
- The author wrote the malware
- The certificate was stolen or adversaries planted malicious code that was signed by the legitimate author
In either case, the reputation of the author is damaged. With the first, the author can be held liable for damages. With the latter, the author can be informed of the issue, and the stolen certificate revoked. This would also alert the author to the compromise so that, hopefully, the author can address the breach and improve security.
Files With Valid Digital Signatures are Not Always Legitimate
While valid signatures can give you some indication of whether or not the file is malicious, it is not a guarantee. In fact, approximately 25% of the malware samples in this database are digitally signed. Many of those signatures are now invalid because the code signing certificate was revoked or expired, but at one point the signatures were valid. At the time of this writing, 5% of the malware in this database possessed valid signatures.
There are four ways a malware authors can ensure their malware has valid digital signature:
1. Purchasing a Code Signing Certificate
Malware authors can purchase code signing certificates from certificate authorities just like any legitimate person or business. This process is becoming more and more difficult for malware authors because you have to prove your identity to the certificate before they will issue you a code signing certificate. For personal certificates, those issued to a person by name, verification is typically done by presenting two forms of government issued ID and having documentation notarized. When purchasing a code signing certificate for a business, then you must provide evidence that the business is legitimate such as: Online Government records on an official website of your country/state that publically displays your business entity registration status, official registration documents, or a notarized legal opinion letter.
Malware authors clearly do not want to give out that kind of personal information because they don’t want to get caught by authorities, so they would have to fake the information necessary to get those certificates. Another way is to steal legitimate business credentials to submit for certificates. Stolen business credentials can be purchased on the black market.
This is the most common method used by malware authors to digitally sign their code.
2. Stealing a Certificate
Buying your own certificate to sign malware is tedious, and if you are already in the business of stealing then you might as well steal code signing certificates to sign your malware. In many cases, developers have setup their pipeline to automatically sign their applications after the compilation process is complete, which generally means the code signing certificate is stored on the system somewhere. If you can break into a legitimate business and gain access to their development environment, then you can probably find a code signing certificate on the build server, code repository, or on a developer’s workstation. Once you have the certificate, then you can digitally sign malware to look legitimate.
A variation on this technique is to add your malware to the legitimate applications build pipeline so that the malware will be digitally signed. It is typically easier to just steal the certificate of it is accessible, but in the instances where that is not possible, then this may be another option.
One of the first major major instances of this type of attack occurred in 2010 with the Stuxnet malware that was used to target Iranian nuclear enrichment program. This type of attack has been observed in the wild with the Plead malware back in 2018.
3. Compromise the Certificate Authority
Another way to ensure your malware has a valid signature is to compromise the certificate authority itself. If a malware authors is able to obtain a root or intermediate certificate from a certificate authority, then the author can simply make their own code signing certificates to then sign their malware with.
4. Hash Collision
The last method is to use hash collisions to create a file with the same hash as a legitimately signed file or to forge a code signing certificate in order to digital sign malware. The Flame family of malware used this technique to forge a code signing certificate that appeared to be from Microsoft. They then used that certificate to digitally sign their malware. Hashing algorithms such as MD5 and SHA1 are known to be vulnerable to collisions. Most certificate authorities use at least SHA256 for code signing certificates, so this type of attack is less likely… though SHA256 is the next algorithm on the chopping block.
Types of Digital Signatures for Files
On Windows systems, there are two types of digital signatures that are supported:
- Embedded (Authenticode Signatures)
- Catalog
Embedded Signatures
An embedded signature is contained within the file that the signature is for. The embedded signature is computed for the file and then appended to the end of the file. The file format must support this type of digital signature. File formats that support embedded signatures are:
- Portable Executable (PE)
- exe
- dll
- ocx
- sys
- cab
- ps1
- jar
Each file type must provide a means of supporting embedded signatures and the launcher of that file type must support verifying those digital signatures. For example, the method Windows employs for verifying digital signatures on drivers is different than those it employs for verifying digital signatures on PowerShell scripts. In this series, we are specifically looking at executables, so that will be the focus of this discussion.
The advantage of embedded vs catalog signatures is that the signature information goes with the file, so if you transfer the file to another system, you still have the digital signature and can verify the authenticity of the file. Embedded signatures are also faster to validate on system startup because the OS doesn’t have to go searching for the right catalog file to verify the code that needs to be loaded.
The downside to embedded signatures is that there is a lot of duplicated signature information in each file which begins to waste space when you have hundreds or thousands of files.
Digital signatures are always embedded in an executable at the end of the file. The location of the digital signature can be determined by following these steps:
- Parse the IMAGE_OPTIONAL_HEADER within the PE file.
- There is a field inside of the IMAGE_OPTIONAL_HEADER called DataDirectory. This field is an array of IMAGE_DATA_DIRECTORY structures. The location of specific data is statically determined by the location of the directory in the array. The constant IMAGE_DIRECTORY_ENTRY_SECURITY declared in winnt.h represents the index of the security directory.
- The VirtualAddress field inside of the security data directory contains the file offset of the signature and the Size field contains the size of the signature in bytes.
Catalog Signatures
Catalog signatures work by storing a list of file hashes in a digitally signed catalog file. This method is helpful when there are a large number of digitally signed files. It is also the only way to digitally sign files that are not PE files.
There can be many different catalog files in the catalog root store which is located in %System%\CatRoot\. When signature validation is performed on an executable, the system must first find which catalog that file is located in. Once that catalog has been found, the signature on the catalog must then be verified.
When conducting an investigation on a system where a potentially malicious file has been found, it may be worth pulling a copy of the signature catalogs for verification on separate, trusted system.
What do digital signatures tell us?
As previously mentioned, a valid digital signature do not guarantee that a file is non-malicious, but it does give us some information. The table below highlights the difference between malicious and legitimate executables and their respective signature status.
Status Definitions
- Certificate Chain Could Not be Built. A chain of certificates to the root certificate authority could not be built. This may happen for a number of reasons including missing certificates in the certificate store.
- Root Certificate Not Trusted. The file had a valid digital signature, but it was signed by a certificate authority that was not trusted by the system.
- Revoked. The certificate authority revoked the code signing certificate, typically because they receive reports that the certificate has been associated with malicious activity.
- Expired. The code signing certificate expired. This can happen for short-lived certificates that were only valid for one or two years. Larger corporations typically acquire code signing certificates that do not expire for many years, which is why you see such a strong correlation with malware.
- Invalid Counter Signature. Some certificates are counter signed, typically for time verification.
- Signed. In this case, the file had a valid digital signature and the certificate authority was trusted.
- Invalid Signature. The signature was present, but the file contents did not match the signature value. Potentially the file was modified after being signed.
- Corrupted. There was an indication that the file was digitally signed, but the location where the digital signature information was supposed to be was not present, not formatted correction, or contained some other error that prevented the certificate information from being read by the system.
- Unsigned. There was no digital signature for the file (either embedded or catalog).
Key Takeaways
- 25% of the malware in this dataset had a valid signature at some point
- 53% of legitimate files have valid signatures, but this is likely skewed due to missing catalog signatures. I would expect there to be more valid signatures.
- 0.86% of malicious samples contained corrupted signature information. There were not legitimate samples with corrupted signature information.
Code Signing Certificate Whitelisting
Another way to threat hunt using file signatures is to track code signing certificates within your environment. You can then cross check any new certificates you discover with the database to get a count of the number of whitelist and blacklist files signed by that certificate. Generally speaking, most legitimate code signing certificates are used to sign more than one file. Therefore, there should be at least one other file in the environment that is signed by that same certificate. So, what we’re looking for is a count of unique executables grouped by the certificate serial number. When applied to this dataset, only 0.8% of legitimate files with valid signatures had no other files in the database that were signed by the same code signing certificate. By the same token, there were no malicious files that were signed by a certificate that had signed whitelisted files associated with it. This is a good way to eliminate a lot of false positives. In the next version, the Malware Analysis Center will support searching for samples by certificate serial to aid in this type of analysis.