Introduction
If you work in security anywhere, you do a lot searching, analyzing, and alerting. It’s the underpinning for almost any keyword you can use to describe the actions we take when working. The minute any equation I’m working on comes down to “finding” or “analyzing”, I know what to reach for and put to use. It’s YARA. The variables of the equation really don’t matter. A quick interrogation of a file to find out about its contents? Dig through source code to find a specific algorithm? Determining if something is malicious or safe to whitelist? YARA handles those use cases and plenty more. Really, it comes down to finding things. Finding fragments of what I’m looking for, whether I want to do so directly, by absence, via a pattern or through some form of calculus. YARA is my go-to.
Outlining what it can do at a high level is simple to express, but it’s unreasonable to expect that you are as familiar with YARA as I am. If you are up for a little exploration, dive into the details with me for a minute.
Delving into Details of Data
When it comes to finding, it’s a discussion of what “whole” thing am I looking for or what “fragment” of a whole am I look to find. In YARA-speak, that’s a detection or detection fragment. Just like bacon makes everything better, so do examples. As a detection, we are going to use “Alienvault”. It’s a recognizable term, after all, and one we want to find. However, perhaps it’s not exactly as we spelled it. To combat spelling, spacing and other issues, we can break the whole thing we are looking to find into detection fragments. Those might be “Alien” and “vault”. Written in a rule, that would look something like this:
rule at_whole_frag {
meta:
description = “simple detection and detection fragment logic”
strings:
$whole = “Alienvault”
$frag1 = “Alien”
$frag2 = “vault”
condition:
$whole or ($frag1 and $frag2)
}
The syntax and structure of YARA is pretty intuitive, so I’m going to skip going into full detail about it. I chatted about the basics of YARA previously on Alienvault and it’s a good primer to get started. Equally, you can jump into one of our classes and really get into the details. Regardless, you have to outline a name for your rule, in this case “an_whole_frag”, that identifies it. Then, you have three internal sections: “meta”, “strings”, and “condition” within a pair of curly brackets. The meta and string sections are handled like variable assignments. The condition section is written to return a Boolean value. If true, it will match, and if false, it will not. The normal code actions of concatenation, stemming, counting, comparison, and looping are allowed at the condition line.
What we did previously in the example was very simple, ASCII text detection. We can shift those detections to Unicode strings, remove issues with upper and lower case, or include negation logic at the condition line to look for the absence or negative space.
rule av_whole_frag_alt {
meta:
description = “simple detection and detection fragment logic with a little more spice.”
strings:
$whole = “Alienvault” fullword nocase
$frag1 = “Alien” ascii wide
$frag2 = “vault” ascii wide
condition:
($frag1 and $frag2) and not $whole
}
The changes we made here reflect the above points. The detection fragments now look for “Alien” and “vault” in both ASCII and UTF formats. The “whole” detection looks for “Alienvault”, regardless of how its spelled and matches only when it’s a complete word bounded by non-alphanumeric characters. Lastly, the condition line has been rebuilt to express logic that will only match when the two fragments are present and the whole is not, showing a negation check. We could do more but that’s a good depiction of the heart of direct or negative detection with YARA.
Describing Patterns with YARA
Where YARA shines very brightly is in describing patterns. If you have used grep or regex, then you likely understand what I mean about searching via patterns. YARA effectively does both of these things, plus a lot more with patterns. When you see rules that leverage patterns, you begin to see a person’s craftsmanship. Patterns are descriptive in nature. You use YARA to outline a concept in a file, like an algorithm or a repeating set of data; a structured output of data and as a means of describing a combination of knowns and unknowns.
Before dropping deeply into this example, I want to introduce a powerful concept. When you put more than one rule together in a file to build a ruleset, you can use a rule as part of the condition of another rule. The only real sticky part here is YARA reads rules in a set from top to bottom. That means a rule has to be placed before the rule using it in the ruleset or it will error. Let’s combine this with an algorithm to look for data.
To keep this compact, I’m going to focus on the algorithm and reference the rule we are going to import. This rule will be called IsHTML and its job is to match on HTML files. This will be brought into the condition of our rule described below.
rule detect_shell_in_div {
meta:
description = “Looking for a target value within a set of
webhshell = “wso_webshell”
strings:
$my_target = “