PowerShell Inside a Certificate? – Part 3

In the first part of this series, we explained the internal structure of certificates and how this knowledge can help us detect fake certificates. In this part, we will provide different rules that you can use in your organization to detect these certificates.

YARA

This is the YARA rule that started this research:

rule certificate_payload
{
    strings:
        $re1 = /-----BEGIN CERTIFICATE-----\r\n[^M]/

    condition:
        $re1 at 0
}

This YARA rule searches for the string —–BEGIN CERTIFICATE—– followed by a carriage return (\r), a newline (\n), and finally any character that is not an uppercase letter M. It uses a regular expression ($re1) to search for this sequence, and this sequence has to be found at the beginning of the file ($re1 at 0).

A certificate generated by Microsoft’s certutil will always start with —–BEGIN CERTIFICATE—– , followed by a carriage return and a newline, and then BASE64 encoded content. The RFC allows for extra whitespace, but that is not generated by certutil and that is why we do not account for extra whitespace in this YARA rule.

Note that there is also an older specification for certificate files that allows headers between the first line and the BASE64 payload. Our rules will trigger on these older certificates, although we have not observed these on VirusTotal.

If you want a YARA rule to detect embedded certificates (e.g. certificates inside another file), you can change the condition from “$re1 at 0” to “@re1 > 0”, like this:

rule embedded_certificate_payload
{
    strings:
        $re1 = /-----BEGIN CERTIFICATE-----\r\n[^M]/

    condition:
        @re1 > 0
}

This means that you want the position of the string matched by regular expression re1 (@re1) to be greater than 0 (> 0), e.g. not at the beginning of the file.

Another example where —–BEGIN CERTIFICATE—– can be found somewhere in a file (i.e. not at position 0): .crt files can contain several certificates.

Because YARA is still a new technology for many organizations, we also developed Suricata and ClamAV rules, which can be found in the next sections.

Suricata

Suricata is a free, open-source IDS.

With the following Suricata rules, you can monitor your network traffic for suspicious certificate files that do not follow the correct standard and may contain a malicious payload:

alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"Certificate with unknown content"; flow:established,to_client; file_data; content:"-----BEGIN CERTIFICATE-----|0D 0A|"; depth:29; fast_pattern; byte_test:1,!=,0x4D,0,relative; reference:url,blog.nviso.be/2018/07/31/powershell-inside-a-certificate-part-1/; classtype:misc-activity; sid:1000019; rev:1;)
alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"Contains certificate with unknown content"; flow:established,to_client; file_data; content:"-----BEGIN CERTIFICATE-----|0D 0A|"; fast_pattern; byte_test:1,!=,0x4D,0,relative; reference:url,blog.nviso.be/2018/07/31/powershell-inside-a-certificate-part-1/; classtype:misc-activity; sid:1000022; rev:1;)

We do exactly the same type of matching as in the YARA rule: we search for —–BEGIN CERTIFICATE—– followed by a carriage return and a newline, although the encoding is a little bit different (—–BEGIN CERTIFICATE—–|0D 0A|). After the header, we look for a byte that is different from M (0x4D) using a byte_test operation.

The first rule looks for this pattern at the beginning of the file (file_data), while the second rule looks for this pattern anywhere in the file.

We’ve tested these rules in our test environment, but make sure you do the same before using them in your production environment.

ClamAV

ClamAV is a free, open-source anti-virus.

Just like Suricata, ClamAV can be fed custom detection signatures, which can help you in detecting malicious files, for example payloads hidden in email attachments.

ClamAV.Certificate.Unknown:0:0:2D2D2D2D2D424547494E2043455254494649434154452D2D2D2D2D0D0A!(4D)
ClamAV.ContainsCertificate.Unknown:0:*:??2D2D2D2D2D424547494E2043455254494649434154452D2D2D2D2D0D0A!(4D)

These signatures should be stored inside a .ndb file. Signature ClamAV.Certificate.Unknown detects a certificate file that contains something else than certificate data (!(4D) means not M) and signature ClamAV.ContainsCertificate.Unknown detects an embedded certificate file that contains something else than certificate data.

Note that you can also use YARA rules with ClamAV, if you have a recent version of ClamAV.

Conclusion

This research is based on a simple idea: a certificate with data that does not start with an uppercase letter M, cannot contain valid certificate data. We will continue monitoring with our rules, and report back if we make interesting discoveries.

We recommend you start with the rules to detect certificates, and not embedded certificates.

Of course, bypassing detection by our rules is trivial, as is the case with any pattern-matching based rule. For example, adding extra whitespace will avoid detection by our basic rules. Because we were searching for files generated with certutil, the current modus operandi of various adversaries, the rules were set up very specific. With the explanation above, it’s easy to modify and improve on our rules, so go out and explore!

We also invite you to post comments with your successes, issues or remarks while using our rules.

About the authors
Didier Stevens is a malware expert working for NVISO. Didier is a SANS Internet Storm Center senior handler and Microsoft MVP, and has developed numerous popular tools to assist with malware analysis. You can find Didier on Twitter and LinkedIn.

2 thoughts on “PowerShell Inside a Certificate? – Part 3

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s