【逆向】Yara規則編寫安裝與使用教程


前言

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 59 F7 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

 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個字符。以下關鍵字是保留的,不能用作標識:

注釋

你可以像編寫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

正則表達式:定義可讀文本的部分

條件表達式

你可以在條件表達中使用如下運算符:

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) == 0x5A4D and
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         2 of ($a,$b,$c)
12 }
View Code

for xxx of xxx :(xxx)

 1 //功能:
 2 對多個字符串匹配相同的條件
 3 //格式:
 4 for AAA of BBB : ( CCC )
 5 //含義:
 6 在BBB字符串集合中,至少有AAA個字符串,滿足了CCC的條件表達式,才算匹配成功。
 7 在CCC條件表達式中,可以使用'$'依次代替BBB字符串集合中的每一個字符串。
 8 
 9 //for..of其實就是of的特別版,所以下面2個例子作用相同
10 any of ($a,$b,$c)
11 for any of ($a,$b,$c) : ( $ )
12 
13 //在abc3個字符串集合中,至少有1個字符串,必須滿足字符串內容與entrypoint相同的條件
14 for 1 of ($a,$b,$c) : ( $ at entrypoint  )
15 for any 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 global rule SizeLimit
4 {
5     condition:
6         filesize < 2MB
7 }
View Code

私有規則

1 //私有規則(private rule)可以避免規則匹配結果的混亂,
2 //比如使用私有規則進行匹配時,YARA不會輸出任何匹配到的私有規則信息
3 //私有規則單獨使用意義不大,一般可以配合"引用其它規則"的功能一起使用
4 //私有規則也可以和全局規則一起使用,只要添加“Private”、“global”關鍵字即可
5 private rule 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM