Signaturing an Authenticode anomaly with Yara

Earlier this week ESET released a paper[1] 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”. [2]

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[3] 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[4], 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!

References

[1] – https://www.welivesecurity.com/wp-content/uploads/2017/08/eset-gazer.pdf

[2] – See “Calculating the PE Image Hash” in “Windows Authenticode Portable Executable Signature Format” from Microsoft, available from download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/Authenticode_PE.docx

[3] – SHA256: fac6736251d3c61ecbd63be0420d1c75d5cd0442181d479013330155ca37d358

[4] – SHA256: 473aa2c3ace12abe8a54a088a08e00b7bd71bd66cda16673c308b903c796bec0

Published date:  01 September 2017

Written by:  David Cannings