Signaturing an Authenticode anomaly with YARA
This is a local mirror of a blog written by me and originally published by NCC Group.
Introduction
Earlier this week ESET released a paper about Gazer, a new toolset associated with a sophisticated attack group.
One interesting quote from the paper stood out:
The compilation date appears to be 2002 but is likely to be faked because the certificate was issued in 2015
This led to an interesting challenge: can these samples be detected using only YARA?
The short answer is yes, it is possible using only YARA and the PE (Portable Executable) module. However, some care is needed as these will not always be malicious.
What are we trying to detect?
The aim of this blog is to develop a rule which detects PE files where the timestamp (inserted by the linker at the final build stage) does not fall within the validity period of the Authenticode signing certificate.
This may occur for a variety of reasons, such as:
- The executable was manually signed after build by a newly generated certificate.
- The executable never had the right linker timestamp.
- The linker timestamp was manually edited by an attacker (“time stomped”) to make it blend in with other files, or to disguise the evolution of an attack tool.
It is important to note that the executable must be time stomped before signing, or the resulting signature will be invalid. Microsoft’s documentation about the Authenticode hashing process lists the following step: “Hashing the PE Header, omitting the file’s checksum and the Certificate Table entry”. See “Calculating the PE Image Hash” in the document “Windows Authenticode Portable Executable Signature Format” from Microsoft.
This clearly includes the linker timestamp, part of the PE header, therefore it should not be changed after it has been signed.
Executables signed with an expired certificate could also be detected by the rule detailed below. However, it’s important to note there is currently no support for revoked certificates. Therefore new executables signed after a certificate has been revoked cannot be detected this way.
A typical development lifecycle
Before diving into detection it’s important to understand how Authenticode signing fits into the typical development lifecycle.
Large companies will have complex, automated, continuous integration workflows with compilation, testing and eventual release of binaries in one process. Code signing is likely to form part of this, limiting the exposure of the code signing certificate and simplifying the burden on developers.
Smaller development operations may provide code signing access to all developers, allowing Visual Studio to sign development or release builds automatically after compilation and linking.
In both of these cases the linker timestamp (stored in the PE header) and the signature time will align, typically within a few minutes. This means the PE linker timestamp will fall within the certificate validity dates, provided the certificate was current during signing.
However there are some important exceptions to this rule. Many executables are not compiled with Visual Studio, or are signed separately, typically using SignTool. A developer may decide to sign old programs, potentially reducing security warnings for modern versions of Windows without recompiling code. This is perfectly valid but could mean the PE linker timestamp falls outside the certificate validity window.
False positives
During testing a legitimate Microsoft binary MSCOMCTL.OCX
(SHA256: fac6736251d3c61ecbd63be0420d1c75d5cd0442181d479013330155ca37d358
) was found as a good example of false positives. The PE linker timestamp shows it was compiled in 2004 but the code signing certificate was not valid until 2005. It is possible this happened around the time Microsoft introduced widespread signing, but it triggers the rule below despite it being a genuine file.
Many other legitimate signed files can also be found, including those from a popular EDR vendor. Therefore this rule can be used as one indicator that a file is interesting but it should be combined with other artefacts before classifying a file as malicious.
The Gazer sample
For one Gazer sample (SHA256: 473aa2c3ace12abe8a54a088a08e00b7bd71bd66cda16673c308b903c796bec0
), the relevant information from YARA is shown below. This can be generated by running YARA with the –D
switch and any rule which imports the PE module.
number_of_signatures = 1
signatures
[0]
issuer = "/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Code Signing CA"
subject = "/C=GB/postalCode=BN3 6HA/ST=East Sussex/L=Hove/street=Unit 11 Hove Business Centre Fonthill Road/postOfficeBox=BN3 6HA/O=Solid Loop Ltd/CN=Solid Loop Ltd"
version = 3
algorithm = "sha256WithRSAEncryption"
serial = "12:90:f2:41:d9:b2:80:af:77:fc:da:12:c6:b4:96:9c"
not_before = 1444867200
not_after = 1476489599
timestamp = 1012930570
This shows a compilation timestamp of Tuesday, 5 February 2002 17:36:10 but the certificate wasn’t valid until Thursday, 15 October 2015 00:00:00.
Sample YARA rule
The rule below detects executables where the PE timestamp falls outside the certificate validity window. It does this by:
- Checking the file starts with MZ, the magic value for a portable executable. Whilst not essential, as the PE module only works on relevant files, further profiling would help understand whether this causes a performance penalty.
- Ensuring there is at least one signature detected.
- Testing each signature, ensuring it was valid at the time stored in the PE linker timestamp.
import "pe"
rule research_pe_signed_outside_timestamp {
meta:
author = "David Cannings"
description = "PE linker timestamp is outside the Authenticode validity period"
strings:
$mz = "MZ"
condition:
$mz at 0 and pe.number_of_signatures > 0 and not for all i in (0..pe.number_of_signatures - 1):
(
pe.signatures[i].valid_on(pe.timestamp)
)
}
It is also possible to use the YARA math module to investigate further, for example check whether there is more than one year difference (in seconds) between the timestamp and certificate validity. This would allow finer grained detection of unusual samples which have clearly been time stomped by the attacker.
Conclusion
Despite false positives, plenty of interesting samples can be found that match this rule including Red Leaves, zxshell and HaveX. Therefore, if properly combined with other detection mechanisms, this is a useful indicator to analysts that a file should be investigated more thoroughly. Once again YARA proves to be an invaluable tool for first stage malware triage, for which the author is very grateful!