Yara 规则

March 18, 2021 恶意木马检测 访问: 50 次

1、安装

 brew install yara

Ps: 一个很漫长的过程,需要下载的依赖有点多

2、测试

echo "rule dummy { condition: true }" > my_first_rule
yara my_first_rule my_first_rule

3、注释

//单行注释

/*
多行注释
*/

4、例子

rule my_rule
{
    meta:
        description = "This is just an example"
        thread_level = 3
        in_the_wild = true
    strings:
        $a = {6A 40 68 00 30 00 00 6A 14 8D 91}
        $b = {8D 4D B0 2B C1 83 C0 27 99 6A 4E 59 F7 F9}
        $c = "radish"
    condition:
        $a or $b or $c
}

meta是用于一些描述信息
strings是定义了$a $b $c 两个十六进制字符串(十六进制字符串用大括号括起来)和文本字符串(文本字符串直接用双引号括起来)

condition 规定了匹配的条件,样本中只要匹配到了$a $b $c 三个字符串中的任意一个,那么样本就会被识别位banker

5、尝试匹配

~/MyFile/study/编程语言/yara
❯ cat ./exp/test.txt
raradishdish
~/MyFile/study/编程语言/yara
❯ cat ./exp/test2.txt
ajhwvdigavkdgiveywgdv
~/MyFile/study/编程语言/yara
❯ yara test.yara ./exp
my_rule ./exp/test.txt

~/MyFile/study/编程语言/yara
❯ yara test.yara ./exp -c
./exp/test.txt: 1
./exp/test2.txt: 0

~/MyFile/study/编程语言/yara
❯

匹配文件头,需要注意的是,是小端序,有uint16和uint32

rule test2
{
    meta:
        description = "description"
        author = "author"
        date = "2021-03-18"
        reference = "reference"
        hash = "hash"
    condition:
        uint16(0) == 0x6172
}

结果:

❯ hexdump -C ./exp/test.txt
00000000  72 61 72 61 64 69 73 68  64 69 73 68              |raradishdish|
0000000c
~/MyFile/study/编程语言/yara 18s
❯ yara test2.yara ./exp/
test2 ./exp//test.txt

6、命令行参数

  • r:递归匹配子目录
  • m:输出详细信息
  • c:显示全部文件匹配后的结果
  • n:反转输出提示,匹配时无输出,不匹配时有输出

7、例子
匹配python文件

rule python_file
{
    meta:
        description = "this is python file"
        author = "radish"
        date = "2021-03-18"
        reference = "reference"
    strings:
        $sign = "if __name__==\"__main__\":"
    condition:
        $sign
}

strings中的字符串默认是区分大小写的,如果要不区分大小写,加入nocase关键字,如下所示:

rule python_file
{
    meta:
        description = "this is python file"
        author = "radish"
        date = "2021-03-18"
        reference = "reference"
    strings:
        $sign = "if __name__==\"__main__\":" nocase
    condition:
        $sign
}

8、not关键字

rule ID_number
{
    meta:
        description = "description"
        author = "author"
        date = "2021-03-18"
        reference = "reference"
        hash = "hash"
    strings:
        $id = /[0-9]{18}/
        $py = "if __name__==\"__main__\":"
    condition:
        $id and not $py
}

结果:

yara ID_number.yara ./exp -c
ID_number.yara(10): warning in rule "ID_number": $id is slowing down scanning
./exp/my_exp.py: 1
./exp/test2.txt: 1
./exp/test.txt: 0

~/MyFile/study/编程语言/yara
❯ yara ID_number.yara ./exp -c
ID_number.yara(10): warning in rule "ID_number": $id is slowing down scanning
./exp/test2.txt: 1
./exp/test.txt: 0
./exp/my_exp.py: 0

~/MyFile/study/编程语言/yara

可以看到 ,脚本结果都输出了一句话:warning in rule "ID_number": $reg is slowing down scanning
这是因为正则表达式写的不好,如果文件比较大的话,就会引起性能的降低

9、限制文件大小

rule file_size
{
    meta:
        description = "description"
        author = "author"
        date = "2021-03-18"
        reference = "reference"
        hash = "hash"
    condition:
        filesize > 72KB
}

10、匹配PE文件start处二进制
这里需要导入“pe”,
-w947

import "pe"
rule pe_rule
{
    meta:
        description = "description"
        author = "author"
        date = "2021-03-18"
        reference = "reference"
        hash = "hash"
    strings:
        $entry = {F8 4A 90 FD 9B}
    condition:
        $entry at pe.entry_point and filesize > 72KB
}

结果:成功筛选出来

❯ yara pe_rule.yara ./exp -c
./exp/windows_exec.til: 0
./exp/my_exp.py: 0
./exp/test.txt: 0
./exp/windows_exec.id2: 0
./exp/windows_dllinject_reverse_http_proxy_pstore.exe: 0
./exp/windows_exec.nam: 0
./exp/test2.txt: 0
./exp/windows_exec.exe: 1
./exp/windows_dllinject_reverse_hop_http.exe: 0
./exp/windows_dllinject_reverse_ord_tcp.exe: 0
./exp/windows_dllinject_reverse_ipv6_tcp.exe: 0
./exp/windows_dllinject_reverse_winhttp.exe: 0
./exp/windows_dllinject_reverse_http.exe: 0
./exp/windows_download_exec.exe: 0
./exp/windows_exec.id0: 0
./exp/windows_format_all_drives.exe: 0
./exp/windows_dllinject_reverse_nonx_tcp.exe: 0
./exp/windows_exec.id1: 0

另一种写法:

import "pe"
rule pe_rule
{
    meta:
        description = "description"
        author = "author"
        date = "2021-03-18"
        reference = "reference"
        hash = "hash"
    // strings:
    //     $entry = {F8 4A 90 FD 9B}
    condition:
        // $entry at pe.entry_point and filesize > 72KB
        pe.entry_point == 0x0000163C and filesize > 72KB
}

同样也可以筛选出来

11、匹配PE文件中导入表的函数

导入“pe”

import "pe"
rule pe_rule
{
    meta:
        description = "description"
        author = "author"
        date = "2021-03-18"
        reference = "reference"
        hash = "hash"
    condition:
        pe.imports("KERNEL32.dll","LocalFree")
}

结果:

❯ yara pe_rule.yara ./exp -c
./exp/my_exp.py: 0
./exp/test.txt: 0
./exp/test2.txt: 0
./exp/windows_exec.id2: 0
./exp/windows_exec.til: 0
./exp/windows_dllinject_reverse_hop_http.exe: 1
./exp/windows_dllinject_reverse_winhttp.exe: 1
./exp/windows_format_all_drives.exe: 1
./exp/windows_exec.nam: 0
./exp/windows_dllinject_reverse_ipv6_tcp.exe: 1
./exp/windows_dllinject_reverse_nonx_tcp.exe: 1
./exp/windows_dllinject_reverse_http.exe: 1
./exp/windows_exec.id0: 0
./exp/windows_exec.exe: 1
./exp/windows_exec.id1: 0
./exp/windows_dllinject_reverse_ord_tcp.exe: 1
./exp/windows_dllinject_reverse_http_proxy_pstore.exe: 1
./exp/windows_download_exec.exe: 1

12、 其他语法

$:字符串定义
#:表示字符串在文件或内存中出现的次数

#a == 1 or #b > 4 and #c < 6  //a出现1次或b大于四次且c小于6次

in表示文件偏移

$a in(1..100)  //a的地址在1与100之间

uin和int:访问文件偏移和访问内存虚拟地址。可以是8、16、32,uin读取的是无符号整数,int读取的是有符号整数,默认读取的是小端

condition:         
        // MZ 
        uint16(0) == 0x5A4D and
        // PE
        uint32(uint32(0x3C)) == 0×00004550

of : 集合

2 of ($a,$b,$c) // 满足 a、b、c任意两个即可匹配到

?? 、 ?分别代表 在十六进制字符串中匹配 一字节未知数和半字节未知数

":双引号
\:反斜杠
t:制表符
n:换行符

fullword:表示匹配单个词组文本字符串

$sign = "radish" fullword  // 能匹配到 "radish asd" ,不能匹配到 “radradishish”

them关键字:
表示strings中的所有变量


rule ThreeRappersPresent
{
    strings:
        $m1 = "Quavo"
        $m2 = "Offset"
        $m3 = "Takeoff"
        $q1 = "Cardi B"
 
    condition:
        3 of them // equivalent to 3 of ($*)

ascii:限制字符串的编码格式是ascii

不定表通配符

strings:
    $sign_1 = {23 21 2f [2] 72 2f 62}//占两个位置
    $sign_2 = {23 21 2f [2-4] 72 2f 62}//占两个到4四个位置
    $sign_3 = {23 21 2f [-] 72 2f 62}//占无限长

有条件的十六进制字符串

strings:
       $hex_string = { BA 21 ( DA BC | C6 ) A5 }

匹配结果

BA 21 DA BC A5
BA 21 C6 A5

宽字符串

wide修饰符可以用来搜寻以2字节表示1字符这种方式编码的字符串, 这种宽字符串在许多二进制文件中都有出现

$fat_villain = "FatTony" wide nocase

匹配长度

在字符串标识符前加一个!得到匹配长度

condition:
        !re1[1] == 4 and !re1[2] > 6

!a[1]是第一个匹配到的字符串$a的长度, 而!a[2]就是第二个匹配到的字符串的长度, 依此类推. !a是!a[1]的缩写.

添加新评论