1. 文本(Text Strings)
下面是一个包含文本字符串规则的示例。字符串标识符 $text_string 代表的是一个文本类字符串,其内容由双引号包裹。
rule TextExample
{
strings:
$text_string = "foobar"
condition:
$text_string
}
文本字符串包含一些修饰符,可以改变字符串的解释方式。这些修饰符附加在字符串的末尾,并用空格进行分割。
1.1 大小写不敏感(Case-insensitive strings)
Yara规则中文本字符串匹配时默认是区分大小写的。关键字"nocase"的使用可以使字符串匹配时大小写不敏感。如下所示:
rule CaseInsensitiveTextExample
{
strings:
// 下面规则只能命中字符串"foobar"
$text_string1 = "foobar"
// 下面规则除了可命中"foobar",还可以命中"FOOBAR"、"FooBar"等。
$text_string2 = "foobar" nocase
condition:
$text_string
}
1.2 宽字符(Wide-character strings)
在二进制文件中经常会看到一个ASCII字符会被编码成两个字符,例如:
Borland ==> B\x00o\x00r\x00l\x00a\x00n\x00d\x00
// 其实就是在每个ASCII字符后面添加一个\x00空字符,在ASCII字符串中插入这些空字符无法直接打印,一般用于矿平台兼容、内存对齐等作用。
针对ASCII字符串会被插入空字符的匹配场景中,可以使用关键字"wide"来适配。如果说不确定是否被插入空字符(\x00),可以同时使用关键字"wide"和"ascii"。默认情况下,字符串使用"ascii"(ASCII字符)模式匹配。
rule WideCharTextExample
{
strings:
// 下面规则匹配字符串 "f\x00o\x00o\x00b\x00a\x00r\x00"
$text_string1 = "foobar" wide
// 既匹配"f\x00o\x00o\x00b\x00a\x00r\x00",也匹配"foobar"
$text_string2 = "foobar" wide ascii
condition:
$wide_and_ascii_string
}
注意:关键字"wide"只是将ASCII字符串中插入一些"\x00"字符,并不是将其编码为UTF-16格式用来表示除ASCII以外的字符。
1.3 异或字符串(XOR strings)
恶意软件有时会使用xor操作来混淆字符串,使得静态分析时难以直接识别字符串内容。针对此场景可以使用Yara中关键字"xor"来对这些字符串进行解密操作,以便进行匹配。下面是"xor"使用示例:
rule XorExample
{
strings:
// xor关键字使得Yara不仅匹配"This program cannot"字符串,还匹配此字符串的每个字节与0x01~0xFF分别xor后的每个新生成的字符串。
$xor_string_00 = "This program cannot" xor
condition:
any of them
}
// 上面规则等同于下面这条规则
rule XorExample2
{
strings:
// 这是原始的字符串。
$xor_string_00 = "This program cannot"
// 这是原始字符串的每个字节与0x01异或后生成的新字符串。
$xor_string_01 = "Uihr!qsnfs`l!b`oonu"
// 这是原始字符串的每个字节与0x02异或后生成的新字符串。
$xor_string_02 = "Vjkq\"rpmepco\"acllmv"
// 以此类推,分别将原始字符串与0x03、0x04、...、0xFF进行xor操作生成新的字符串。
... ...
condition:
any of them
}
除此之外,关键字"xor"还能和"wide"、"ascii"关键字一齐使用。不过"xor"关键字优先级相较其它两个低,因此配合使用时,先根据其它两个关键字变形生成对应的新串,然后再对新串执行xor操作。
rule XorExample
{
strings:
$xor_string = "This program cannot" xor wide ascii
condition:
$xor_string
}
Yara3.11版本之后,可以控制关键字"xor"进行异或的范围,如下所示:
rule XorExample
{
strings:
// 只对原始字符串的每个字节分别与0x01、0x02进行异或操作,也就是说只会生成两个变形后的字符串。
$xor_string = "This program cannot" xor(0x01-0x2)
condition:
$xor_string
}
1.4 Base64字符串(Base64 strings)
Base64是网络中常见的传输编码方式之一。这种编码方法常用于使用文本格式表示二进制数据,例如在电子邮件、URL或配置文件中。Yara规则中关键字"base64"可用于匹配经过Base64算法编码后的字符串。如下图所示:
rule Base64Example
{
strings:
$a = "This program cannot" base64
condition:
$a
}
上面示例规则告诉Yara匹配原字符串"This program cannot"经过Base64编码后的目标字符串,且由于Yara的转换机制会将原串转换成三个目标串,下面是"This program cannot"转换后的三个目标串:
- VGhpcyBwcm9ncmFtIGNhbm5vd
- RoaXMgcHJvZ3JhbSBjYW5ub3
- UaGlzIHByb2dyYW0gY2Fubm90
根据Base64编码规则,原字符串"This program cannot"编码后的结果为"VGhpcyBwcm9ncmFtIGNhbm5vdA=="。由于Base64编码原理是三个字节编码成四个字节,因此如果说原字符串不能被三个字节正好分配的话,不满三个字节的字符转换后结果需要使用字符"="填充。而实际匹配过程中,原字符串很大概率是嵌入文本之中,因此Yara全面考虑到原串可能受前面和后面字符的影响。
影响字符在后面:
"This program cannot" Base64编码后为 "VGhpcyBwcm9ncmFtIGNhbm5vdA=="
由于实际匹配过程中后面很有可能因为其它字符填充到原串导致生成其它结果,示例如下:
"This program cannott" Base64编码后为 "VGhpcyBwcm9ncmFtIGNhbm5vdHQ="
"This program cannotte" Base64编码后为 "VGhpcyBwcm9ncmFtIGNhbm5vdHRl"
"This program cannottes" Base64编码后为 "VGhpcyBwcm9ncmFtIGNhbm5vdHRlcw=="
综上,为了去除原串后面字符对其转换后结果的影响,Yara将"VGhpcyBwcm9ncmFtIGNhbm5vd"作为原串的匹配目标。
影响字符在前面:
"tThis program cannot" Base64编码后为 "dFRoaXMgcHJvZ3JhbSBjYW5ub3Q="
"teThis program cannot" Base64编码后为 "dGVUaGlzIHByb2dyYW0gY2Fubm90"
"tesThis program cannot" Base64编码后为 "dGVzVGhpcyBwcm9ncmFtIGNhbm5vdA=="
"testThis program cannot" Base64编码后为 "dGVzdFRoaXMgcHJvZ3JhbSBjYW5ub3Q="
综上,为了去除原串前面字符对其转换后结果的影响,Yara将"RoaXMgcHJvZ3JhbSBjYW5ub3"和"UaGlzIHByb2dyYW0gY2Fubm90"作为原串的匹配目标。
综上为了去除匹配时,文本中其它内容对原串"This program canno"前后填充字符导致的影响,Yara直接匹配三个不同的Base64转换结果去除了前后字符对匹配准确度的影响。
关键字"base64wide"的作用是先将原字符串使用base64算法编码生成中间串,然后将中间串遵循wide字符格式填充"\x00"。
除此之外,Yara还支持自定义的base64索引表,示例如下:
rule Base64Example
{
strings:
// 其中()中内容为自定义Base64转化索引表。需要注意的是,字母表长度必须为64字节。
$a = "This program cannot" base64("!@#$%^&*(){}[].,|ABCDEFGHIJ\x09LMNOPQRSTUVWXYZabcdefghijklmnopqrstu")
condition:
$a
}
注意:"base64"和"base64wide"关键字只支持文本字符串(Text Strings),不支持十六进制字符串(Hex Strings)和正则表达式,否则会编译报错。除此之外,也不能和"xor"、"fullword"和"nocase"关键字一齐使用。
1.5 完整单词匹配(Searching for full words)
关键字"fullword"要求匹配目标单词时,前后不能相邻字符或者数字,但是可以相邻一下除字符、数字外的符号,示例如下:
rule FullWordExample
{
strings:
// 下面规则能命中"www.my-domain.com"或者"www.domain.com"等,但是"www.mydomain.com"不能命中。
$a = "domain" fullword
condition:
$a
}