【51CTO.com快译】本文介绍如何编写YARA规则以充分利用它。
使用空模板开始入手
YARA规则是文本文件,遵循基本但强大的语法。
YARA规则包含三部分:
- 元部分:这部分包含未处理但帮助用户了解内容的一般或特定的信息。
- 字符串部分:这部分包含需要在文件中搜索的所有字符串。
- 条件部分:这部分定义匹配的条件。它可以只匹配一个或多个字符串,但也可以较复杂,我们会在文章后面看到。
我强烈建议创建一个空模板,您将始终用它来开始编写新规则。这样,您只需填充几个可变内容,添加所需的条件。
- rule samplerule
- {
- meta:
- author="Cedric Pernet"
- version="0.1"
- date="2021/05/12"
- reference="any useful reference"
- strings:
- condition:
- }
使用该模板,您可以快速编辑元数据和规则名称(本例中名为samplerule)。元数据可以是用户想要放在那里的任何东西。我总是使用版本号、日期、可能是恶意软件哈希的引用或提及我想要检测的内容的博客报告以及作者字段。
现在元数据已写好,不妨开始编写第一个规则。
第一个规则
YARA规则结合了字符串元素和条件。字符串可以是文本字符串、十六进制字符串或正则表达式。
条件是布尔表达式,就像在其他编程语言中一样。最有名的条件是AND、OR和NOT。 也可以使用关系、算术和按位运算符。
这是第一个规则:
- rule netcat_detection
- {
- meta:
- author="Cedric Pernet"
- version="0.1"
- date="2021/05/12"
- reference="netcat is a free tool available freely online"
- strings:
- $str1="gethostpoop fuxored" // this is very specific to the netcat tool
- $str2="nc -l -p port [options]"
- condition:
- $str1 or $str2
- }
不妨解释这个名为netcat_detection的规则。
在我们通常的元数据之后,字符串部分包含两个变量:str1和str2,当然可以按我们的喜好来命名。此外为了说明如何添加注释,第一个变量在末尾含有一个注释。
条件部分包含以下条件:必须匹配str1或str2。
这可以用更舒适的方式来编写:
- condition:
- any of ($str*)
如果我们有很多不同的变量,只想匹配其中任何一个,这很有用。
运行第一个规则
现在不妨运行规则,我们将其保存为名为rule1.yar的文件。我们想针对包含多个不同文件的文件夹运行它,其中两个是netcat软件的32位和64位版本(图A)。我们用于测试的系统是Ubuntu Linux发行版,但这没关系,因为Yara可以轻松安装在Linux、Mac或Windows操作系统上。
图A. 在文件夹上运行YARA规则以检测特定软件
不出所料,YARA运行并返回匹配规则的所有文件的名称。
当然,您可以将任意数量的YARA规则放在一个文件中,这比拥有许多不同的规则文件更方便。
使用-s选项运行YARA可显示与这些文件匹配的确切字符串(图 B):
图B. 使用-s选项运行YARA以显示匹配的字符串
附带说明一下,在公司网络中的某个地方找到像netcat这样的工具确实值得研究:普通用户计算机上应该找不到这个基本工具,因为它允许计算机在特定端口上连接和交换数据,可能被攻击者所使用。当然,它也可能被IT人员或红队人员使用,因此调查一番,以确定为什么在公司网络的机器上发现它。
较复杂的字符串
匹配基本字符串足以在系统中查找文件。然而,字符串在不同系统上的编码方式可能不同,或者可能被攻击者轻微触发。比如说,一个细微的变化可以改变使用随机大小写的字符串的大小写。幸运的是,YARA可以轻松处理这个问题。
在下面的YARA字符串部分,字符串无论使用什么大小写都会匹配:
- strings:
- $str1="thisisit" nocase
条件$str1现在与使用的任何大小写匹配:"ThisIsIt"、"THISISIT"、"thisisit"和"ThIsIsiT"等。
如果字符串使用每个字符两个字节来编码,可以使用“wide”修改符,当然可以彼此结合。
- strings:
- $str1="thisisit" nocase wide
想搜索ASCII和宽格式的字符串,修改符“ascii”可与wide结合使用。
- strings:
- $str1="thisisit" ascii wide
十六进制字符串
十六进制字符串可轻松使用:
- strings:
- $str1={ 75 72 65 6C 6E 20 }
- $str2={ 75 72 65 6C ?? 20 }
- $str3={ 75 72 [2-4] 65 6C }
这是三个不同的十六进制变量。第一个搜索十六进制字符串上的精确序列。第二个使用两个?字符表示的通配符,将搜索任何十六进制值的带有??的字符串。
第三个字符串搜索前两个字节,然后跳过两到四个字符,最后是最后两个字节。某些序列在不同文件中不一样、但在两个已知序列之间显示可预测数量的随机字节时,这非常方便。
正则表达式
就像在任何编程语言中一样,正则表达式对于检测可以用不同方式编写的特定内容非常有用。在YARA中,它们通过使用以斜杠(/) 字符开头和结尾的字符串来定义。
不妨举一个有意义的例子。
在恶意软件二进制文件中,开发人员留下了调试信息,尤其是著名的PDB字符串。
内容如下:
- D:\workspace\Malware_v42\Release\malw.pdb
现在的想法是不仅要创建一个与该恶意软件匹配的规则,还要创建它的所有不同版本,以防版本号发生变化。此外,我们决定从规则中排除“D”驱动器,因为开发人员也可能将它放在另一个驱动器上。
我们给出了正则表达式(图C):
图C. 根据其PDB字符串和结果,匹配恶意软所有版本的规则
出于演示目的,我们构建了一个名为newmalwareversion.exe的文件,包含三个不同的PDB字符串,每个字符串都有不同的版本号。我们的规则与它们全部匹配。
请注意,我们字符串中的\字符已加倍,因为\是需要转义的特殊字符,就像在C语言中一样。
较复杂的条件
条件可能比仅匹配单个或多个字符串来得更智能。您可以使用条件来计算字符串、指定要查找字符串的偏移量、匹配文件大小甚至使用循环。
以下是我加注释以解释的几个示例:
- condition:
- 2 of ($str*) // will match on 2 of several strings named str followed by a number
- ($str1 or $str2) and ($text1 or $text2) // example of Boolean operators
- #a == 4 and #b > 6 // string a needs to be found exactly four times and string b needs to be found strictly more than six times
- $str at 100 // string str needs to be located within the file at offset 100
- $str in (500..filesize) // string str needs to be located between offset 500 and end of file.
- filesize > 500KB // Only files which are more than 500KB big will be considered
原文标题:How to write YARA rules for improving your security and malware detection,作者:Cedric Pernet
【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】