XProtect & YARA – YARA Post #3

In yesterday’s post I covered an example of a YARA rule from AT&T’s Alien Labs used to detect payloads used by BlackCat Ransomware. Today I’ll take a quick look at one of the YARA rules used by Apple in XProtect to help protect macOS devices.

Apple’s XProtect uses YARA rules to deliver “signature-based detection and removal of malware” as described in their security guide Protecting against malware in macOS.

On my version of macOS these signatures are located in /Library/Apple/System/Library/CoreServices/XProtect.bundle/Contents/Resources/XProtect.yara . In this file Apple uses a technique called private rules to define reusable YARA rules that can be references in the conditions of other rules.

For example, one of these rules identifies Portable Executables:

private rule PE
{
    meta:
        description = "private rule to match PE binaries"

    condition:
        uint16(0) == 0x5a4d and uint32(uint32(0x3C)) == 0x4550
}

This rule is a little different from the condition uses in yesterday’s BlackCat rule that just used uint16(0) == 0x5A4D to identify the executable. Here the rule Apple are using does a couple of lookups to identify that this is a PE file using specific offsets defined in the PE file format specification:

After the MS-DOS stub, at the file offset specified at offset 0x3c, is a 4-byte signature that identifies the file as a PE format image file. This signature is “PE\0\0” (the letters “P” and “E” followed by two null bytes).

PE Format

If you are interested in seeing how Apple identifies MACH-0 files (executable format used by macOS and iOS) they also have a private rule to do that as well:

private rule Macho
{
    meta:
        description = "private rule to match Mach-O binaries"
    condition:
        uint32(0) == 0xfeedface or uint32(0) == 0xcefaedfe or uint32(0) == 0xfeedfacf or uint32(0) == 0xcffaedfe or uint32(0) == 0xcafebabe or uint32(0) == 0xbebafeca

}

These private rules can be used within the condition sections of the public rules that XProtect also uses. For example in the XProtect_MACOS_51f7dde rule we can see that the rules condition first references the Macho private rule, an upper bound on file size, and then the presence of multiple strings (that were defined using the Hexadecimal format in the strings section above):

rule XProtect_MACOS_51f7dde
{
    meta:
        description = "MACOS.51f7dde"
    strings:

        $a = { 63 6F 6D 2E 72 65 66 6F 67 2E 76 69 65 77 65 72 }
        $b = { 53 6D 6F 6B 65 43 6F 6E 74 72 6F 6C 6C 65 72 }
        $c1 = { 75 70 64 61 74 65 53 6D 6F 6B 65 53 74 61 74 75 73 }
        $c2 = { 70 61 75 73 65 53 6D 6F 6B 65 3A }
        $c3 = { 72 65 73 75 6D 65 53 6D 6F 6B 65 3A }
        $c4 = { 73 74 6F 70 53 6D 6F 6B 65 3A }
    condition:
        Macho and filesize < 2MB and all of them
}

This shows how commonly used elements of a rule can be defined separately and then composed with other conditions to simplify the resulting rules.

YARA BlackCat Payload Example – YARA Post #2

In my first post in this series, Day 1 of the 12 Days of YARA, I shared some resources that can help you to get started with YARA. YARA is a rules based language that allows for pattern matching against a file (or a processes memory). This is a useful tool that can describe a malware sample in a way can match on both a specific sample and (if properly generalized) on similar samples. A generalized rule may continue to match on related samples even if they change slightly from version to version, this is in contrast to cryptographic hash based approaches (SHA1, SHA256, MD5) to detection where minor changes in the malware create an entirely different hash value.

YARA rules are quite simple in terms of structure. The rule typically consists of the strings that will match file contents, and boolean conditions that determine whether the rule is matched or not. There’s a good overview of how to write a YARA rule in the documentation that it is worth reading if you are unfamiliar with how the rules are structured.

When I learn something I like to learn by reading the documentation as well as examples published by others. This helps me get a better sense of the idiomatic use of a language. Luckily there are lots of examples published that you can use to see different approaches people have taken.

In this post I’ll reference one of the YARA rules provided by AT&T Alien Labs in their post about BlackCat ransomware earlier this year:

rule BlackCat : WindowsMalware {
   meta:
      author = "AlienLabs"
      description = "Detects BlackCat payloads."
      SHA256 = "6660d0e87a142ab1bde4521d9c6f5e148490b05a57c71122e28280b35452e896"
    strings:
        $rust = "/rust/" ascii wide
        $a0 = "vssadmin.exe Delete Shadows /all /quietshadow" ascii
        $a1 = "bcdedit /set {default}bcdedit /set {default} recoveryenabled No" ascii wide
        $a2 = "Services\\LanmanServer\\Parameters /v MaxMpxCt /d 65535" ascii wide
        $a3 = ".onion/?access-key=${ACCESS_KEY}" ascii wide
        $b0 = "config_id" ascii
        $b1 = "public_key" ascii
        $b2 = "extension" ascii
        $b3 = "note_file_name" ascii
        $b4 = "enable_esxi_vm_kill" ascii
        $b5 = "enable_esxi_vm_snapshot_kill" ascii
    condition:
        uint16(0) == 0x5A4D and filesize < 5MB and $rust and 2 of ($a*) and 3 of ($b*)

}

Taking a few moments to examine this a few things begin to pop out.

First the meta section provides information about the origin of the rule, in this case information about the authorship, description, and the hash of the Windows BlackCat payload. While the hash in the metadata is not used in the rule itself, it is useful to be able to look up more information about the file on other sources (like VirusTotal).

Second, in the strings section the author has grouped related sets of strings together with the same prefix ($a,$b), when we look in the condition section we can see that YARA allows the use of wildcards to identify these different sets of strings and apply different conditional logic to them.

Third, in the condition section we can see how the author uses both the strings defined earlier, as well as some other conditional statements:

  • uint16(0) == 0x5A4D. The uint16(0) reads the unsigned 16 bit integer at the start of the file (offset 0) and compares it with 0x5A4D which is the magic number indicating this is an executable file on Windows. YARA does include a PE module that allows for fine-grained inspection of attributes of a portable executable files, but looking for specific markers at a known offset (as in this case) may be more efficient from an execution perspective if the rule doesn’t need that level of granularity.
  • filesize < 5MB. Here the authors include a filesize limit, this will help optimise the processing of very large files (above the 5MB specified) so that the scan can concentrate on the right set of files.
  • $rust and 2 of ($a*) and 3 of ($b*). Here the author uses the strings defined earlier. These sets of strings relate to characteristics that are less likely to change over time. For example, commands to delete shadow copies are a common characteristics of ransomware, so detecting strings related to that operation are less likely to change than strings related to non-core aspects of the malware.

Stay tuned for Day 3 tomorrow!

Kicking YARA Series – YARA Post #1

For the last few years I have been working in Product Management at Rubrik. One of the offerings I recently launched was the ability to scan backups of different systems looking for Indicators of Compromise (IOCs). These IOCs are intended to help identify systems that have been compromised and are showing malicious activity. The IOC is an indicator of such activity.

When an IOC is file based, if you have access to the backups of the system, you essentially have a time-series history of that system that you can scan for those IOCs. This can helps you to identify details about the initial infection, when it first landed etc., without relying on the primary system being available. At Rubrik we introduced support for scanning for IOCs, using YARA rules (and hashes and file patterns), against the system backups.

You can begin learning more about YARA from the project page, and from the documentation. In this series of blog posts I will share a somewhat eclectic collection of tips, tricks and resources all about YARA and a few things I’ve picked up a long the way.

Stay tuned and I hope you had a Merry Christmas!