【逆向】Yara规则编写安装与使用教程

摘要:
前言Yara是一个能够帮助恶意软件研究人员识别和分类恶意软件样本的工具。规则标识符区分大小写,并且不能超过128个字符。以下关键字是保留的,不能用作标识:注释你可以像编写C语言一样,在Yara规则中添加注释:1//单行注释23/*4多行注释5*/ViewCode字符串Yara中有三种类型的字符串:十六进制串:定义原始字节序列1//通配符:可以代替某些未知字节,与任何内容匹配2ruleWildcardExample3{4strings:5//使用‘?’作为通配符6$hex_string={0011??
前言

Yara是一个能够帮助恶意软件研究人员识别分类恶意软件样本的工具(类似正则表达式)。
规则可以通过文本二进制的模式被创建,并且每个规则均由一组字符串和一个布尔表达式组成。

1 //示例规则
2 rule Test : Trojan
3 {
4     //规则描述
5 meta:
6         author = "Sunset"
7         date = "2020-04-08"
8         description = "Trojan Detection"
9 
10     //规则字符串
11 strings:
12         $a = {6A 40 68 00 30 00 00 6A 14 8D 91}
13         $b = {8D 4D B0 2B C1 83 C0 27 99 6A 4E 59F7 F9}
14         $c = "UVODFRYSIHLNWPEJXQZAKCBGMT"
15 
16     //条件表达式
17 condition:
18 $a or $b or $c
19 }
View Code
编译下载

项目:https://github.com/virustotal/yara

releases:https://github.com/VirusTotal/yara/releases

【逆向】Yara规则编写安装与使用教程第1张

1 --atom - quality - table = FILE             //
2 - C, --compiled - rules                     //加载编译规则
3 - c, --count                                //只打印命中的规则数量
4 - d, --define = VAR = VALUE                 //定义外部变量
5      --fail - on - warnings                 //失败警告
6 - f, --fast - scan                          //快速匹配模式
7 - h, --help                                 //显示帮助并退出
8 - i, --identifier = IDENTIFIER              //匹配指定名称的规则(使用指定名称的规则进行匹配)
9 - l, --max - rules = NUMBER                 //匹配多个规则后中止扫描
10      --max - strings - per - rule = NUMBER  //设置每个规则的最大字符串数量(默认 = 10000)
11 - x, --module - data = MODULE = FILE        //将文件内容作为额外数据传递给模块
12 - n, --negate                               //只打印不匹配的规则
13 - w, --no - warnings                        //禁用警告
14 - m, --print - meta                         //打印元数据(在命中结果中显示:规则元数据)
15 - D, --print - module - data                //打印模块数据(在命中结果中显示:规则名称与样本名称)
16 - e, --print - namespace                    //打印规则的名称空间
17 - S, --print - stats                        //打印规则的统计信息
18 - s, --print - strings                      //打印匹配的字符串
19 - L, --print - string - length              //打印匹配的字符串长度(字符串在文件中的偏移与长度)
20 - g, --print - tags                         //打印标签(显示命中规则的标签)
21 - r, --recursive                            //递归搜索目录(匹配该目录下的所有样本文件)
22 - k, --stack - size = SLOTS                 //设置最大堆栈大小(默认值为16384)
23 - t, --tag = TAG                            //匹配指定标签的规则(使用指定规则标签进行匹配,标签区分大小写)
24 - p, --threads = NUMBER                     //指定多少线程数来扫描目录
25 - a, --timeout = SECONDS                    //指定多少秒后中止扫描
26 - v, --version                              //显示版本信息
View Code
规则编写

Yara规则语法类似于C语言,易于编写和理解,每个规则都以关键字“rule”开头,后面跟着一个规则标识符。
标识符必须遵循与C语言相同的词法约定,它们可以包含任何字母数字和下划线,但第一个字符不能是数字
规则标识符区分大小写,并且不能超过128个字符。以下关键字是保留的,不能用作标识:

【逆向】Yara规则编写安装与使用教程第2张

注释

你可以像编写C语言一样,在Yara规则中添加注释:

1 //单行注释
2 
3 /*
4 多行注释
5 */
View Code

字符串

Yara中有三种类型的字符串:
十六进制串:定义原始字节序列

1 //通配符:可以代替某些未知字节,与任何内容匹配
2 rule WildcardExample
3 {
4 strings:
5        //使用‘?’作为通配符
6        $hex_string = { 00 11 ?? 33 4? 55}
7 
8 condition:
9 $hex_string
10 }
11 
12 //跳转:可以匹配长度可变的字符串
13 rule JumpExample
14 {
15 strings:
16            //使用‘[]’作为跳转,与任何长度为0-2字节的内容匹配
17            $hex_string1 = { 00 11 [2] 44 55}
18            $hex_string2 = { 00 11 [0-2] 44 55}           
19            //该写法与string1作用完全相同
20            $hex_string3 = { 00 11 ?? ?? 44 55}
21 
22 condition:
23 $hex_string1 and $hex_string2
24 }
25 
26 //也可以使用类似于正则表达式的语法
27 rule AlternativesExample1
28 {
29 strings:
30        $hex_string = { 00 11 ( 22 | 33 44 ) 55}
31        /*
32 可以匹配以下内容:
33 00 11  22  55
34 00 11  33 44  55
35        */
36        
37 condition:
38 $hex_string
39 }
40 
41 //还可以将上面介绍的方法整合在一起用
42 rule AlternativesExample2
43 {
44 strings:
45        $hex_string = { 00 11 ( 33 44 | 55 | 66 ?? 88 ) 99}
46 
47 condition:
48 $hex_string
49 }
View Code

文本字符串:定义可读文本的部分

1 //转义符:
2     \"双引号
3 \\        反斜杠
4 \t        制表符
5 \n        换行符
6 \xdd      十六进制的任何字节
7     
8 //修饰符:
9 nocase:  不区分大小写
10 wide:    匹配2字节的宽字符
11 ascii:   匹配1字节的ascii字符
12 xor:     匹配异或后的字符串
13 fullword:匹配完整单词
14     private: 定义私有字符串
15     
16 rule CaseInsensitiveTextExample
17 {
18 strings:
19         //不区分大小写
20         $text_string = "foobar"nocase
21         //匹配宽字符串
22         $wide_string = "Borland"wide
23         //同时匹配2种类型的字符串
24         $wide_and_ascii_string = "Borland"wide ascii
25         //匹配所有可能的异或后字符串
26         $xor_string = "This program cannot"xor
27         //匹配所有可能的异或后wide ascii字符串
28         $xor_string = "This program cannot"xor wide ascii
29         //限定异或范围
30         $xor_string = "This program cannot" xor(0x01-0xff)
31         //全词匹配(匹配:www.domain.com  匹配:www.my-domain.com  不匹配:www.mydomain.com)
32         $wide_string = "domain"fullword
33         //私有字符串可以正常匹配规则,但是永远不会在输出中显示
34         $text_string = "foobar" private
35         
36 condition:
37 $text_string
38 }
View Code

正则表达式:定义可读文本的部分

条件表达式

你可以在条件表达中使用如下运算符:

【逆向】Yara规则编写安装与使用教程第3张

all any them

1 all of them       //匹配规则中的所有字符串
2 any of them       //匹配规则中的任意字符串
3 all of ($a*)      //匹配标识符以$a开头的所有字符串
4 any of ($a,$b,$c) //匹配a, b,c中的任意一个字符串
5 1 of ($*)         //匹配规则中的任意一个字符串
View Code

#

1 //===匹配字符串在文件或内存中出现的次数
2 rule CountExample
3 {
4 strings:
5         $a = "dummy1"
6         $b = "dummy2"
7 
8 condition:
9         //a字符串出现6次,b字符串大于10次
10         #a == 6 and #b > 10
11 }
View Code

@

1 //可以使用@a[i],获取字符串$a在文件或内存中,第i次出现的偏移或虚拟地址
2 //小标索引从1开始,并非0
3 //如果i大于字符串出现的次数,结果为NaN(not a number 非数值)
View Code

1 //可以使用!a[i],获取字符串$a在文件或内存中,第i次出现时的字符串长度   
2 //下标索引同@一样都是从1开始
3 //!a 是 !a[1]的简写
View Code

at

1 //===匹配字符串在文件或内存中的偏移
2 rule AtExample
3 {
4 strings:
5         $a = "dummy1"
6         $b = "dummy2"
7 
8 condition:
9         //a和b字符串出现在文件或内存的100和200偏移处
10         $a at 100 and $b at 200
11 }
View Code

in

1 //===在文件或内存的某个地址范围内匹配字符串
2 rule InExample
3 {
4 strings:
5         $a = "dummy1"
6         $b = "dummy2"
7 
8 condition:
9         $a in (0..100) and $b in (100..filesize)
10 }
View Code

filesize

1 //===使用关键字匹配文件大小
2 rule FileSizeExample
3 {
4 condition:
5        //filesize只在文件时才有用,对进程无效
6        //KB MB后缀只能与十进制大小一起使用
7        filesize >200KB
8 }
View Code

entrypoint

1 //===匹配PE或ELF文件入口点(高版本请使用PE模块的pe.entry_point代替)
2 rule EntryPointExample1
3 {
4 strings:
5         $a = { E8 00 00 00 00}
6 
7 condition:
8 $a at entrypoint
9 }
10 
11 rule EntryPointExample2
12 {
13 strings:
14         $a = { 9C 50 66 A1 ?? ?? ?? 00 66 A9 ?? ?? 58 0F 85}
15 
16 condition:
17        $a in (entrypoint..entrypoint + 10)
18 }
View Code

intxxx uintxxx

1 //===从指定的文件或内存偏移处读取数据
2 //小端: 有符号整数
3 int8(<offset or virtual address>)
4 int16(<offset or virtual address>)
5 int32(<offset or virtual address>)
6 
7 //小端: 无符号整数
8 uint8(<offset or virtual address>)
9 uint16(<offset or virtual address>)
10 uint32(<offset or virtual address>)
View Code

intxxxbe uintXXXbe

1 //大端: 有符号整数
2 int8be(<offset or virtual address>)
3 int16be(<offset or virtual address>)
4 int32be(<offset or virtual address>)
5 
6 //大端: 无符号整数
7 uint8be(<offset or virtual address>)
8 uint16be(<offset or virtual address>)
9 uint32be(<offset or virtual address>)
10 
11 //应用示例
12 rule IsPE
13 {
14 condition:
15      //判断是否PE文件
16      uint16(0) == 0x5A4Dand
17      uint32(uint32(0x3C)) == 0x00004550
18 }
View Code

of

1 //===匹配多个字符串中的某几个
2 rule OfExample1
3 {
4 strings:
5         $a = "dummy1"
6         $b = "dummy2"
7         $c = "dummy3"
8 
9 condition:
10         //3个字符串只需匹配任意2个
11         2of ($a,$b,$c)
12 }
View Code

for xxx of xxx :(xxx)

1 //功能:
2 对多个字符串匹配相同的条件
3 //格式:
4 forAAA of BBB : ( CCC )
5 //含义:
6 在BBB字符串集合中,至少有AAA个字符串,满足了CCC的条件表达式,才算匹配成功。
7 在CCC条件表达式中,可以使用'$'依次代替BBB字符串集合中的每一个字符串。
8 
9 //for..of其实就是of的特别版,所以下面2个例子作用相同
10 any of ($a,$b,$c)
11 forany of ($a,$b,$c) : ( $ )
12 
13 //在abc3个字符串集合中,至少有1个字符串,必须满足字符串内容与entrypoint相同的条件
14 for 1of ($a,$b,$c) : ( $ at entrypoint  )
15 forany of ($a,$b,$c) : ( $ at entrypoint  )
16 
17 //所有字符串,在文件或内存中出现的次数必须大于3,才算匹配成功。
18 for all of them : ( # > 3)
19 
20 //所有以$a开头的字符串,在文件或内存中第2次出现的位置必须小于9
21 for all of ($a*) : (@[2] < 0x9)
View Code

for xxx i in (xxx) :(xxx)

1 //格式:
2 for AAA BBB in(CCC) : (DDD)
3 //含义:
4 作用与for of类似,只是增加了下标变量与下标范围,具体看示例
5 
6 //$b在文件或内存中出现的前3次偏移,必须与$a在文件或内存中出现的前3次偏移+10相同
7 for all i in (1,2,3) : ( @a[i] + 10 ==@b[i] ) 
8 for all i in (1..3) : ( @a[i] + 10 ==@b[i] )
9 
10 //$a每次在文件或内存中出现位置,都必须都小于100
11 for all i in (1..#a) : ( @a[i] < 100)
12 
13 //其它示例
14 for any i in (1..#a) : ( @a[i] < 100)
15 for 2 i in (1..#a) : ( @a[i] < 100 )
View Code

引用其它规则

1 rule Rule1
2 {
3 strings:
4         $a = "dummy1"
5 
6 condition:
7 $a
8 }
9 
10 rule Rule2
11 {
12 strings:
13         $a = "dummy2"
14 
15 condition:
16 $a and Rule1
17 }
View Code

全局规则

1 //全局规则(global rule)可以在匹配其他规则前优先筛选,
2 //比如在匹配目标文件之前需要先筛选出小于2MB的文件,在匹配其他规则
3 globalrule SizeLimit
4 {
5 condition:
6         filesize <2MB
7 }
View Code

私有规则

1 //私有规则(private rule)可以避免规则匹配结果的混乱,
2 //比如使用私有规则进行匹配时,YARA不会输出任何匹配到的私有规则信息
3 //私有规则单独使用意义不大,一般可以配合"引用其它规则"的功能一起使用
4 //私有规则也可以和全局规则一起使用,只要添加“Private”、“global”关键字即可
5 privaterule PrivateRuleExample
6 {
7 ...
8 }
View Code

规则标签

1 //规则标签,可以让你在YARA输出的时候只显示你感兴趣的规则,而过滤掉其它规则的输出信息
2 //你可以为规则添加多个标签
3 rule TagsExample1 : Foo Bar Baz
4 {
5 ...
6 }
7 
8 rule TagsExample2 : Bar
9 {
10 ...
11 }
View Code

导入模块

1 //使用“import”导入模块
2 //你可以自己编写模块,也可以使用官方或其它第三方模块
3 //导入模块后,就可以开始使用模块导出的变量或函数
4 import "pe"
5 import "cuckoo"
6 
7 pe.entry_point == 0x1000
8 cuckoo.http_request(/someregexp/)
View Code

外部变量

1 //外部变量允许你在使用YARA -d命令时指定一个自定义数据,
2 //该数据可以是整数、字符串、布尔变量,具体看以下示例
3 
4 //使用布尔变量和一个整数变量作为判断条件
5 rule ExternalVariableExample2
6 {
7 condition:
8        bool_ext_var or filesize <int_ext_var
9 }
10 
11 //字符串变量可以与以下运算符一起使用:
12 contains:如果字符串包含指定的子字符串,返回True
13 matches: 如果字符串匹配给定的正则表达式时,返回True
14 
15 rule ExternalVariableExample3
16 {
17 condition:
18         string_ext_var contains "text"
19 }
20 
21 rule ExternalVariableExample4
22 {
23 condition:
24         string_ext_var matches /[a-z]+/
25 }
View Code

文件包含

1 //作用于C语言一样,可以包含其它规则到当前文件中
2 include "other.yar"
3 
4 //相对路径
5 include "./includes/other.yar"
6 include "../includes/other.yar"
7 
8 //全路径
9 include "/home/plusvic/yara/includes/other.yar"
View Code
参考资料

https://github.com/virustotal/yara
https://github.com/Yara-Rules/rules
https://yara.readthedocs.io/en/stable/
https://github.com/InQuest/awesome-yara
https://bbs.pediy.com/thread-226011.htm

免责声明:文章转载自《【逆向】Yara规则编写安装与使用教程》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇VirtualBox 之 共享磁盘CentOS VNC配置(转)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

EasyPoi 导入导出Excel时使用GroupName的踩坑解决过程

一、开发功能介绍: 简单的一个excel导入功能 二、Excel导入模板(大致模板没写全): 姓名 性别 生日 客户分类 联系人姓名 联系人部门  备注 材料 综合 采购 张三 男 1994/05/25 1 1 1 张三 开发部   李四 男 1994/05/25 1 1 1 张三 开发部   王五 男 1994/05/25 1 1 1...

java中String编码转换 UTF-8转GBK

1.GB2312等都可以用GBK代替.2.new String(row.getBytes("GB2312"), "UTF8") 这种写法是不对的, 中文仍然会乱码. 方案:解决GBK字符转UTF-8乱码问题: https://www.cnblogs.com/xijin-wu/p/5884822.html 彻底搞懂编码 GBK 和 UTF8:https:/...

简道云--公式与函数的使用教程

公式与函数 在制作表单时,可以设置控件与控件之间的数据联动关系。给例如编辑完单价和数量后,自动计算总价等这样的业务场景提供了支撑。 公式面板左侧可以选择当前表单控件所对应的值,以及所有表单控件所对应的字段名。被选择后,在公式面板中会以反引号包裹的形式显示。 注意:函数在简道云里的设置是大写,即在运用函数的时候,请用纯大写字母。 表单控件与其返回值的数据类型...

Thrift的TJsonProtocol协议分析

Thrift协议实现目前有二进制协议(TBinaryProtocol),紧凑型二进制协议(TCompactProtocol)和Json协议(TJsonProtocol)。 前面的两篇文字从编码和协议原理方面分析了TBinaryProtocol和TCompactProtocol协议,下面对TJsonProtocol协议做一下分析。 TJsonProtocol...

Effective Modern C++:05右值引用、移动语义和完美转发

         移动语义使得编译器得以使用成本较低的移动操作,来代替成本较高的复制操作;完美转发使得人们可以撰写接收任意实参的函数模板,并将其转发到目标函数,目标函数会接收到与转发函数所接收到的完全相同的实参。右值引用是将这两个不相关的语言特性连接起来的底层语言机制,正是它使得移动语义和完美转发成了可能。 23:理解std::move和std::forw...

java解决大文件断点续传

第一点:Java代码实现文件上传 FormFile file = manform.getFile(); String newfileName =null; String newpathname =null; String fileAddre ="/numUp"; try { InputStream stream = file.getInputStream(...