With the help of a specifically crafted YARA rule developed by NVISO analysts, we found multiple certificate files (.crt) that do not contain a certificate, but instead a malicious PowerShell script. In this blog post, we explain how we crafted this YARA rule.

Certificates

Certificate files in Windows can have different extensions, like .cer and .crt, and usually, .cer files contain binary data and .crt files ASCII data. But as happens more with Microsoft applications and utilities, these extensions can be interchanged and the applications will still process the certificate files correctly (they look at the content and parse it accordingly).

For the purpose of this blog post, we’ll stick to the convention: a .cer file contains binary data and a .crt file contains ASCII data.

A .cer file contains the certificate data encoded according to the Distinguished Encoding Rules (DER), an encoding format specified in the X.690 standard. Here is an example of a .cer file found in Microsoft Office’s installation directories:



A .crt file contains ASCII data: a BASE64 encoding of a .cer file (DER encoding). These files start with “—–BEGIN CERTIFICATE—–” and end with “—–END CERTIFICATE—–“, with BASE64 encoded data in between, according to RFC 7468. Here is an example of a .crt file created from the previous .cer file with certutil:

(Ab)using certutil

Certutil is a versatile Windows executable, used to perform all kinds of operations with certificates and services. Since Casey Smith Tweeted about certutil BASE64 decoding and encoding, red teams and criminals have been using this encoding to get all kind of files past IDS and AV.

certutil does not perform validation of the binary data it is encoding: it will encode any file. Windows executables (PE files) can be easily encoded with certutil, and in this form, many IDS systems and anti-virus applications will not recognize the PE file. Here is an example of a Windows executable encoded into a .crt file:

Notice that the first letter of the BASE64 data is letter T. This will always be the case for a PE file encoded with certutil: the first byte of a PE file is uppercase letter M (from MZ). In binary notation, that’s 01001101. BASE64 encodes in chunks of 6 bits, hence 010011 will be the first chunk to be encoded. In decimal notation, 010011 is 19. In BASE64, 0 is encoded as A, 1 as B, …, and 19 as T.



That is why a BASE64 encoded PE file will always start with T.

There are detection rules for this: they trigger if they detect a file starting with —–BEGIN CERTIFICATE—– and then followed by uppercase letter T. These kind of detection rules are for so-called “known-bad” detections: it is known how an executable file looks like when encoded with certutil, hence that is what detection engines look for.

These rules are very reliable, and we have detected many encoded PE files with them.

Detection

However, at NVISO, we try to do better than “known-bad detection”. That is why we set out to develop a rule to detect certificate files that do not contain a certificate. So, not only certificate files that contain a Windows executable, but any certificate file that does not contain certificate data.

Certificate (X.509) data always starts with an ASN.1 sequence element as defined in RFC 5280. A sequence element has a tag number of 0x30 and hence it’s DER encoded binary data starts with byte value 0x30.

Just like we explained with PE files, we can determine how byte value 0x30 (that’s ASCII digit 0) is represented in BASE64: it starts with the uppercase letter M.

Conclusion: every X.509 certificate encoded according to RFC 7468 starts with “—–BEGIN CERTIFICATE—–” followed by letter M.

Inference: every certificate file containing “—–BEGIN CERTIFICATE—–” not followed by letter M can not be a valid X.509 certificate.

We created a simple YARA rule based on this knowledge, and let it run for several months on VirusTotal Intelligence.

rule certificate_payload { strings: $re1 = /-----BEGIN CERTIFICATE-----\r

[^M]/ condition: $re1 at 0 }

With this rule, we detected many Windows executables disguised as certificates, and also a couple more interesting files. There were no false positives on valid certificates.

One of the more interesting files we detected has MD5 hash value 0082aed588f76b517946a824fba43994.



It has 0 out of 60 detections on VirusTotal. But when we analyze it with base64dump.py, something stands out:

This certificate file contains an encoded PowerShell script: that’s not a good sign. The analysis of this script requires several steps, that’s why we will cover this in part 2.

Conclusion

By developing and using a “not known-good” detection method instead of using a “known-bad” detection method, we were not only able to identify “known-bad” files, but also “unknown-bad” files. Besides YARA rules, we created Suricata and ClamAV rules too, we will release all rules in an blog post part 3.

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.

Share this: Twitter

Reddit

WhatsApp

Email

