Yara规则
YARA(Yet Another Recursive Acronym)是一种用于识别和分类恶意软件的工具。它是恶意软件研究和反病毒领域的重要工具。YARA规则是一种描述文件或内容特征的文本格式,用于检测和识别文件中的特定模式或特征。
一个Yara规则由三部分组成,规则名称和元数据、字符串部分以及条件部分。
规则名称和元数据:
- 每个YARA规则都有一个唯一的名称。
- 元数据部分包含作者、规则描述、日期等信息,通常用来记录规则的背景和用途。
字符串部分:
- 定义需要匹配的字符串,可以是文本字符串、十六进制字符串或正则表达式。
- 支持各种字符串修饰符,如nocase(忽略大小写)、wide(宽字符)和ascii(ASCII字符)。
条件部分:
- 指定匹配条件,定义字符串或模式出现的条件。
- 支持布尔逻辑、位置匹配和计数等条件。
示例:
rule MaliciousFile
{
meta:
author = "Jane Doe"
description = "Detects files containing the malicious string"
date = "2024-07-29"
strings:
$malicious_string = "malicious"
$malicious_hex = { 6D 61 6C 69 63 69 6F 75 73 }
$malicious_regex = /malicious/i
condition:
$malicious_string or $malicious_hex or $malicious_regex
}
安装
Github:https://github.com/virustotal/yara
Yara规则编写
YARA 中的每条规则都以关键字开头rule
,后跟规则标识符。标识符必须遵循与 C 编程语言相同的词汇约定,它们可以包含任何字母数字字符和下划线字符,但第一个字符不能是数字。规则标识符区分大小写,并且不能超过 128 个字符。以下关键字是保留的,不能用作标识符:
规则主要由俩部分构成,字符串部分和条件部分。字符串可以省略,但条件部分是必需。每个字符串都有一个标识符,该标识符由 $ 字符后跟一串字母数字字符和下划线组成,这些标识符可用于条件部分以引用相应的字符串。字符串可以以文本或十六进制形式定义,如下例所示:
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
}
文本字符串像 C 语言一样用双引号括起来。十六进制字符串用花括号括起来,由一串十六进制数字组成,这些数字可以连续出现,也可以用空格分隔。十六进制字符串中不允许使用十进制数字。
条件部分必须包含一个布尔表达式,说明在何种情况下文件或进程满足规则或不满足规则。
注释
在Yara规则中添加注释跟C语言一样,分为单行注释和多行注释:
rule ExampleRule
{
strings:
$text_string = "malicious" /* 这个字符串用于检测示例文本,
包含恶意软件特征的字符串 */
condition:
$text_string or $hex_string or $regex_string // 条件:任意一个字符串匹配
}
字符串
Yara规则中的字符串可以是十六进制字符串、文本字符串或正则表达式字符串。
十六进制字符串
十六进制字符串用于匹配文件中的字节模式,可以包含通配符和跳转。
rule HexStringExample
{
strings:
$a = { 6D 61 6C 69 63 69 6F 75 73 } // 直接匹配字节模式
$b = { 6D 61 6C ?? 63 69 6F 75 73 } // 带有通配符的字节模式
$c = { 6D 61 [1-3] 69 6F 75 73 } // 带有跳转的字节模式
condition:
$a or $b or $c
}
文本字符串
文本字符串用于匹配文件中的普通文本。可以指定单个字符串或一组字符串,还可以使用修饰符来调整匹配行为。
rule TextStringExample
{
strings:
$a = "malicious" // 普通文本字符串
$b = "example" nocase // 忽略大小写
$c = "foobar" wide // 宽字符 (UTF-16)
$d = "baz" ascii // ASCII 字符串
condition:
$a or $b or $c or $d
}
正则表达式字符串
rule RegexStringExample
{
strings:
$a = /malicious/ // 匹配 'malicious'
$b = /example/i // 匹配 'example',忽略大小写
$c = /foo(bar|baz)/ // 匹配 'foobar' 或 'foobaz'
$d = /ba[rz]/ nocase ascii wide // 匹配 'bar' 或 'baz',忽略大小写,支持 ASCII 和宽字符
condition:
$a or $b or $c or $d
}
条件
条件不过是布尔表达式,类似于所有编程语言中可以在 if 语句中找到的那些表达式。它们可以包含典型的布尔运算符 and、or 和 not,以及关系运算符 >=、<=、<、>、== 和 !=。另外,算术运算符(+、-、*、\、%)和按位运算符(&、|、<<、>>、~、^)也可以在数值表达式中使用。
优先级
Yara运算符优先级从高到低:() ~ * / % + - << >> < <= > >= == != & ^ | and or not
计算字符串
有时我们不仅需要知道某个字符串是否存在,还需要知道该字符串在文件或进程内存中出现了多少次。每个字符串出现的次数由一个变量表示,该变量的名称是字符串标识符,但用 # 字符代替 $ 字符。例如:
rule CountExample
{
strings:
$a = "dummy1"
$b = "dummy2"
condition:
#a == 6 and #b > 10
}
此规则匹配包含字符串 $a 六次且包含字符串 $b 十次以上的任何文件或进程。
从 YARA 4.2.0 开始,可以用整数范围来表示字符串的计数,如下所示:
#a in (filesize-500..filesize) == 2
在此示例中,文件最后 500 个字节中的“a”字符串的数量必须正好等于 2。
字符串偏移量或虚拟地址
当我们想知道字符串是否位于文件中的某个特定偏移量或进程地址空间中的某个虚拟地址,可以使用at
运算符:
rule AtExample
{
strings:
$a = "dummy1"
$b = "dummy2"
condition:
$a at 100 and $b at 200
}
仅当字符串 $a 位于文件内的偏移量 100 处(或如果应用于正在运行的进程,则位于虚拟地址 100 处)时,上述示例中的表达式才为真。字符串 $b 应出现在偏移量 200 处。
也可以使用in
运算符,该运算符允许在偏移量或地址范围内搜索字符串。
rule InExample
{
strings:
$a = "dummy1"
$b = "dummy2"
condition:
$a in (0..100) and $b in (100..filesize)
}
在上面的例子中,字符串 $a 必须位于偏移量 0 到 100 之间,而字符串 $b 必须位于偏移量 100 到文件末尾之间。
特殊变量
字符串标识符可以出现在条件中充当变量,filesize
也可以,该变量用于保存被扫描文件的大小,大小以字节表示。
rule FileSizeExample
{
condition:
filesize > 200KB
}
RedLine Yara规则编写
Yara规则:
rule RedLine
{
meta:
date = "2024-07-29"
comment = "RedLine Yara"
strings:
$mz = {4D 5A}
$RedLine_Name = "Happy.exe"
$GetLoaction_URL = {61 00 70 00 69 00 2E 00 69 00 70 00 2E 00 73 00 62 00}
$GetLoactionIP_URL = {6100700069002E00690070006900660079002E006F00720067}
$InformationIP_URL = {6900700069006E0066006F002E0069006F}
$C2_URL = {73006900790061007400650072006D0069002E006400750063006B0064006E0073002E006F00720067003A00310037003000340034}
$Create_Directory = {590061006E006400650078005C00590061004100640064006F006E}
condition:
$mz at 0 and
and
(
$RedLine_Name or
$GetLoaction_URL and
$GetLoactionIP_URL and
$InformationIP_URL or
$C2_URL and
$Create_Directory
)
}
解析
首先是个PE文件,加个MZ头部。
文件名,Happy.exe:
RedLine访问了一个Url用于获取ip地址,如下:
用于字符串部分的三个变量。
C2: