适用场景
YARA 规则是安全团队检测恶意软件与攻击痕迹的行业标准工具,适用于以下场景:威胁情报团队基于已确认的恶意样本提取特征并批量检测同类变种;蓝队运维人员对服务器目录、邮件附件、用户上传文件做恶意软件巡检;应急响应人员对失陷主机进行 IOC(入侵指标)匹配,快速确认主机是否感染已知家族。本教程面向已经掌握 Linux 基础命令、具备一定安全分析经验的技术人员,帮助你从零编写可用的 YARA 规则。
前置条件
- Linux 服务器(CentOS 7+ / Ubuntu 20.04+),具备 root 权限
- 已安装 yara 命令行工具与 yara-python(如需 Python 集成)
- 准备若干恶意样本(建议在隔离的病毒分析虚拟机中操作)或公开样本库样本
- 了解正则表达式与十六进制字节的基本概念
安装 YARA:
# Ubuntu / Debian
apt install yara
# CentOS / RHEL(EPEL 源)
yum install epel-release
yum install yara
# 源码安装(获取最新版本)
wget https://github.com/VirusTotal/yara/archive/refs/tags/v4.5.2.tar.gz
tar zxf v4.5.2.tar.gz && cd yara-4.5.2
./bootstrap.sh && ./configure --enable-cuckoo --enable-magic
make -j$(nproc) && make install
# 验证安装
yara --version
原理说明
YARA 规则本质上是一组”条件表达式”:当目标文件的内容满足规则中声明的字符串、字节序列与逻辑条件时,该文件即被判定为命中。规则由三部分组成——meta(元信息)、strings(特征字符串)和condition(匹配条件)。引擎会从文件中提取字符串表与字节序列,再逐一求值条件,命中后输出规则名称与命中的特征。理解这一点后,编写高质量规则的关键就不再是”堆字符串”,而是设计精确的条件组合,在检出率与误报率之间取得平衡。
操作步骤
第一步:编写基础规则
创建第一个规则文件 first.yar:
rule First_Rule
{
meta:
author = "wafai"
description = "示例规则:检测测试标记"
date = "2026-08-18"
strings:
$a = "malware_marker"
$b = { 6D 61 6C 77 61 72 65 }
condition:
$a or $b
}
创建测试文件并扫描:
echo "this is a malware_marker test" > /tmp/sample.txt
yara /tmp/first.yar /tmp/sample.txt
# 输出: First_Rule /tmp/sample.txt
第二步:使用宽字符串与十六进制字节
Windows 恶意软件常以 UTF-16LE 编码字符串,普通 ASCII 规则会漏检。用 wide 修饰符匹配宽字符串,用十六进制块匹配可变字节:
rule Wide_String_Detect
{
strings:
$a = "cmd.exe" wide ascii
$b = { 68 00 74 00 74 00 70 00 3A 00 2F 00 2F 00 } // h t t p : / /
condition:
$a or $b
}
十六进制块支持通配符 ? 与跳转 [-N],例如 { 6A ?? 74 } 表示第二个字节任意。
第三步:文件属性条件
结合文件大小、熵值等属性降低误报:
rule PE_Malware_Size_Hint
{
condition:
uint16(0) == 0x5A4D // MZ 头
and filesize < 2MB
and pe.imphash() == "3b2c3c4a5d6e7f80"
}
注意:pe 模块需要编译时开启(--enable-cuckoo 或默认已包含 PE 支持)。
第四步:目录批量扫描与递归
# 扫描单个目录(不递归)
yara /tmp/rules/ /tmp/samples/
# 递归扫描并显示命中的字符串
yara -r -s /tmp/rules/ /tmp/samples/
# 仅统计命中数量
yara -c /tmp/rules/ /tmp/samples/
第五步:多规则文件与规则标签
// tags.yar
rule Tagged_Rule : webshell php
{
strings:
$a = "eval("
condition:
$a
}
扫描时用 -t 按标签过滤:
yara -t webshell /tmp/rules/ /tmp/samples/
配置验证
验证规则有效性的标准流程:
# 1. 语法检查(有语法错误会直接报错)
yara /tmp/rules/all.yar /tmp/empty.txt
# 2. 用已知恶意样本做正向验证(必须命中)
yara /tmp/rules/all.yar /tmp/malware_sample.bin
# 3. 用良性文件做误报验证(尽量不命中)
yara /tmp/rules/all.yar /usr/bin/ls /etc/passwd
# 4. 计算规则覆盖率
yara -c -r /tmp/rules/ /tmp/samples/
# 输出命中文件计数,与样本总数对比
建议在 CI 中集成 yara 回归测试:每次新增规则后,用已知恶意样本库与白样本库同时跑一遍,命中率与误报率的变化一目了然。
常见问题
FAQ 1:规则误报率高怎么办?
优先增加条件约束而非删除字符串:加 filesize 范围、uint16(0) == 0x5A4D 等文件类型判断、多个字符串的 and 组合,以及 #a > 3 的计数条件。先用 -s 查看实际命中了哪些字符串,再针对性收紧。
FAQ 2:为什么宽字符串规则匹配不到样本?
确认样本字符串确实是 UTF-16LE 编码,并同时使用 wide ascii 双修饰符;检查是否在规则中遗漏了 condition 中的引用。另外,被压缩或加壳的样本需要先脱壳再匹配,否则特征被压缩无法命中。
总结
YARA 规则编写是安全运营的基础技能:规则 = 特征字符串 + 逻辑条件,核心是在检出率与误报率之间做平衡。建议按”编写—正样本验证—白样本验证—入库”—循环持续迭代,并利用 pe.imphash()、文件大小、熵值等属性增强规则的鲁棒性,将 YARA 与病毒分析沙箱、EDR 告警联动,形成从样本到检测的完整闭环。