当前位置: 首页 > 工具软件 > YARA > 使用案例 >

yara规则

凌声
2023-12-01

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

本篇参照官网规则,将yara语法总结如本文部分


一、字符串规则

1.字符串之16进制字符串,用于定义原始字节序列

//通配符:可以用来代替某些未知的字节,并与人和内容匹配

rule WildcardExample
{
	strings:
	    //使用'?'作为通配符,一个?代表一位
	    $hex_string = { 00 11 ?? 33 4? 55}

	condition:
	    $hex_string
}

//跳转:可以匹配长度可以变化的字符串
rule JumpExample
{
	strings:
	    //使用'[]'作为跳转,与任何长度为0~n字节的内容匹配
	    $hex_string1 = { 00 11 [n] 44 55 }
	    $hex_string2 = { 00 11 [0-n] 44 55 }
	    //实例,string3和string4完全相同
	    $hex_string3 = { 00 11 [0-2] 44 55 }
        $hex_string4 = { 00 11 ?? ?? 44 55 }

    condition:
        $hex_string1 or $hex_string2
}

//也可以使用类似正则表达式的方法
rule AlternativeExample
{
	strings:
	      $hex_string = { 00 11 ( 22 | 33 44 ) 55 }
	      /*
	      该表达式可以匹配一下内容:
	      00 11 22 55
	   或 00 11 33 44 55
	      */

	condition:
	      ¥hex_string
}

//方法整合
rule AlternativeExample2
{
	string2:
	    $hex_string = { 00 11 ( 33 44 | 55 | 66 ?? 88 ) 99 }

	condition:
	    &hex_string
}

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

/*
    转义符号:
    \"   //双引号
    \\   //反斜杠
    \t   //制表符
    \n   //换行符
    \xdd //十六进制的任何字节

    修饰符:
    nocase:   不区分大小写
    wide:    匹配2字节的宽字符
    ascii:   匹配1字节的ascii字符
    xor:     匹配异或后的字符串
    fullword:匹配完整单词
    private: 定义私有字符串 
*/
rule CaseInsensitiveTextExample
{
	strings:
	     $text_string = "foobar" nocase //不区分大小写
	     $wide_string = "Borland" wide  //匹配宽字符
	     $wide_and_ascii_string = "Borland" wide ascii  //同时匹配2种类型的字符串
	     $xor_string = "This program cannot" xor  //匹配所有可能的异或后的字符串
         $xor_wide_ascii_string = "This program canot" xor wide ascii  //匹配所有可能异或后的wide ascii字符串
         $xor_egde_string = "This program cannot" xor(0x01-oxff)  //限定异或的范围
         $full_string = "domain" fullword  //全词匹配(匹配:www.domain.com 匹配:www.my-domain 不匹配:www.mydomain.com)
         $private_string = "foobar" private  //私有字符串可以正常匹配规则,但似乎永远不会在输出中显示

    condition:
         $text_string
}

二、条件表达式

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

//"#"标识符:用于匹配字符串在文件或内存中出现的次数
rule CountExample
{
	strings:
	   $a = "dummy1"
	   $b = "dummy2"

	condition:
	   //a字符串出现6次,b字符串出现10次
	   #a == 6 and #b > 10
}

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

/*
   "!"标识符:
   可以使用!a[i],获取字符串$a在文件或者内存中,第i次出现时的字符串长度
   下标同@一样从1开始
   !a是!a[1]的简写
*/

//"at"标识符:用于匹配字符串在文件或者内存中的偏移
rule AtExample
{
	strings:
	    $a = "dummy1"
	    $b = "dummy2"

	condition:
	    //a和b字符串分别出现在文件或者内存的100和200偏移处
	    $a at 100 and $b at 200
}

//"in"标识符:用于在文件或者内存的某个地址范围内匹配字符串
rule InExample
{
	strings:
	     $a = "dummy1"
	     $b = "dummy1"

	condition:
	     $a in (0..100) and $b in (100..filesize)
}

//"filesize"关键字:用于匹配文件大小
rule FileSizeExample
{
	condition:
         //filesize只能在文件时才有用,对进程无效
         //KB MB后缀只能与十进制大小一起使用
	     filesize > 200KB
}

//"entrypoint":用于匹配PE或ELF文件的入口点(高版本使用PE模块的pe.entry_point代替)
rule EntryPointExample1
{
	strings:
	     $a = { E8 00 00 00 00 }

	condition:
	     $a at entrypoint
}

rule EntryPointExample2
{
	strings:
	     $a = { 9c 50 66 A1 ?? ?? ?? 00 66 A9 ?? ?? 58 0F 85 }
	 condition:
         $a in (entrypoint..entrypoint + 10)
}

//"intxxx uintxxx":从指定的文件或内存偏移处读取数据
//小端:有符号整数
int8(<offset or virtual address>)
int16(<offset or virtual address>)
int32(<offset or virtual address>)
//小端:无符号整数
uint8(<offset or virtual address>)
uint16(<offset or virtual address>)
uint32(<offset or virtual address>)

//"intxxxbe uintxxxbe":从指定的文件或内存偏移处读取数据
//大端:有符号整数
int8be(<offset or virtual address>)
int16be(<offset or virtual address>)
int32be(<offset or virtual address>)
//大端:无符号整数
uint8be(<offset or virtual address>)
uint16be(<offset or virtual address>)
uint32be(<offset or virtual address>)
//应用实例
rule IsPE
{
	condition:
	     //判断是否是PE文件
	     uint16(0) == 0x5A4D and uint32(uint(0x3C)) == 0x00004550
}

//"of"关键词:用于匹配多个字符串中的某几个
rule OfExample1
{
	strings:
	     $a = "dummy1"
	     $b = "dummy2"
	     $c = "dummy3"

	conditon:
	     2 of ($a,$b,$c)//三个字符串只需匹配任意两个
}

//"for xxx of xxx:(xxx)"
/* 
   功能:对多个字符串匹配相同的规则
   格式: for AAA of BBB : ( CCC )
   含义:在BBB字符串集合中,至少有AAA个字符串,满足了CCC的条件表达式,才算匹配成功。在CCC条件表达式中,可以使用$一次代替BBB字符串集合中的每一个字符串。
   
   for ... of其实就是of的特别版,所以下面两个例子的作用相同
   any of ($a,$b,$c)
   for any of ($a,$b,$c) : ( $ )

   所有字符串,在文件或内存中出现的次数必须大于3,才算匹配成功
   for all of them : ( # > 3 )

   所有以$a开头的字符串,在文件或内存中第二次出现的位置必须小于9
   for all of ($a*) : (@[2] < 0x9)
*/

//"for xxx i in (xxx) : (xxx)"
/*
   格式:for AAA BBB in (CCC):(DDD)
   含义:作用与for of相似,只是增加了下标变量和下表范围,具体看实例

   $b在文件或内存中出现的前3次偏移,必须与$a在文件或者内存中出现的前3次偏移+10相同
   for all i in (1,2,3) : (@a[i] + 10 == @b[i])
   for all i in (1..3)  : (@a[i] + 10 == @b[i])

   $a每次在文件或内存中出现的位置,都必须小于100
   for all i in (1..#a) : ( @a[i] < 100 )

   其他
   for any i in (1..#a) : ( @a[i] < 100 )
   for 2 i in (1..#a) : ( @a[i] < 100 )
*/

//引用其他规则
rule Rule1
{
	strings:
	     $a = "dummy1"

	condition:
	     $a
}

rule Rule2
{
	strings:
	     $a = "dummy2"

	condition:
	     $a and Rule1
}

//全局规划(global rule)可以在匹配其他规则前优先筛选,比如在匹配目标文件前优先筛选出小于2MB的文件,再匹配其他规则
global rule SizeLimit
{
	condition:
	     filesize < 2MB
}

//私有规则(private rule)可以避免规则匹配的结果混乱,比如使用私有规则进行匹配时,YARA不会输出任何匹配到私有规则信息
//私有规则单独使用的意义不大,一般需要配合"引用其他规则"的功能一起使用
//私有规则也可以和全局规划一起使用,只需要添加"private"、"global"关键字即可
private rule PrivateRuleExample
{
	...
}

//规则标签:可以在YARA输出时仅展示你敢兴趣的规则,而过滤掉其他规则的输出信息,可以为规则添加多个标签
rule TagExample1: Foo Bar Baz
{
	...
}

rule TagExample2: Bar
{
	...
}

//导入模块:使用"import"导入模块,可以自己编写模块,也可以使用官方或者其他的第三方模块。在导入模块后,就可以开始使用模块导出的变量和函数,例如:
import "pe"
import "cuckoo"
pe.entry_point == 0x1000
cuckoo.http_request(/someregexp/)

//外部变量:允许你在使用YARA -d命令时指定一个自定义数据,该数据可以是整数、字符串、布尔变量、具体如下:

//使用布尔变量和一个整数变量作为判断条件
rule ExternalVariableExample2
{
	condition:
	     bool_ext_var or filesize < int_ext_var
}

//字符串变量可以与以下运算符一起使用:
//contains:如果字符串包含指定的字符串,返回True
//matches:如果字符串匹配给定的正则表达式时,返回Ture

rule ExternalVariableExample3
{
	condition:
	     string_ext_var1 contains "text" and
         steing_ext_var2 marches /[a-z]+/
}

//文件包含:作用于C语言一样,可以包含其他规则到当前文件中
include "other.yar"

//相对路径
include "./includes/other.yar"
include ",./includes/other.yar"

//全路径
include "/home/plusvic/yara/includes/other.yar"

 类似资料: