YARA规则摘要

原文链接:https://yara.readthedocs.io/en/v3.7.0/writingrules.html

一个简单的yara规则示范:

rule ExampleRule
{
    strings:
        $my_text_string = "text here"
        $my_hex_string = { E2 34 A1 C8 23 FB }

    condition:
        $my_text_string or $my_hex_string
}

yara规则由rule引导,后跟一个类似C语言变量格式的字符串作为规则名称,长度不能超过128字节。花括号定义规则内容。

规则中用户定义的字符串变量由$字符引导,变量由字母、数字或下划线组成,不能是保留的关键字。

yara规则中的关键字:

allandanyasciiatconditioncontains
entrypointfalsefilesizefullwordforglobalin
importincludeint8int16int32int8beint16be
int32bematchesmetanocasenotorof
privaterulestringsthemtrueuint8uint16
uint32uint8beuint16beuint32bewide

字符串变量可以是由双引号""界定的文本内容,也可以是花括号{}界定的十六进制字符串。

注释

类似于C语言,支持行注释//和块注释/**/

字符串

十六进制字符串

  • 占位符?
    示例:{ E2 34 ?? C8 A? FB }?代表任意值的半字节内容。

  • 范围[x-y](0<=x<=y)
    示例:{ F4 23 [4-6] 62 B4 [6] EA BB [10-] FF [-]}
    [4-6]代表任意4-6个字节;
    [6][6-6]的简写形式,代表6个字节;
    [10-]代表10个字节及以上;
    [-]代表任意多个字节。

  • 多选|
    示例:{ F4 23 ( 62 B4 | 56 | 45 ?? 67 ) 45 }
    圆括号内使用|字符分隔的内容匹配任意一个即可。

文本字符串

双引号界定的文本内容:"foobar"
转义字符:

\"双引号
\\反斜杠
\tTab
\n换行符
\xdd定义字节

字符串修饰

  • nocase
    查找时需要忽略大小写:$text_string = "foobar" nocase
  • ascii
    默认定义的字符串为ascii格式,可以省略。
  • wide
    定义宽字符:$wide_string = "Borland" wide。仅通过在ascii字符之间插入0字节实现,不支持非ascii字符。
    同时定义宽字符和ascii字符:$wide_and_ascii_string = "Borland" wide ascii
  • fullword
    全字搜索:$text_string = "foobar" fullword。搜索时确保字符串的前后字节不是字母。

正则表达式

元字符:

\转义元字符
^匹配文件开头
$匹配文件末尾
|多选
()分组
[]字符集

量词:

*匹配0或多次
+匹配1或多次
?匹配0或1次
{n}匹配n次
{n,}匹配至少n次
{,m}匹配最多m次
{n,m}匹配n到m次

默认使用贪婪模式匹配,在量词后面追加?字符切换为非贪婪模式。

其它转义字符:

\tTab
\n换行
\r回车
\f换页
\aAlarm
\xNN定义字节

字符类:

\w匹配一个字母数字下划线中的字符
\W匹配一个非字母数字下划线中的字符
\s匹配一个空白字符
\S匹配一个非空白字符
\d匹配一个数字字符
\D匹配个非数字字符
\b匹配一个字的边界(3.3.0)
\B匹配一个非字边界(3.3.0)

条件

类似于编程语言的布尔表达式,支持逻辑运算符:and,or,not,关系运算符:>=,<=,<,>,==,~=,算术运算符:+,-,*,\,%,位运算符:&,|,<<,>>,~,^。条件中出现的数字默认为十进制,如果要使用十六进制需要加上前导内容0x

字符串变量可以直接作为布尔值使用,存在匹配时为true,否则为false
示例:

rule Example
{
    strings:
        $a = "text1"
        $b = "text2"
        $c = "text3"
        $d = "text4"

    condition:
        ($a or $b) and ($c or $d)
}

匹配次数

字符串变量的前导字符$替换成#,代表该字符串在目标(文件或进程)出现的次数,可以直接在条件表达式中使用。

rule CountExample
{
    strings:
        $a = "dummy1"
        $b = "dummy2"

    condition:
        #a == 6 and #b > 10
}

匹配文件偏移或虚拟地址

使用at指定字符串在指定位置进行匹配。

rule AtExample
{
    strings:
        $a = "dummy1"
        $b = "dummy2"

    condition:
        $a at 100 and $b at 200
        //或在指定的范围内匹配
        //$a in (0..100) and $b in (100..filesize)
}

@a[i]:获取第i个匹配的偏移或地址。i从1开始计数。如果i超出范围则返回一个空值。
!a[i]:获取第i个匹配结果的长度。i从1开始计数。!a代表第一个匹配结果的长度。

File size

filesize代表目标文件的长度字节,如果目标是进程则该变量无意义。

rule FileSizeExample
{
    condition:
       filesize > 200KB
}

KB前面的数字只能是十进制,还支持MB。(GB是否支持文档没说)

取值

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>)

u开头的读取无符号整数,be结尾的按big-endian字节序读取。
示例:

rule IsPE
{
  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
}

字符串集合

使用of关键字检查任意或多个字符串的匹配。示例:

rule OfExample1
{
    strings:
        $foo1 = "dummy1"
        $foo2 = "dummy2"
        $bar1 = "dummy3"
        $bar2 = "dummy4"

    condition:
        2 of ($foo1,$foo2,$bar1,$bar2) //至少有两个匹配
        //或使用以下形式匹配规则内字符串变量
        //2 of($foo*,$bar*)
        //或使用$*匹配规则内所有字符串变量($*与them相同)
        //2 of ($*)
        //2 of them
        //of前面的数字可以使用以下关键字:
        //any of them //匹配任意一个
        //all of them //匹配所有
        //all of ($foo*)
}

多个字符串应用同一个条件

语法:for expression of string_set : ( boolean_expression )
示例:

any of ($a,$b,$c)
for any of ($a,$b,$c) : ( $ )
for all of them : ( # > 3 )
for all of ($a*) : ( @ > @b )

圆括号中的占位符功能:
$代表正在评估的字符串;
#代表正在评估的字符串出现的次数;
@代表正在评估的字符串第一个匹配所在的偏移或虚拟地址。

使用匿名变量

rule AnonymousStrings
{
    strings:
        $ = "dummy1"
        $ = "dummy2"

    condition:
        1 of them
}

匹配结果遍历

语法:for expression identifier in indexes : ( boolean_expression )
示例:

rule Occurrences
{
    strings:
        $a = "dummy1"
        $b = "dummy2"

    condition:
        for all i in (1,2,3) : ( @a[i] + 10 == @b[i] )
        //也可写为
        //for all i in (1..3) : ( @a[i] + 10 == @b[i] )
        //可使用变量代替循环范围
        //for all i in (1..#a) : ( @a[i] < 100 )
}

引用其它规则

示例:

rule Rule1
{
    strings:
        $a = "dummy1"

    condition:
        $a
}

rule Rule2
{
    strings:
        $a = "dummy2"

    condition:
        $a and Rule1
}

规则设置

全局规则

全局规则在所有其它规则之前评估,如果结果为false则不会再评估其它规则。允许存在多个全局规则。
示例:

global rule SizeLimit
{
    condition:
        filesize < 2MB
}

私有规则

私有规则不会像全局规则一样对结果产生影响,评估后也不会提交给yara,但可以与其它规则混合使用。
示例:

private rule PrivateRuleExample
{
    ...
}

可以对一个规则同时定义全局和私有属性,评估后不会提交给yara,但必须满足条件。

规则标签

规则后面添加标签,用于过滤输出。在命令行使用时通过-t <tag>--tag=<tag>选项指定需要输出的标签。一个规则允许有多个标签,使用空格隔开。标签的名称格式与变量相同。
示例:

rule TagsExample1 : Foo Bar Baz
{
    ...
}

rule TagsExample2 : Bar
{
    ...
}

元数据

仅用于存储规则的附加信息,不能在条件中使用,支持文本、整数和布尔值字符串(true/false)。
示例:

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
}

使用模块

必须在规则外部导入模块:

import "pe"
import "cuckoo"

使用<module name>.引用模块变量:

pe.entry_point == 0x1000
cuckoo.http_request(/someregexp/)

未定义的值

yara确保模块中未定义的变量在使用时结果永远为undefinedpe.entry_point指向PE文件的入口地址,但是在扫描一个非PE文件时,该变量是没有值的。示例:

import "pe"

rule Test
{
  strings:
      $a = "some string"

  condition:
      $a and pe.entry_point == 0x1000
}

该规则匹配结果始终为undefined。但是如果将条件改为$a or pe.entry_point == 0x1000,且目标不是PE文件,则以$a的结果为准。

扩展变量

扩展变量由外部定义,可以在条件中直接使用。
示例1:

rule ExternalVariableExample1
{
    condition:
       ext_var == 10
}

示例2:

rule ExternalVariableExample3
{
    condition:
        string_ext_var contains "text"
}

rule ExternalVariableExample4
{
    condition:
        string_ext_var matches /[a-z]+/is
}

正则表达式末尾追加i表示忽略大小写,追加s表示只在同一行进行匹配。

外部变量必须在运行时定义。yara-python中的compilematch函数的externals参数可以指定外部变量。外部变量的值支持文本、整数和布尔值。在命令行可以通过-d选项定义。

包含文件

使用include关键字包含其它规则文件。在Linux系统中允许使用相对路径或绝对路径,在windows中必须使用绝对路径。
Linux系统示例:

include "./includes/other.yar"
include "../includes/other.yar"
include "/home/plusvic/yara/includes/other.yar"

Windows系统示例:

include "c:/yara/includes/other.yar"
include "c:\\yara\\includes\\other.yar"
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值