前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >yara匹配引擎进阶语法指南

yara匹配引擎进阶语法指南

作者头像
用户1879329
发布于 2023-02-27 07:34:19
发布于 2023-02-27 07:34:19
1.6K00
代码可运行
举报
文章被收录于专栏:安全的矛与盾安全的矛与盾
运行总次数:0
代码可运行

前言

具备检测相关经验的同学可能都对yara匹配引擎比较熟悉了,看雪论坛上也有非常详细的翻译文章 - 编写Yara规则检测恶意软件 本文主要对yara文档容易被忽略的部分进行了翻译和总结,并且给出一些进阶用法的例子,提高对yara匹配引擎语法的理解程度。

参考文档:** https://yara.readthedocs.io/en/v4.2.3/writingrules.html

匹配字符串

yara的匹配字符串可以使用一些修饰符,总结下来有如下部分:

关键词

支持的字符串类型

概括

限制

nocase

文本,正则表达式

忽略大小写

不能与xor、base64、 或base64wide一起使用

wide

文本,正则表达式

通过交错空 (0x00) 字符来模拟 UTF16

ascii

文本,正则表达式

匹配 ASCII 字符,仅在wide使用时才需要

xor

文本

匹配具有单字节键的 XOR 文本字符串

不能与nocase、base64、 或base64wide一起使用

base64

文本

base64 编码的字符串(分割成3条)

不能与nocase、xor、 或fullword一起使用

base64wide

文本

base64 编码的字符串(分割成3条),然后交错空字符,如 wide

不能与nocase、xor、 或fullword一起使用

fullword

文本,正则表达式

匹配前后没有字母数字挨着的字符(串)

不能与base64或一起使用base64wide一起使用

private

十六进制、文本、正则表达式

匹配不包含在输出中

base64修饰符

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rule Base64Example1
{
    strings:
        $a = "This program cannot" base64

    condition:
        $a
}

将至少会匹配如下三个字符串:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
VGhpcyBwcm9ncmFtIGNhbm5vd
RoaXMgcHJvZ3JhbSBjYW5ub3
UaGlzIHByb2dyYW0gY2Fubm90

看起来很奇怪,原因如下: base64是将三个字节变成四个字节,如果不能被整除,那就会涉及到补位,同样的字符串可能因为前缀的不一样导致编码结果不同,这个不一致的循环次数是3,看如下的编码结果就明白了。

三个结果对应这三个不同前缀。 详情请阅读文档:https://www.leeholmes.com/searching-for-content-in-base-64-strings/ 另外base64和base64wide修饰符支持自定义的字符码表,可以匹配一些被修改过的base64编码。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rule Base64Example2
{
    strings:
        $a = "This program cannot" base64("!@#$%^&*(){}[].,|ABCDEFGHIJ\x09LMNOPQRSTUVWXYZabcdefghijklmnopqrstu")

    condition:
        $a
}

XOR修饰符

xor 修饰符是将声明的字符串按照 [0x01 - 0xFF] 都进行单字节异或,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rule XorExample1
{
    strings:
        $xor_string = "This program cannot" xor

    condition:
        $xor_string
}

等价于:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rule XorExample2
{
    strings:
        $xor_string_00 = "This program cannot"
        $xor_string_01 = "Uihr!qsnfs`l!b`oonu"  // xor 0x1 
        $xor_string_02 = "Vjkq\"rpmepco\"acllmv" // xor 0x2 
        // Repeat for every single byte XOR
    condition:
        any of them
}

另外还支持参数,限定xor的范围:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rule XorExample5
{
    strings:
        $xor_string = "This program cannot" xor(0x01-0x3F)
    condition:
        $xor_string
}

匹配条件的语法

支持的运算符

所有运算符的优先级如下:

优先级

操作

描述

性质

1

[].

Array subscripting 数组下标Structure member access 结构成员访问

从左到右

2

–~

Unary minus 按位减Bitwise not 按位非

从右到左

3

***\%**

Multiplication 乘法Division 除法Remainder 取余

从左到右

4

+–

Addition 加法Subtraction 减法

从左到右

5

<<>>

Bitwise left shift 按位左移Bitwise right shift 按位右移

从左到右

6

&

Bitwise AND 按位与

从左到右

7

^

Bitwise XOR 按位异或

从左到右

8

|

Bitwise OR 按位或

从左到右

9

<<=>>=

Less than 小于Less than or equal to 小于等于Greater than 大于Greater than or equal to 大于等于

从左到右

10

==!=containsicontainsstartswithistartswithendswithiendswithmatches

Equal to 等于Not equal to 不等于String contains substring 包含Like contains but case-insensitive 包含不区分大小写String starts with substring 以开始字符串Like startswith but case-insensitive 以开始字符串不区分大小写String ends with substring 以结尾字符串Like endswith but case-insensitive 以结尾字符串区分大小写String matches regular expression 正则表达式

从左到右

11

not

Logical NOT 逻辑非

从右到左

12

and

Logical AND 逻辑与

从左到右

13

or

Logical OR 逻辑或

从左到右

字符串计数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rule CountExample
{
    strings:
        $a = "dummy1"
        $b = "dummy2"
    condition:
        #a == 6 and #b > 10
}

还能指定范围计数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#a in (filesize-500..filesize) == 2

字符串偏移或者虚拟地址

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rule AtExample
{
    strings:
        $a = "dummy1"
        $b = "dummy2"
    condition:
        $a at 100 and $b at 200
}

rule InExample
{
    strings:
        $a = "dummy1"
        $b = "dummy2"
    condition:
        $a in (0..100) and $b in (100..filesize)
}

取字符串第i次出现的偏移,注意只能用 == 运算符

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rule AtExample
{
    strings:
        $a = "dummy1"
        $b = "dummy2"
    condition:
        @a[3] == 100 
}

匹配长度

这个主要用于正则表达式,比如 /fo*/可以匹配字符串 ‘fo’, ‘foo’,’fooo’等,但是具体要选择哪一个呢?这里可以用!来去匹配长度:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rule MatchLength{
	strings:
    $a = /fo*/
	condition:
  	!a[1] == 4 // 匹配 fooo
}

访问指定位置的数据

使用以下函数从给定偏移量的文件中读取数据:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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>)
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>)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rule IsPE
{
    condition:
        // MZ signature at offset 0 and ...
        uint16(0) == 0x5A4D and
        // ... PE signature at offset stored in MZ header at 0x3C
        uint32(uint32(0x3C)) == 0x00004550
}

字符串集合

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2 of ($a,$b,$c)
all of them       // all strings in the rule
any of them       // any string in the rule
all of ($a*)      // all strings whose identifier starts by $a
any of ($a,$b,$c) // any of $a, $b or $c
1 of ($*)         // same that "any of them"
none of ($b*)     // zero of the set of strings that start with "$b"


all of ($a*) in (filesize-500..filesize)
any of ($a*, $b*) in (1000..2000)

for循环

对多个字符串使用相同的条件
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for expression of string_set : ( boolean_expression )

在集合string_set中,expression必须满足( boolean_expression )

例如:
for any of ($a,$b,$c) : ( $ at pe.entry_point )
布尔表达式中的 $ 符号不与任何特定字符串相关联,它将是 $a,然后是 $b,最后是 $c

其实这里可以发现any of 是一种简写:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
any of ($a,$b,$c)
等价于
for any of ($a,$b,$c) : ( $ )

在 expression 中也可以使用 @, # ,! 等运算符:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for all of them : ( # > 3 )
for all of ($a*) : ( @ > @b )
迭代字符串

可以使用以下语法访问给定字符串出现在文件或进程地址空间中的偏移量或虚拟地址:@a[i],其中 i 是一个索引,指示出现了你所指的字符串 $a 。(@a[1]、@a[2]、…)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rule Occurrences
{
    strings:
        $a = "dummy1"
        $b = "dummy2"
    condition:
        for all i in (1,2,3) : ( @a[i] + 10 == @b[i] )
}

以上条件也可以写成:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for all i in (1..3) : ( @a[i] + 10 == @b[i]

另一个规则:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for all i in (1..#a) : ( @a[i] < 100 )   //#a 代表 $a 出现的次数

还有可以限定满足条件的迭代次数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for 2 i in (1..#a) : ( @a[i] < 100 )
迭代器

在 YARA 4.0 中,for..of运算符得到了改进,现在它不仅可以用于迭代整数枚举和范围(例如:1,2,3,4 和 1..4),还可以用于任何类型的可迭代数据类型,例如YARA 模块定义的数组和字典。例如,以下表达式在 YARA 4.0 中有效:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for any section in pe.sections : ( section.name == ".text"// 等价于
for any i in (0..pe.number_of_sections-1) : ( pe.sections[i].name == ".text" )

在迭代字典时,您必须提供两个变量名,它们将保存字典中每个条目的键和值,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for any k,v in some_dict : ( k == "foo" and v == "bar" )

外部变量

外部变量允许您定义依赖于外部提供的值的规则。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rule ExternalVariableExample1
{
    condition:
        ext_var == 10
}

在这种情况下ext_var是一个外部变量,其值在运行时分配。外部变量可以是以下类型:整数、字符串或布尔值;它们的类型取决于分配给它们的值。整数变量可以替代条件中的任何整数常量,布尔变量可以占据布尔表达式的位置。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rule ExternalVariableExample2
{
    condition:
        bool_ext_var or filesize < int_ext_var
}

string类型的外部变量可以与以下运算符一起使用:contains、startswith、endswith及其不区分大小写的对应运算符:icontains、istartswith和iendswith`。它们还可以与“matches运算符一起使用,如果字符串与给定的正则表达式匹配,则返回true。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rule ContainsExample
{
    condition:
        string_ext_var contains "text"
}
rule CaseInsensitiveContainsExample
{
    condition:
        string_ext_var icontains "text"
}
rule StartsWithExample
{
    condition:
        string_ext_var startswith "prefix"
}
rule EndsWithExample
{
    condition:
        string_ext_var endswith "suffix"
}
rule MatchesExample
{
    condition:
        string_ext_var matches /[a-z]+/is
}

偏门模块

  1. Hash模块

https://yara.readthedocs.io/en/latest/modules/hash.html

  1. Math模块

https://yara.readthedocs.io/en/latest/modules/math.html

  1. Dotnet 模块

https://yara.readthedocs.io/en/latest/modules/dotnet.html

一些进阶用法

打分

利用yara的math模块进行打分

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
math.to_number(SubRule1) * 60 + math.to_number(SubRule2) * 20 + math.to_number(SubRule3) * 70 > 80

判断.text section的墒值在7.4与7.6之间

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
for any section in pe.sections : ( 
section.name == ".text" 
and  math.in_range(math.entropy(section.raw_data_offset,section.raw_data_size),7.4,7.6))

导入表有且仅有VirtualAllocCreateRemoteThread 以及 _WriteProcessMemory_

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pe.imports("kernel32.dll","VirtualAlloc") 
and 
pe.imports("kernel32.dll","CreateRemoteThread") 
and 
pe.imports("kernel32.dll","WriteProcessMemory") 
and 
pe.imports("kernel32.dll")  == 3

有某个图标,并且无签名(不够灵活,没法设定一个hash列表)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import "hash"
import "pe"

rule iconForge{

   condition:
    	for any res in pe.resources: (
          res.type == pe.RESOURCE_TYPE_ICON
            hash.md5( res.offset,res.length) == "xxxxx"
            ) 
        and 
            pe.number_of_signatures == 0
}

匹配PDB路径

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pe.pdb_path icontains "shellcode" or pe.pdb icontains "qianxin"

匹配特征在具体的节区

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import "pe"
import "console"

rule test{

    strings:
        $a = {55 8B EC F6 45 08 01 56 8B F1 C7 06 94 1F 43 00}

    condition:
        $a in (
            pe.sections[ pe.section_index(".text") ].raw_data_offset..pe.sections[ pe.section_index(".text") ].raw_data_offset+pe.sections[ pe.section_index(".text") ].raw_data_size
        )
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-02-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
linux的nohup命令的用法
在应用Unix/Linux时,我们一般想让某个程序在后台运行,于是我们将常会用 & 在程序结尾来让程序自动运行。比如我们要运行mysql在后台: /usr/local/mysql/bin/mysqld_safe –user=mysql &。可是有很多程序并不想mysqld一样,这样我们就需要nohup命令,怎样使用nohup命令呢?这里讲解nohup命令的一些用法。
周小董
2019/03/25
3.8K0
linux的nohup命令
在应用Unix/Linux时,我们一般想让某个程序在后台运行,于是我们将常会用 & 在程序结尾来让程序自动运行。比如我们要运行mysql在后台: /usr/local/mysql/bin/mysqld_safe –user=mysql &。可是有很多程序并不想mysqld一样,这样我们就需要nohup命令,怎样使用nohup命令呢?这里讲解nohup命令的一些用法。
全栈程序员站长
2022/11/15
1.7K0
Linux:Nohup命令详解
在上面的例子中,0 – stdin (standard input),1 – stdout (standard output),2 – stderr (standard error) ;
新码农
2020/12/21
14.6K0
Linux:Nohup命令详解
nohup 详解
nohup 详解
Java架构师必看
2021/09/08
4340
linux 后台运行进程:& , nohup
当我们在终端或控制台工作时,可能不希望由于运行一个作业而占住了屏幕,因为可能还有更重要的事情要做,比如阅读电子邮件。对于密集访问磁盘的进程,我们更希望它能够在每天的非负荷高峰时间段运行(例如凌晨)。为了使这些进程能够在后台运行,也就是说不在终端屏幕上运行,有几种选择方法可供使用。
DevOps在路上
2023/05/16
5K0
linux 后台运行进程:& , nohup
[Linux笔记] nohup 命令 解决 SSH关闭窗口,程序也中断的问题!
nohup 英文全称 no hang up(不挂起),用于在系统后台不挂断地运行命令,退出终端不会影响程序的运行。
科控物联
2022/04/19
6.5K0
[Linux笔记] nohup 命令 解决 SSH关闭窗口,程序也中断的问题!
linux常用命令_screen和nohup管理远程会话
线上服务器往往没有安装系统桌面,在进行耗时时间长的操作过程中,有时中途不得不离开,回来之后,因为网络断开,往往操作没有完成。欲哭无泪,不得不重新开始,自从学会了下面两个命令,再也不担心操作被某些原因中断啦。
IT不难
2022/03/11
8910
linux常用命令_screen和nohup管理远程会话
详解nohup和& 区别 原
不挂断地运行命令。no hangup的缩写,意即“不挂断”。一般理解&记住一个命令最简单的方法是记住它是什么缩写,就自然理解了这个命令。 nohup运行由 Command参数和任何相关的 Arg参数指定的命令,忽略所有挂断(SIGHUP)信号;
拓荒者
2019/03/11
2.4K0
Linux nohup和&的使用说明,"2>1&"含义解释
Linux中nohup和&配合使用说明,以及使用时2>1& 的解释,还有Linux进程查询等命令
俺也想起舞
2019/07/24
13.3K0
nohup和&后台运行,进程查看及终止 原
  无论是否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out 文件中。
拓荒者
2019/03/11
2.9K0
nohup和&后台运行,进程查看及终止
                                                                            原
Linux||后台运行及查看状态命令
在使用Linux运行程序的时候,常常遇到需要耗费一定时间才能完成的文件,如果在前台运行,此时坐在电脑前的你只能被迫打开其他软件进行摸鱼。
小汪Waud
2023/02/16
7.8K0
Linux||后台运行及查看状态命令
让linux程序在后台运行
最近要用php进程发奖励,因为要精确到秒执行,linux系统的定时用不了,于是写了个死循环,usleep是必须的,否则系统cpu占用很高的系统cpu。
用户3094376
2018/09/12
5.2K0
&和nohup
当我们在终端或控制台工作时,可能不希望由于运行一个作业而占住了屏幕,因为可能还有更重要的事情要做,比如阅读电子邮件。对于密集访问磁盘的进程,我们更希望它能够在每天的非负荷高峰时间段运行(例如凌晨)。为了使这些进程能够在后台运行,也就是说不在终端屏幕上运行,有几种选择方法可供使用。
陈不成i
2021/05/27
7490
利用nohup后台运行jar文件包程序
java -jar XXX.jar 特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出
Java架构师历程
2019/09/29
3.3K0
关于 Linux后台运行进程
最近在搭建kafka的过程中,发现启动相关服务后,终端界面无法再进行操作。每次都需要开启多个终端界面,实在是特别麻烦。于是就研究了下Linux后台启动程序的方法,并整理了如下的笔记。
用户8710643
2021/06/11
2.4K0
Linux命令之nohup
语法:nohup Command [ Arg ... ] [ & ] 描述:nohup 命令运行由 Command 参数和任何相关的 Arg 参数指定的命令,忽略所有挂断(SIGHUP)信号。在注销后使用 nohup 命令运行后台中的程序。要运行后台中的 nohup 命令,添加 & ( 表示“and”的符号)到命令的尾部。
AsiaYe
2019/11/06
2.4K0
Linux 运行jar包命令[通俗易懂]
特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出
全栈程序员站长
2022/11/15
7.1K0
Springboot项目使用java -jar 启动jar包参数详解
nohup java -Xms500m -Xmx500m -Xmn250m -Xss256k -server -XX:+HeapDumpOnOutOfMemoryError -jar $JAR_PATH/test-0.0.1-SNAPSHOT.jar --spring.profiles.active=daily -verbose:class &
IT工作者
2022/05/17
5.8K0
015 Linux 标准输入输出、重定向、管道和后台启动进程命令
IO 重定向是为了改变默认输入、输出的位置,如默认情况下标准输出(STDOUT),标准错误输出(STDERR)都是输出到显示终端,如对标准输出、标准错误输出改变其默认输出位置,可重定向输出到指定的文件中(实际工作中经常这么使用),要重定向就要配合一些语法符号。
落寞的鱼丶
2022/02/21
2.1K0
相关推荐
linux的nohup命令的用法
更多 >
LV.4
这个人很懒,什么都没有留下~
目录
  • 前言
  • 匹配字符串
    • base64修饰符
    • XOR修饰符
  • 匹配条件的语法
    • 支持的运算符
    • 字符串计数
    • 字符串偏移或者虚拟地址
    • 匹配长度
    • 访问指定位置的数据
    • 字符串集合
    • for循环
      • 对多个字符串使用相同的条件
      • 迭代字符串
      • 迭代器
    • 外部变量
  • 偏门模块
  • 一些进阶用法
    • 打分
    • 判断.text section的墒值在7.4与7.6之间
    • 导入表有且仅有VirtualAlloc 和 CreateRemoteThread 以及 _WriteProcessMemory_
    • 有某个图标,并且无签名(不够灵活,没法设定一个hash列表)
    • 匹配PDB路径
    • 匹配特征在具体的节区
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档