Yara is a popular open source tool used to identify and classify Malware Samples. It is motto is Swiss knife
for malware researchers and everyone else. I think it deserves this because of its features. In this tutorial we will look some features of yara.
Install
Installation of Yara is very easy for Linux installations. We will just use package manager to obtain and install Yara.
Fedora, CentOS, RedHat:
$ sudo yum install yara -y
Ubuntu, Debian:
$ apt install yara
Help
Yara help information can be listed simply like below.
$ yara -h

We can see also the usage of yara command like below. Yara supports target as binary file, directory or process id as we see below.
yara [OPTION]... RULES_FILE FILE | DIR | PID
Getting Started with Yara
Yara tool read rules from rule file and implement these rules to the specified binary file in specified configuration. After the implementation the result is printed to the terminal or console. We will start with a simple sample by defining a rule file.
Create Rule File
In the example we will use rule file name myrule
and this rules file contain following rules.
myrule
rule dummy { condition: true }
Download Binary Sample
We will download our binary samples from web. Our sample binary is popular ssh client named Putty
. Download following link to get.
https://the.earth.li/~sgtatham/putty/latest/w32/putty.exe
We use wget
for Linux for download operation.
$ wget https://the.earth.li/~sgtatham/putty/latest/w32/putty.exe
Run Yara
Now we can run our first rule with yara.
$ yara myrule putty.exe
The result is not se exiting but it works. This rule file simply print text dummy
and the file name in this example putty.exe
Rule
Yara rule syntax is similar to C programming language. Here is a simple rule named myrule
.
rule myrule { strings: $my_text_string = "text here" $my_hex_string = { E2 34 A1 C8 23 FB } condition: $my_text_string or $my_hex_string }
We have two main parts in the rule definition.
First part is string:
which is used to define variables. In this case type of the variables are string. There may be more than one part if we have different type of variables.
Second part is condition:
where we define logic to match intended data. For example in this example rule we want to match two string data if one of them exist.
Keywords
Yara have keywords reserved for rule definitions like other programming languages. This keywords can not be used as variable or other user defined things.
all | and | any | ascii | at | condition | contains |
entrypoint | false | filesize | fullword | for | global | in |
import | include | int8 | int16 | int32 | int8be | int16be |
int32be | matches | meta | nocase | not | or | of |
private | rule | strings | them | true | uint8 | uint16 |
uint32 | uint8be | uint16be | uint32be | wide |
Comments
In a big projects there will be alot of rules and we need to remember and and document these rules wihtout effecting the rule. Comments are use to document or take not in rule files.
There is two type of comments;
Single Line
comments only used to comment current line.//
is used to specify single line comment.Multi Line
comments will wrap multiple lines where/*
specifies start and*/
specified end. Text between these delimiters are all comments.
//Single line commen /* Multi line comments */
Strings
Now we will start defining variables and data to be used in rules. One of the most used variable is string. We can set a string value and look for it in a binary.
We will look string putty
in the putty.exe
with the following rule. We set the rule name name_putty
.
rule name_putty { strings: $pname="putty" condition: $pname }
If we run the rule like below the rule matches the condition and prints the rule name with the binary name.
$ yara myrule putty.exe
Regular Expression or Regex
One of the most common usage of yara rules is using regex. Regex gives the flexibility yo define the general or similar data structures.
In the example we will look strings those are like p*tty
. We will use wildcard for *
. This can be alphanumeric character.
rule name_putty { strings: $pname=/p[0-9a-zA-Z]tty/ condition: $pname }
Here we specify
File Size
File size is another factor while writing rules. We can check the size of file with operators like <
, >
, =
and providing size like below.
KB
for kilobyteMB
for megabyte
In this example we will specify the size condition as higher than 500KB
by using filesize
keyword.
rule name_putty { strings: $pname=/p[0-9a-zA-Z]tty/ condition: $pname and filesize > 500KB }
If we run the example the rule will match because we have two conditions to where first one is the name of the file and second one is the size
Access Data
Up to know we checked strings inside file or the size of the file. Those are useful but not enough for complete malware analysis. Malware generally have some signatures in the related memory ranges. We need to access data resides in these memory ranges. We will provide address and data we want to check with the following keywords.
int8(<offset or virtual address>) int16(<offset or virtual address>) int32(<offset or virtual address>) uint8(<offset or virtual address>) uint16(<offset or virtual address>) uint32(<offset or virtual address>) int8be(<offset or virtual address>) int16be(<offset or virtual address>) int32be(<offset or virtual address>) uint8be(<offset or virtual address>) uint16be(<offset or virtual address>) uint32be(<offset or virtual address>)
For example in this example we will check whether given file is a Portable Executable
(PE) file.
rule ThisIsPE { condition: // MZ signature at offset 0 and ... uint16(0) == 0x5A4D and // ... PE signature at offset stored in MZ header at 0x3C uint32(uint32(0x3C)) == 0x00004550 }
When we run the file with this rule we will get ThisIsPE
in the console like below. We have saved this rule as rule2.yara
Global Rules
During malware analysis we need some general rules t define. We call those as global rules and effects all rules in this run. We will simply put the global
keyword start of the global rule like below.
global rule SizeLimit { condition: filesize < 2MB }
Private Rules
Yara provides inheritance like feature to create basic rules and create super rules which inherits these basic rules conditions. In this situations we can use private
keyword before rule definition. We will use private rules for building blocks of other rules.
private rule PrivateRuleExample { ... }
Rules Tags
Tags are used while printing the matched rules in order to filter. They have no effect on matching. There is no restriction about tag count. In this rules Foo
, Bar
and Baz
are tags of the rules.
rule TagsExample1 : Foo Bar Baz { ... } rule TagsExample2 : Bar { ... }
Metadata
We may need to specify additional information about the rule. We can use metadata
for this work. We will create a new section with meta:
keyword like below.
rule MetadataExample { meta: my_identifier_1 = "Some string data" my_identifier_2 = 24 my_identifier_3 = true strings: $my_text_string = "text here" $my_hex_string = { E2 34 A1 C8 23 FB } condition: $my_text_string or $my_hex_string }
Modules
Modules are extensions for YARA. We can use some modules like PE
or Cuckoo
those comes with YARA. We can also write our own modules too. Modules can be imported with import
statement.
In this example we will import and use PE
module.
import "pe" rule Test { strings: $a = "some string" condition: $a and pe.entry_point == 0x1000 }
Including Other Files
We can include other rule files with include
keyword. We will simply include other yara rule files in the following example. We can use relative or absolute path without a problem.
include "/home/poftut/basics.yara"